From 9d0ddc4cd9c4d3f7f86aa4205e9985ff8e7cd169 Mon Sep 17 00:00:00 2001 From: lbw Date: Fri, 28 Jul 2023 12:51:52 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20Introducing=20new=20features.=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=87=E4=BB=B6=E5=88=86=E7=BB=84=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pigx/admin/api/dto/SysFileGroupDTO.java | 24 ++++ .../pigx/admin/api/entity/SysFile.java | 6 + .../pigx/admin/api/entity/SysFileGroup.java | 73 +++++++++++ .../admin/controller/SysFileController.java | 68 +++++++++- .../pigx/admin/mapper/SysFileGroupMapper.java | 33 +++++ .../pigx/admin/service/SysFileService.java | 38 +++++- .../service/impl/SysFileServiceImpl.java | 117 ++++++++++++++++-- 7 files changed, 342 insertions(+), 17 deletions(-) create mode 100644 pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysFileGroupDTO.java create mode 100644 pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysFileGroup.java create mode 100644 pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileGroupMapper.java diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysFileGroupDTO.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysFileGroupDTO.java new file mode 100644 index 000000000..68b285870 --- /dev/null +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysFileGroupDTO.java @@ -0,0 +1,24 @@ +package com.pig4cloud.pigx.admin.api.dto; + +import lombok.Data; + +/** + * 文件传输DTO + * + * @author lengleng + * @date 2023/7/26 + */ +@Data +public class SysFileGroupDTO { + + /** + * 文件组 + */ + private Long groupId; + + /** + * 文件id + */ + private Long[] ids; + +} diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysFile.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysFile.java index 8884b4a5b..9521627bb 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysFile.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysFile.java @@ -69,6 +69,12 @@ public class SysFile extends Model { @Schema(description = "文件类型") private String type; + /** + * 文件组 + */ + @Schema(description = "文件组") + private Long groupId; + /** * 文件大小 */ diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysFileGroup.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysFileGroup.java new file mode 100644 index 000000000..2a490ce25 --- /dev/null +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysFileGroup.java @@ -0,0 +1,73 @@ +package com.pig4cloud.pigx.admin.api.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/** + * 文件类型 + * + * @author lengleng + * @date 2023/7/25 + */ +@Data +@Schema(description = "文件") +@EqualsAndHashCode(callSuper = true) +public class SysFileGroup extends Model { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "主键ID") + private Long id; + + @Schema(description = "父级ID") + private Long pid; + + @Schema(description = "分类类型: [10=图片,20=视频]") + private Long type; + + @Schema(description = "分类名称") + private String name; + + /** + * 上传人 + */ + @TableField(fill = FieldFill.INSERT) + @Schema(description = "创建者") + private String createBy; + + /** + * 上传时间 + */ + @TableField(fill = FieldFill.INSERT) + @Schema(description = "创建时间") + private LocalDateTime createTime; + + /** + * 更新人 + */ + @TableField(fill = FieldFill.INSERT) + @Schema(description = "更新者") + private String updateBy; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.UPDATE) + @Schema(description = "更新时间") + private LocalDateTime updateTime; + + /** + * 删除标识:1-删除,0-正常 + */ + @TableLogic + @TableField(fill = FieldFill.INSERT) + @Schema(description = "删除标记,1:已删除,0:正常") + private String delFlag; + +} diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysFileController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysFileController.java index 1e9af99f4..b17c2077a 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysFileController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysFileController.java @@ -22,7 +22,9 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.pig4cloud.pigx.admin.api.dto.SysFileGroupDTO; import com.pig4cloud.pigx.admin.api.entity.SysFile; +import com.pig4cloud.pigx.admin.api.entity.SysFileGroup; import com.pig4cloud.pigx.admin.service.SysFileService; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.log.annotation.SysLog; @@ -30,6 +32,7 @@ import com.pig4cloud.pigx.common.security.annotation.Inner; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import org.springdoc.core.annotations.ParameterObject; @@ -39,7 +42,7 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import jakarta.servlet.http.HttpServletResponse; +import java.util.Objects; /** * 文件管理 @@ -66,6 +69,8 @@ public class SysFileController { @GetMapping("/page") public R getSysFilePage(@ParameterObject Page page, @ParameterObject SysFile sysFile) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() + .eq(StrUtil.isNotBlank(sysFile.getType()), SysFile::getType, sysFile.getType()) + .eq(Objects.nonNull(sysFile.getGroupId()), SysFile::getGroupId, sysFile.getGroupId()) .like(StrUtil.isNotBlank(sysFile.getOriginal()), SysFile::getOriginal, sysFile.getOriginal()); return R.ok(sysFileService.page(page, wrapper)); } @@ -86,14 +91,21 @@ public class SysFileController { return R.ok(); } + @PutMapping("/rename") + public R rename(@RequestBody SysFile sysFile) { + return R.ok(sysFileService.updateById(sysFile)); + } + /** * 上传文件 文件名采用uuid,避免原始文件名中带"-"符号导致下载的时候解析出现异常 * @param file 资源 * @return R(/ admin / bucketName / filename) */ @PostMapping(value = "/upload") - public R upload(@RequestPart("file") MultipartFile file) { - return sysFileService.uploadFile(file); + public R upload(@RequestPart("file") MultipartFile file, + @RequestParam(value = "groupId", required = false) Long groupId, + @RequestParam(value = "type", required = false) String type) { + return sysFileService.uploadFile(file, groupId, type); } /** @@ -122,4 +134,54 @@ public class SysFileController { IoUtil.copy(resource.getInputStream(), response.getOutputStream()); } + /** + * 查询文件组列表 + * @param fileGroup SysFileGroup对象,用于筛选条件 + * @return 包含文件组列表的R对象 + */ + @GetMapping("/group/list") + public R listGroup(SysFileGroup fileGroup) { + return R.ok(sysFileService.listFileGroup(fileGroup)); + } + + /** + * 添加文件组 + * @param fileGroup SysFileGroup对象,要添加的文件组信息 + * @return 包含添加结果的R对象 + */ + @PostMapping("/group/add") + public R addGroup(@RequestBody SysFileGroup fileGroup) { + return R.ok(sysFileService.saveOrUpdateGroup(fileGroup)); + } + + /** + * 更新文件组 + * @param fileGroup SysFileGroup对象,要更新的文件组信息 + * @return 包含更新结果的R对象 + */ + @PutMapping("/group/update") + public R updateGroup(@RequestBody SysFileGroup fileGroup) { + return R.ok(sysFileService.saveOrUpdateGroup(fileGroup)); + } + + /** + * 删除文件组 + * @param id 待删除文件组的ID + * @return 包含删除结果的R对象 + */ + @DeleteMapping("/group/delete/{id}") + public R updateGroup(@PathVariable Long id) { + return R.ok(sysFileService.deleteGroup(id)); + } + + /** + * 移动文件组 + * @param fileGroupDTO SysFileGroupDTO对象,要移动的文件组信息 + * @return 包含移动结果的R对象 + */ + @PutMapping("/group/move") + public R moveFileGroup(@RequestBody SysFileGroupDTO fileGroupDTO) { + return R.ok(sysFileService.moveFileGroup(fileGroupDTO)); + } + } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileGroupMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileGroupMapper.java new file mode 100644 index 000000000..c55dd9a1f --- /dev/null +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileGroupMapper.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ + +package com.pig4cloud.pigx.admin.mapper; + +import com.pig4cloud.pigx.admin.api.entity.SysFileGroup; +import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 文件分组管理 + * + * @author lbw + * @date 2023年07月25日21:31:48 + */ +@Mapper +public interface SysFileGroupMapper extends PigxBaseMapper { + +} diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysFileService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysFileService.java index c4d275036..2f85400e0 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysFileService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysFileService.java @@ -17,12 +17,16 @@ package com.pig4cloud.pigx.admin.service; +import cn.hutool.core.lang.tree.Tree; import com.baomidou.mybatisplus.extension.service.IService; +import com.pig4cloud.pigx.admin.api.dto.SysFileGroupDTO; import com.pig4cloud.pigx.admin.api.entity.SysFile; +import com.pig4cloud.pigx.admin.api.entity.SysFileGroup; import com.pig4cloud.pigx.common.core.util.R; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.multipart.MultipartFile; -import jakarta.servlet.http.HttpServletResponse; +import java.util.List; /** * 文件管理 @@ -35,9 +39,11 @@ public interface SysFileService extends IService { /** * 上传文件 * @param file + * @param groupId + * @param type * @return */ - R uploadFile(MultipartFile file); + R uploadFile(MultipartFile file, Long groupId, String type); /** * 读取文件 @@ -54,4 +60,32 @@ public interface SysFileService extends IService { */ Boolean deleteFile(Long id); + /** + * 查询文件组列表 + * @param fileGroup SysFileGroup对象,用于筛选条件 + * @return 包含文件组列表的Tree对象列表 + */ + List> listFileGroup(SysFileGroup fileGroup); + + /** + * 添加或更新文件组 + * @param fileGroup SysFileGroup对象,要添加或更新的文件组信息 + * @return 添加或更新成功返回true,否则返回false + */ + Boolean saveOrUpdateGroup(SysFileGroup fileGroup); + + /** + * 删除文件组 + * @param id 待删除文件组的ID + * @return 删除成功返回true,否则返回false + */ + Boolean deleteGroup(Long id); + + /** + * 移动文件组 + * @param fileGroupDTO SysFileGroupDTO对象,要移动的文件组信息 + * @return 移动成功返回true,否则返回false + */ + Boolean moveFileGroup(SysFileGroupDTO fileGroupDTO); + } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java index 1d398b4f1..92389b97b 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java @@ -16,18 +16,28 @@ */ package com.pig4cloud.pigx.admin.service.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.lang.tree.Tree; +import cn.hutool.core.lang.tree.TreeNode; +import cn.hutool.core.lang.tree.TreeUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import com.amazonaws.services.s3.model.S3Object; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.admin.api.dto.SysFileGroupDTO; import com.pig4cloud.pigx.admin.api.entity.SysFile; +import com.pig4cloud.pigx.admin.api.entity.SysFileGroup; +import com.pig4cloud.pigx.admin.mapper.SysFileGroupMapper; import com.pig4cloud.pigx.admin.mapper.SysFileMapper; import com.pig4cloud.pigx.admin.service.SysFileService; +import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.file.core.FileProperties; import com.pig4cloud.pigx.common.file.core.FileTemplate; +import jakarta.servlet.http.HttpServletResponse; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -35,11 +45,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; -import jakarta.servlet.http.HttpServletResponse; import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.nio.charset.StandardCharsets; +import java.util.*; /** * 文件管理 @@ -54,15 +62,19 @@ public class SysFileServiceImpl extends ServiceImpl impl private final FileTemplate fileTemplate; + private final SysFileGroupMapper fileGroupMapper; + private final FileProperties properties; /** * 上传文件 * @param file + * @param groupId + * @param type * @return */ @Override - public R uploadFile(MultipartFile file) { + public R uploadFile(MultipartFile file, Long groupId, String type) { String fileName = IdUtil.simpleUUID() + StrUtil.DOT + FileUtil.extName(file.getOriginalFilename()); Map resultMap = new HashMap<>(4); resultMap.put("bucketName", properties.getBucketName()); @@ -72,7 +84,7 @@ public class SysFileServiceImpl extends ServiceImpl impl try (InputStream inputStream = file.getInputStream()) { fileTemplate.putObject(properties.getBucketName(), fileName, inputStream, file.getContentType()); // 文件管理数据记录,收集管理追踪文件 - fileLog(file, fileName); + fileLog(file, fileName, groupId, type); } catch (Exception e) { log.error("上传失败", e); @@ -116,17 +128,98 @@ public class SysFileServiceImpl extends ServiceImpl impl } /** - * 文件管理数据记录,收集管理追踪文件 - * @param file 上传文件格式 - * @param fileName 文件名 + * 查询文件组列表 + * @param fileGroup SysFileGroup对象,用于筛选条件 + * @return 包含文件组树形结构列表的List对象 */ - private void fileLog(MultipartFile file, String fileName) { + @Override + public List> listFileGroup(SysFileGroup fileGroup) { + // 从数据库查询文件组列表 + List> treeNodeList = fileGroupMapper.selectList(Wrappers.query(fileGroup)) + .stream() + .map(group -> { + TreeNode treeNode = new TreeNode<>(); + treeNode.setName(group.getName()); + treeNode.setId(group.getId()); + treeNode.setParentId(group.getPid()); + return treeNode; + }) + .toList(); + + // 构建树形结构 + List> treeList = TreeUtil.build(treeNodeList, CommonConstants.MENU_TREE_ROOT_ID); + return CollUtil.isEmpty(treeList) ? new ArrayList<>() : treeList; + } + + /** + * 添加或更新文件组 + * @param fileGroup SysFileGroup对象,要添加或更新的文件组信息 + * @return 添加或更新成功返回true,否则返回false + */ + @Override + public Boolean saveOrUpdateGroup(SysFileGroup fileGroup) { + if (Objects.isNull(fileGroup.getId())) { + // 插入文件组 + fileGroupMapper.insert(fileGroup); + } + else { + // 更新文件组 + fileGroupMapper.updateById(fileGroup); + } + return Boolean.TRUE; + } + + /** + * 删除文件组 + * @param id 待删除文件组的ID + * @return 删除成功返回true,否则返回false + */ + @Override + public Boolean deleteGroup(Long id) { + // 根据ID删除文件组 + fileGroupMapper.deleteById(id); + return Boolean.TRUE; + } + + /** + * 移动文件组 + * @param fileGroupDTO SysFileGroupDTO对象,要移动的文件组信息 + * @return 移动成功返回true,否则返回false + */ + @Override + public Boolean moveFileGroup(SysFileGroupDTO fileGroupDTO) { + // 创建SysFile对象并设置groupId属性 + SysFile file = new SysFile(); + file.setGroupId(fileGroupDTO.getGroupId()); + + // 根据IDS更新对应的SysFile记录 + baseMapper.update(file, Wrappers.lambdaQuery().in(SysFile::getId, fileGroupDTO.getIds())); + return Boolean.TRUE; + } + + /** + * 文件管理数据记录,收集管理追踪文件 + * @param file 上传的文件格式 + * @param fileName 文件名 + * @param groupId 文件组ID + * @param type 文件类型 + */ + private void fileLog(MultipartFile file, String fileName, Long groupId, String type) { + // 创建SysFile对象并设置相关属性 SysFile sysFile = new SysFile(); sysFile.setFileName(fileName); - sysFile.setOriginal(file.getOriginalFilename()); + + // 对原始文件名进行编码转换 + String originalFilename = new String( + Objects.requireNonNull(file.getOriginalFilename()).getBytes(StandardCharsets.ISO_8859_1), + StandardCharsets.UTF_8); + sysFile.setOriginal(originalFilename); sysFile.setFileSize(file.getSize()); - sysFile.setType(FileUtil.extName(file.getOriginalFilename())); sysFile.setBucketName(properties.getBucketName()); + sysFile.setType(type); + sysFile.setGroupId(groupId); + + // 调用save方法保存SysFile对象 this.save(sysFile); }