Skip to content

Commit df122b0

Browse files
committed
feat: allow edit the limit after upload
1 parent 2b35f86 commit df122b0

15 files changed

+158
-103
lines changed

src/main/java/cn/bukkit/sip/SimpleImgPlatformApplication.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@
99
import com.fasterxml.jackson.databind.ObjectMapper;
1010
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
1111
import lombok.extern.slf4j.Slf4j;
12+
import org.apache.coyote.http11.AbstractHttp11Protocol;
1213
import org.springframework.boot.SpringApplication;
1314
import org.springframework.boot.autoconfigure.SpringBootApplication;
1415
import org.springframework.boot.env.EnvironmentPostProcessor;
16+
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
17+
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
18+
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
1519
import org.springframework.cache.CacheManager;
1620
import org.springframework.cache.annotation.EnableCaching;
1721
import org.springframework.context.annotation.Bean;
@@ -30,7 +34,6 @@
3034

3135
import java.time.Duration;
3236
import java.util.Map;
33-
import java.util.Objects;
3437
import java.util.Optional;
3538

3639

@@ -97,4 +100,16 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringAp
97100
System.out.printf("SimpleImgPlatformApplication.postProcessEnvironment: %s=%s\r\n", k, v);
98101
});
99102
}
103+
104+
@Bean
105+
public ServletWebServerFactory tomcatEmbedded() {
106+
TomcatServletWebServerFactory tomcat = new org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory();
107+
tomcat.addConnectorCustomizers(connector -> {
108+
if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol<?>)) {
109+
((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
110+
}
111+
});
112+
return tomcat;
113+
114+
}
100115
}

src/main/java/cn/bukkit/sip/api/ExceptionController.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.springframework.web.bind.annotation.ExceptionHandler;
1010
import org.springframework.web.bind.annotation.ResponseBody;
1111
import org.springframework.web.bind.annotation.RestController;
12+
import org.springframework.web.multipart.MultipartException;
1213

1314
import javax.validation.ValidationException;
1415
import java.io.PrintWriter;
@@ -27,19 +28,26 @@ public String exception(WebException e) {
2728
return e.getMessage();
2829
}
2930

31+
@ExceptionHandler
32+
@ResponseBody
33+
public RestData exception(RestException e) {
34+
StringWriter sw = new StringWriter();
35+
e.printStackTrace(new PrintWriter(sw, true));
36+
log.debug(sw.toString());
37+
return RestData.builder().code(e.getCode()).message(e.getMessage()).data(e.getData()).build();
38+
}
39+
3040
@ExceptionHandler
3141
@ResponseBody
3242
public RestData ValidationException(ValidationException e) {
3343
return this.exception(RestException.builder().code(-1).message(e.getMessage()).build());
3444
}
3545

