From 28e645f012903ddf7d8a6f7c271e5b131960ebb2 Mon Sep 17 00:00:00 2001 From: dinghao <459102951@qq.com> Date: Wed, 19 Nov 2025 21:51:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86bug?= =?UTF-8?q?=EF=BC=8C=E6=96=B0=E5=A2=9E=E6=9C=8D=E5=8A=A1=E7=AB=AF=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=BC=8F=E6=96=87=E4=BB=B6=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-dev.yml | 4 +- fs-admin/src/main/resources/application.yml | 3 +- .../framework/redis/RedisAutoConfigure.java | 2 - .../file/controller/FileShareController.java | 30 ++-- .../fs/file/domain/dto/CreateShareCmd.java | 2 +- .../fs/file/domain/qry/FileSharePageQry.java | 12 -- .../fs/file/domain/qry/FileShareQry.java | 20 +-- .../fs/file/domain/vo/FileShareVO.java | 7 +- .../fs/file/service/FileShareService.java | 26 ++- .../FileShareAccessRecordServiceImpl.java | 2 + .../service/impl/FileShareServiceImpl.java | 166 +++++++++++------- 11 files changed, 155 insertions(+), 119 deletions(-) delete mode 100644 fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/qry/FileSharePageQry.java diff --git a/fs-admin/src/main/resources/application-dev.yml b/fs-admin/src/main/resources/application-dev.yml index f976aebb..2045d343 100644 --- a/fs-admin/src/main/resources/application-dev.yml +++ b/fs-admin/src/main/resources/application-dev.yml @@ -27,7 +27,7 @@ spring: redis: host: 127.0.0.1 port: 6379 - password: insentek + password: 123456 database: 0 # 连接超时时间 timeout: 10s @@ -54,7 +54,7 @@ redisson: config: | singleServerConfig: address: "redis://127.0.0.1:6379" - password: "insentek" + password: "123456" database: 0 timeout: 3000 connectionPoolSize: 64 diff --git a/fs-admin/src/main/resources/application.yml b/fs-admin/src/main/resources/application.yml index 9471d68a..1f3d5a0a 100644 --- a/fs-admin/src/main/resources/application.yml +++ b/fs-admin/src/main/resources/application.yml @@ -121,7 +121,8 @@ security: - /apis/user/register - /apis/user/forget-password/code/** - /apis/user/forget-password - - /apis/share/items + - /apis/share/**/items + - /apis/share/verify/code - /apis/share/**/info --- #Sa-Token 配置 diff --git a/fs-framework/fs-redis/src/main/java/com/xddcodec/fs/framework/redis/RedisAutoConfigure.java b/fs-framework/fs-redis/src/main/java/com/xddcodec/fs/framework/redis/RedisAutoConfigure.java index abab4ab6..7c645cd8 100644 --- a/fs-framework/fs-redis/src/main/java/com/xddcodec/fs/framework/redis/RedisAutoConfigure.java +++ b/fs-framework/fs-redis/src/main/java/com/xddcodec/fs/framework/redis/RedisAutoConfigure.java @@ -1,8 +1,6 @@ package com.xddcodec.fs.framework.redis; -import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; diff --git a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/controller/FileShareController.java b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/controller/FileShareController.java index fbf3a019..bf35a2f8 100644 --- a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/controller/FileShareController.java +++ b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/controller/FileShareController.java @@ -2,7 +2,6 @@ package com.xddcodec.fs.file.controller; import com.xddcodec.fs.file.domain.dto.CreateShareCmd; import com.xddcodec.fs.file.domain.dto.VerifyShareCodeCmd; -import com.xddcodec.fs.file.domain.qry.FileSharePageQry; import com.xddcodec.fs.file.domain.qry.FileShareQry; import com.xddcodec.fs.file.domain.vo.FileShareAccessRecordVO; import com.xddcodec.fs.file.domain.vo.FileShareThinVO; @@ -10,7 +9,6 @@ import com.xddcodec.fs.file.domain.vo.FileShareVO; import com.xddcodec.fs.file.domain.vo.FileVO; import com.xddcodec.fs.file.service.FileShareAccessRecordService; import com.xddcodec.fs.file.service.FileShareService; -import com.xddcodec.fs.framework.common.domain.PageResult; import com.xddcodec.fs.framework.common.domain.Result; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -34,10 +32,18 @@ public class FileShareController { @Autowired private FileShareAccessRecordService fileShareAccessRecordService; - @GetMapping("/pages") - @Operation(summary = "分页获取我的分享", description = "分页获取我的分享列表") - public PageResult getMyPages(FileSharePageQry qry) { - return fileShareService.getMyPages(qry); + @GetMapping("/list") + @Operation(summary = "获取我的分享", description = "获取我的分享列表") + public Result> getList(FileShareQry qry) { + List result = fileShareService.getList(qry); + return Result.ok(result); + } + + @GetMapping("/{shareId}") + @Operation(summary = "获取分享详细信息", description = "获取分享详细信息") + public Result getDetail(@PathVariable String shareId) { + FileShareVO result = fileShareService.getDetail(shareId); + return Result.ok(result); } @GetMapping("/{shareId}/access/records") @@ -54,10 +60,10 @@ public class FileShareController { return Result.ok(fileShareVO); } - @PutMapping("/{id}/cancel") + @DeleteMapping("/cancels") @Operation(summary = "取消分享", description = "取消分享") - public Result cancelShare(@PathVariable String id) { - fileShareService.cancelShare(id); + public Result cancelShares(@RequestBody List ids) { + fileShareService.cancelShares(ids); return Result.ok(); } @@ -75,8 +81,8 @@ public class FileShareController { } @Operation(summary = "获取分享页文件列表数据", description = "获取分享页文件列表数据") - @GetMapping("/items") - public Result> getShareFileItems(@Validated FileShareQry qry) { - return Result.ok(fileShareService.getShareFileItems(qry)); + @GetMapping("/{shareId}/items") + public Result> getShareFileItems(@PathVariable String shareId, @RequestParam(required = false) String parentId) { + return Result.ok(fileShareService.getShareFileItems(shareId, parentId)); } } diff --git a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/dto/CreateShareCmd.java b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/dto/CreateShareCmd.java index cd913779..1cdb78d1 100644 --- a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/dto/CreateShareCmd.java +++ b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/dto/CreateShareCmd.java @@ -28,7 +28,7 @@ public class CreateShareCmd { private String shareName; /** - * 有效期类型:1-1天 2-7天 3-30天 4-自定义 null-永久 + * 有效期类型:1-7天 2-30天 3-自定义 4-永久 */ private Integer expireType; diff --git a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/qry/FileSharePageQry.java b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/qry/FileSharePageQry.java deleted file mode 100644 index 239abe6e..00000000 --- a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/qry/FileSharePageQry.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.xddcodec.fs.file.domain.qry; - -import com.xddcodec.fs.framework.common.domain.PageQuery; -import lombok.Data; -import lombok.EqualsAndHashCode; - -@EqualsAndHashCode(callSuper = true) -@Data -public class FileSharePageQry extends PageQuery { - - private String keyword; -} diff --git a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/qry/FileShareQry.java b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/qry/FileShareQry.java index d21f69ed..d2a2c529 100644 --- a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/qry/FileShareQry.java +++ b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/qry/FileShareQry.java @@ -1,22 +1,12 @@ package com.xddcodec.fs.file.domain.qry; - -import jakarta.validation.constraints.NotBlank; +import com.xddcodec.fs.framework.common.domain.PageQuery; import lombok.Data; +import lombok.EqualsAndHashCode; -/** - * - * @author Yann - * @date 2025/11/19 15:50 - */ +@EqualsAndHashCode(callSuper = true) @Data -public class FileShareQry { +public class FileShareQry extends PageQuery { - /** 分享ID */ - @NotBlank(message = "分享ID不能为空") - private String shareId; - /** - * 文件父ID - */ - private String parentId; + private String keyword; } diff --git a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/vo/FileShareVO.java b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/vo/FileShareVO.java index 297aeff4..3f3e8b31 100644 --- a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/vo/FileShareVO.java +++ b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/domain/vo/FileShareVO.java @@ -26,11 +26,6 @@ public class FileShareVO implements Serializable { */ private String shareName; - /** - * 分享链接 - */ - private String shareUrl; - /** * 提取码 */ @@ -70,7 +65,7 @@ public class FileShareVO implements Serializable { /** * 文件数量 */ - private Integer fileCount; + private Long fileCount; /** * 创建时间 diff --git a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/service/FileShareService.java b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/service/FileShareService.java index d32fecb2..c9940844 100644 --- a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/service/FileShareService.java +++ b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/service/FileShareService.java @@ -4,12 +4,10 @@ import com.mybatisflex.core.service.IService; import com.xddcodec.fs.file.domain.FileShare; import com.xddcodec.fs.file.domain.dto.CreateShareCmd; import com.xddcodec.fs.file.domain.dto.VerifyShareCodeCmd; -import com.xddcodec.fs.file.domain.qry.FileSharePageQry; import com.xddcodec.fs.file.domain.qry.FileShareQry; import com.xddcodec.fs.file.domain.vo.FileShareThinVO; import com.xddcodec.fs.file.domain.vo.FileShareVO; import com.xddcodec.fs.file.domain.vo.FileVO; -import com.xddcodec.fs.framework.common.domain.PageResult; import java.util.List; @@ -27,7 +25,15 @@ public interface FileShareService extends IService { * @param qry * @return */ - PageResult getMyPages(FileSharePageQry qry); + List getList(FileShareQry qry); + + /** + * 获取分享详情 + * + * @param shareId 分享ID + * @return + */ + FileShareVO getDetail(String shareId); /** * 创建分享 @@ -39,9 +45,9 @@ public interface FileShareService extends IService { /** * 取消分享 * - * @param shareId 分享ID + * @param ids 分享ID集合 */ - void cancelShare(String shareId); + void cancelShares(List ids); /** * 校验提取码 @@ -52,10 +58,18 @@ public interface FileShareService extends IService { /** * 获取文件分享页对象 + * * @param shareId 分享id * @return vo */ FileShareThinVO getFileShareThinVO(String shareId); - List getShareFileItems(FileShareQry qry); + /** + * 获取分享文件列表 + * + * @param shareId 分享id + * @param parentId 父目录id + * @return + */ + List getShareFileItems(String shareId, String parentId); } diff --git a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/service/impl/FileShareAccessRecordServiceImpl.java b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/service/impl/FileShareAccessRecordServiceImpl.java index 5a370111..6bf67f51 100644 --- a/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/service/impl/FileShareAccessRecordServiceImpl.java +++ b/fs-modules/fs-file/src/main/java/com/xddcodec/fs/file/service/impl/FileShareAccessRecordServiceImpl.java @@ -12,6 +12,7 @@ import io.github.linpeilie.Converter; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; import java.util.List; import static com.xddcodec.fs.file.domain.table.FileShareAccessRecordTableDef.FILE_SHARE_ACCESS_RECORD; @@ -40,6 +41,7 @@ public class FileShareAccessRecordServiceImpl extends ServiceImpl getMyPages(FileSharePageQry qry) { - Integer pageNumber = qry.getPage() == null ? 1 : qry.getPage(); - Integer pageSize = qry.getPageSize() == null ? 10 : qry.getPageSize(); - Page page = Page.of(pageNumber, pageSize); - + public List getList(FileShareQry qry) { String userId = StpUtil.getLoginIdAsString(); - QueryWrapper wrapper = new QueryWrapper(); wrapper.where(FILE_SHARE.USER_ID.eq(userId)); @@ -68,7 +65,6 @@ public class FileShareServiceImpl extends ServiceImpl fileShares = this.list(wrapper); + return converter.convert(fileShares, FileShareVO.class); + } + + @Override + public FileShareVO getDetail(String shareId) { + FileShare share = this.getById(shareId); + if (share == null) { + throw new BusinessException("该分享不存在"); + } + return buildShareVO(share); + } - page = this.page(page, wrapper); - long total = page.getTotalRow(); - List fileShares = page.getRecords(); - List fileShareVOS = converter.convert(fileShares, FileShareVO.class); - fileShareVOS.forEach(vo -> { - vo.setShareUrl(shareDomain + "/s/" + vo.getId()); - vo.setIsPermanent(vo.getExpireTime() == null); - }); - return PageResult.success(fileShareVOS, total); + /** + * 构建分享VO + */ + private FileShareVO buildShareVO(FileShare share) { + FileShareVO vo = converter.convert(share, FileShareVO.class); + // 是否永久有效 + vo.setIsPermanent(share.getExpireTime() == null); + // 查询有几个文件 + vo.setFileCount(fileShareItemService.countByShareId(share.getId())); + // 判断是否到期 + return vo; } @Override @@ -108,9 +118,9 @@ public class FileShareServiceImpl extends ServiceImpl now.plusDays(1); - case 2 -> now.plusDays(7); - case 3 -> now.plusDays(30); + case 1 -> now.plusDays(7); + case 2 -> now.plusDays(30); default -> now.plusDays(7); }; } @Override @Transactional(rollbackFor = Exception.class) - public void cancelShare(String shareId) { - String userId = StpUtil.getLoginIdAsString(); - - FileShare share = this.getById(shareId); - if (share == null) { - throw new BusinessException("该分享不存在"); - } - - if (!share.getUserId().equals(userId)) { - throw new BusinessException("无权取消此分享"); + public void cancelShares(List ids) { + for (String id : ids) { + FileShare share = this.getById(id); + if (share == null) { + continue; + } + if (share.getUserId().equals(StpUtil.getLoginIdAsString())) { + this.removeById(id); + fileShareItemService.removeByShareId(id); + } } - - this.removeById(share); - - fileShareItemService.removeByShareId(shareId); } @Override public boolean verifyShareCode(VerifyShareCodeCmd cmd) { - FileShare share = this.getById(cmd.getShareId()); + // 故意延迟200ms,增加暴力破解成本 + try { + Thread.sleep(200); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + FileShareVO share = this.getDetail(cmd.getShareId()); if (share == null) { throw new BusinessException("该分享不存在"); } @@ -194,7 +191,7 @@ public class FileShareServiceImpl extends ServiceImpl getShareFileItems(FileShareQry qry) { - FileShare fileShare = this.getById(qry.getShareId()); + public List getShareFileItems(String shareId, String parentId) { + FileShare fileShare = this.getById(shareId); if (fileShare == null) { throw new BusinessException("该分享不存在或已删除"); } - if (StringUtils.isNotEmpty(qry.getParentId())) { + if (StringUtils.isNotEmpty(parentId)) { // 若有父文件ID参数, 则需要查询子数据集 FileQry fileQry = new FileQry(); - fileQry.setParentId(qry.getParentId()); + fileQry.setParentId(parentId); return fileInfoService.getList(fileQry); } // 获取分享明细 - List shareFileIds = fileShareItemService.getShareFileIds(qry.getShareId()); + List shareFileIds = fileShareItemService.getShareFileIds(shareId); + + //记录访问日志 + recordShareAccessLog(shareId); + //访问计数 + 1 +// incrementViewCount(qry.getShareId()); + return fileInfoService.getByFileIds(shareFileIds); } + + /** + * 记录分享访问日志 + * + * @param shareId + */ + private void recordShareAccessLog(String shareId) { + String ip = IpUtils.getIpAddr(); + String address = Ip2RegionUtils.search(ip); + String browser = IpUtils.getBrowser(); + String os = IpUtils.getOs(); + CreateFileShareAccessRecordCmd cmd = new CreateFileShareAccessRecordCmd(); + cmd.setShareId(shareId); + cmd.setAccessIp(ip); + cmd.setAccessAddress(address); + cmd.setBrowser(browser); + cmd.setOs(os); + eventPublisher.publishEvent(new CreateFileShareAccessRecordEvent(this, cmd)); + } + + /** + * 原子递增访问次数 + */ +// private void incrementViewCount(String shareId) { +// String key = VIEW_COUNT_KEY + shareId; +// Long count = redisTemplate.opsForValue().increment(key); +// +// if (count == null) { +// return; +// } +// // 第一次访问时设置过期时间(与分享有效期一致,或者永不过期) +// if (count == 1) { +// // 选项1: 永不过期 +// // redisTemplate.persist(key); +// +// // 选项2: 与分享有效期同步(推荐) +// setExpireTimeByShareExpiry(shareId, key); +// } +// } } -- Gitee