36-
@ExceptionHandler
46+
@ExceptionHandler(MultipartException.class)
3747
@ResponseBody
38-
public RestData exception(RestException e) {
39-
// StringWriter sw = new StringWriter();
40-
// e.printStackTrace(new PrintWriter(sw, true));
41-
// log.debug(sw.toString());
42-
return RestData.builder().code(e.getCode()).message(e.getMessage()).data(e.getData()).build();
48+
public RestData MultipartException(MultipartException e) {
49+
e.printStackTrace();
50+
return RestData.builder().code(-1).message(e.getLocalizedMessage()).build();
4351
}
4452

4553
@ExceptionHandler

src/main/java/cn/bukkit/sip/api/ImgController.java

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,23 @@
33
import cn.bukkit.sip.exception.RestException;
44
import cn.bukkit.sip.orm.entity.ImgEntity;
55
import cn.bukkit.sip.pojo.RestData;
6+
import cn.bukkit.sip.pojo.ImgMetaDto;
67
import cn.bukkit.sip.security.CasdoorAuthenticationToken;
78
import cn.bukkit.sip.service.ImgService;
89
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
910
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
10-
import lombok.SneakyThrows;
1111
import org.springframework.beans.factory.annotation.Value;
1212
import org.springframework.validation.annotation.Validated;
13-
import org.springframework.web.bind.annotation.PathVariable;
14-
import org.springframework.web.bind.annotation.RequestMapping;
15-
import org.springframework.web.bind.annotation.ResponseBody;
16-
import org.springframework.web.bind.annotation.RestController;
13+
import org.springframework.web.bind.annotation.*;
1714

1815
import javax.annotation.Resource;
1916
import javax.validation.constraints.DecimalMax;
2017
import javax.validation.constraints.DecimalMin;
2118
import javax.validation.constraints.NotNull;
2219
import java.time.LocalDateTime;
20+
import java.util.HashMap;
2321
import java.util.Optional;
22+
import java.util.stream.Collectors;
2423

2524
@RequestMapping("/img")
2625
@RestController
@@ -34,53 +33,71 @@ public class ImgController {
3433

3534
// 显示图片
3635
@RequestMapping(path = "/get/{id}", produces = "image/*;charset=utf-8")
37-
@ResponseBody
38-
public byte[] get(@PathVariable Long id) {
39-
byte[] img = imgService.loadImg(id);
36+
public byte[] get(@PathVariable Long id, CasdoorAuthenticationToken authentication) {
37+
ImgEntity imgEntity = imgService.getImgDaoService().getById(id);
38+
byte[] img = null;
39+
if (imgEntity != null &&
40+
((authentication != null && this.imgService.checkPermission(imgEntity, authentication)) ||
41+
this.imgService.limitCheck(imgEntity))) {
42+
this.imgService.addTimes(imgEntity.getId());
43+
img = imgService.loadImg(id);
44+
}
4045
if (img == null || img.length == 0) img = imgService.loadUnknownImg();
4146
return img;
4247
}
4348

44-
45-
@RequestMapping(path = "/del/{id}")
46-
@ResponseBody
49+
@PostMapping(path = "/del/{id}")
4750
public RestData del(@PathVariable Long id, CasdoorAuthenticationToken authentication) {
4851
ImgEntity imgEntity = imgService.getImgDaoService().getById(id);
4952
if (imgEntity == null) throw RestException.builder().message("图片不存在").build();
50-
if (imgEntity.getOwner().isBlank()
51-
||
52-
!(authentication != null &&
53-
(authentication.getPrincipal().getRoles().stream().anyMatch(role -> role.getName().contains("admin"))
54-
|| imgEntity.getOwner().equalsIgnoreCase(authentication.getPrincipal().getId()))
55-
)
56-
)
53+
if (!this.imgService.checkPermission(imgEntity, authentication))
5754
throw RestException.builder().message("无权操作").build();
5855
if (!imgService.getImgDaoService().removeById(id)) throw RestException.builder().message("删除失败").build();
5956
return RestData.builder().build();
6057
}
6158

6259
@RequestMapping(path = "/info/{id}")
63-
@ResponseBody
64-
@SneakyThrows
6560
public RestData info(@PathVariable Long id) {
6661
ImgEntity imgEntity = imgService.getImgDaoService().getById(id);
6762
if (imgEntity == null) throw RestException.builder().message("图片不存在").build();
68-
if (imgEntity.getDateLimit().isBefore(LocalDateTime.now()) ||
69-
(Optional.ofNullable(imgEntity.getTimesLimit()).orElse(0) > 0 && this.imgService.getTimes(imgEntity.getId()) >= imgEntity.getTimesLimit()))
70-
throw RestException.builder().message("图片已过期").build();
71-
this.imgService.addTimes(imgEntity.getId());
72-
return RestData.builder().data(imgEntity).build();
63+
return RestData.builder().data(new HashMap<>() {
64+
{
65+
put("info", imgEntity);
66+
put("times", imgService.getTimes(id));
67+
}
68+
}).build();
69+
}
70+
71+
@PostMapping(path = "/edit/{id}")
72+
public RestData edit(@PathVariable Long id, ImgMetaDto dto, CasdoorAuthenticationToken authenticationToken) {
73+
ImgEntity imgEntity = imgService.getImgDaoService().getById(id);
74+
if (imgEntity == null) throw RestException.builder().message("图片不存在").build();
75+
if (!this.imgService.checkPermission(imgEntity, authenticationToken))
76+
throw RestException.builder().message("无权操作").build();
77+
if (dto.getIsPublic() != null) imgEntity.setIsPublic(dto.getIsPublic());
78+
if (dto.getDateLimit() != null && dto.getDateLimit() != 0)
79+
imgEntity.setDateLimitFromTimestamp(dto.getDateLimit() / 1000);
80+
else if (Optional.ofNullable(dto.getDateLimit()).orElse(0L) == 0L)
81+
imgEntity.setDateLimit(null);
82+
if (dto.getTimesLimit() != null) imgEntity.setTimesLimit(dto.getTimesLimit());
83+
this.imgService.getImgDaoService().updateById(imgEntity);
84+
return RestData.builder().build();
7385
}
7486

7587

76-
@RequestMapping("/list")
77-
@ResponseBody
88+
@PostMapping("/list")
7889
public RestData list(@NotNull @DecimalMin("1") Integer current, @NotNull @DecimalMax("20") Integer size) {
7990
Page<ImgEntity> page = this.imgService.getImgDaoService().page(
8091
new Page<>(current, size),
8192
Wrappers.<ImgEntity>lambdaQuery()
8293
.eq(ImgEntity::getIsPublic, true)
94+
.and(i -> i.isNull(ImgEntity::getDateLimit).or().gt(ImgEntity::getDateLimit, LocalDateTime.now()))
8395
.orderByDesc(ImgEntity::getId));
84-
return RestData.builder().data(page.getRecords()).build();
96+
return RestData.builder().data(new HashMap<>() {
97+
{
98+
put("img", page.getRecords().stream().filter(r -> imgService.limitCheck(r)).collect(Collectors.toList()));
99+
put("hasNext", page.getSize() >= size);
100+
}
101+
}).build();
85102
}
86103
}

src/main/java/cn/bukkit/sip/api/TestController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package cn.bukkit.sip.api;
22

33
import cn.bukkit.sip.exception.RestException;
4-
import cn.bukkit.sip.orm.entity.ImgEntity;
5-
import cn.bukkit.sip.service.ImgService;
64
import cn.bukkit.sip.orm.UserDaoService;
5+
import cn.bukkit.sip.orm.entity.ImgEntity;
76
import cn.bukkit.sip.pojo.RestData;
7+
import cn.bukkit.sip.service.ImgService;
88
import org.springframework.beans.factory.annotation.Autowired;
99
import org.springframework.security.web.csrf.CsrfToken;
1010
import org.springframework.web.bind.annotation.GetMapping;
Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package cn.bukkit.sip.api;
22

3-
import cn.bukkit.sip.pojo.UploadImgDTO;
4-
import cn.bukkit.sip.service.ImgService;
53
import cn.bukkit.sip.orm.UserDaoService;
64
import cn.bukkit.sip.orm.entity.ImgEntity;
75
import cn.bukkit.sip.pojo.RestData;
6+
import cn.bukkit.sip.pojo.ImgMetaDto;
87
import cn.bukkit.sip.security.CasdoorAuthenticationToken;
8+
import cn.bukkit.sip.service.ImgService;
99
import lombok.SneakyThrows;
1010
import org.springframework.beans.factory.annotation.Value;
11+
import org.springframework.validation.annotation.Validated;
1112
import org.springframework.web.bind.annotation.RequestMapping;
12-
import org.springframework.web.bind.annotation.RequestParam;
1313
import org.springframework.web.bind.annotation.RequestPart;
1414
import org.springframework.web.bind.annotation.RestController;
1515
import org.springframework.web.multipart.MultipartFile;
@@ -19,6 +19,7 @@
1919
import java.util.Optional;
2020

2121
@RestController
22+
@Validated
2223
public class UploadController {
2324

2425
@Value("${spring.servlet.multipart.location}")
@@ -33,13 +34,11 @@ public class UploadController {
3334
@SneakyThrows
3435
@RequestMapping(path = "/upload")
3536
public RestData upload(@RequestPart(value = "file") MultipartFile fileReq,
36-
UploadImgDTO uploadImgDTO,
37+
ImgMetaDto imgMetaDto,
3738
@NotNull CasdoorAuthenticationToken token) {
38-
ImgEntity imgEntity = imgService.uploaderImg(fileReq, userDaoService.getById(token.getPrincipal().getId()), uploadImgDTO);
39-
if (!uploadImgDTO.getIsPublic()) {
40-
imgEntity.setIsPublic(false);
41-
this.imgService.getImgDaoService().updateById(imgEntity);
42-
}
39+
ImgEntity imgEntity = imgService.uploaderImg(fileReq, userDaoService.getById(token.getPrincipal().getId()), imgMetaDto);
40+
imgEntity.setIsPublic(Optional.ofNullable(imgMetaDto.getIsPublic()).orElse(true));
41+
this.imgService.getImgDaoService().updateById(imgEntity);
4342
return RestData.builder().data(imgEntity).build();
4443
}
4544
}

src/main/java/cn/bukkit/sip/orm/ImgDaoService.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import cn.bukkit.sip.orm.entity.ImgEntity;
44
import cn.bukkit.sip.orm.mapper.ImgMapper;
55
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
6+
import org.springframework.cache.annotation.CacheEvict;
67
import org.springframework.cache.annotation.Cacheable;
78
import org.springframework.stereotype.Service;
89

@@ -17,8 +18,8 @@ public ImgEntity getById(Serializable id) {
1718
}
1819

1920
@Override
20-
@Cacheable(value = "img", key = "#entity.id", unless = "#entity == null or #entity.id == null")
21-
public boolean updateById(ImgEntity entity) {
22-
return super.updateById(entity);
21+
@CacheEvict(value = "img", key = "#imgEntity.id")
22+
public boolean updateById(ImgEntity imgEntity) {
23+
return super.updateById(imgEntity);
2324
}
2425
}

src/main/java/cn/bukkit/sip/orm/UserDaoService.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package cn.bukkit.sip.orm;
22

3-
import org.springframework.stereotype.Service;
4-
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
5-
import cn.bukkit.sip.orm.mapper.UserMapper;
63
import cn.bukkit.sip.orm.entity.UserEntity;
4+
import cn.bukkit.sip.orm.mapper.UserMapper;
5+
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
6+
import org.springframework.stereotype.Service;
77
@Service
88
public class UserDaoService extends ServiceImpl<UserMapper, UserEntity> {
99

src/main/java/cn/bukkit/sip/orm/entity/ImgEntity.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ public class ImgEntity implements Serializable {
3939
@TableField(value = "public")
4040
private Boolean isPublic = true;
4141

42-
@TableField(value = "limit_date")
42+
@TableField(value = "limit_date", updateStrategy = FieldStrategy.IGNORED)
4343
@JsonSerialize(using = LocalDateTimeToTimestampSerializer.class)
4444
@JsonDeserialize(using = LocalDateTimeToTimestampDeserializer.class)
4545
private LocalDateTime dateLimit;
4646

47-
@TableField(value = "limit_times")
47+
@TableField(value = "limit_times", updateStrategy = FieldStrategy.IGNORED)
4848
private Integer timesLimit;
4949

5050
@TableField(value = "owner")

src/main/java/cn/bukkit/sip/orm/entity/UserEntity.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
package cn.bukkit.sip.orm.entity;
22

33
import com.baomidou.mybatisplus.annotation.*;
4-
5-
import java.io.Serializable;
6-
import java.time.LocalDateTime;
7-
84
import lombok.AllArgsConstructor;
95
import lombok.Builder;
106
import lombok.Data;
117
import lombok.NoArgsConstructor;
128
import org.casbin.casdoor.entity.CasdoorUser;
139

10+
import java.io.Serializable;
11+
import java.time.LocalDateTime;
12+
1413
@Data
1514
@Builder
1615
@AllArgsConstructor
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package cn.bukkit.sip.pojo;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Data;
5+
import lombok.NoArgsConstructor;
6+
7+
import javax.validation.constraints.Digits;
8+
import javax.validation.constraints.Size;
9+
10+
@Data
11+
@AllArgsConstructor
12+
@NoArgsConstructor
13+
public class ImgMetaDto {
14+
private Boolean isPublic;
15+
@Digits(message = "日期必须有效", fraction = 0, integer = 13)
16+
private Long dateLimit;
17+
@Size(min = 0, max = 10000)
18+
private Integer timesLimit;
19+
}

0 commit comments

Comments
 (0)