✨ Introducing new features. 增加文件分组功能

This commit is contained in:
lbw committed 2023-07-28 12:51:52 +08:00
1 parent 524a9fe9da
commit 9d0ddc4cd9
7 files changed
+342 -17

No files matched your search

@@ -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;
}
@@ -69,6 +69,12 @@ public class SysFile extends Model<SysFile> {
@Schema(description = "文件类型")
private String type;
/**
* 文件组
*/
@Schema(description = "文件组")
private Long groupId;
/**
* 文件大小
*/
@@ -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<SysFile> {
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;
}
@@ -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<SysFile> wrapper = Wrappers.<SysFile>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));
}
}
@@ -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<SysFileGroup> {
}
@@ -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<SysFile> {
/**
* 上传文件
* @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<SysFile> {
*/
Boolean deleteFile(Long id);
/**
* 查询文件组列表
* @param fileGroup SysFileGroup对象,用于筛选条件
* @return 包含文件组列表的Tree对象列表
*/
List<Tree<Long>> 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);
}
@@ -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<SysFileMapper, SysFile> 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<String, String> resultMap = new HashMap<>(4);
resultMap.put("bucketName", properties.getBucketName());
@@ -72,7 +84,7 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> 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<SysFileMapper, SysFile> impl
}
/**
* 文件管理数据记录,收集管理追踪文件
* @param file 上传文件格式
* @param fileName 文件名
* 查询文件组列表
* @param fileGroup SysFileGroup对象,用于筛选条件
* @return 包含文件组树形结构列表的List对象
*/
private void fileLog(MultipartFile file, String fileName) {
@Override
public List<Tree<Long>> listFileGroup(SysFileGroup fileGroup) {
// 从数据库查询文件组列表
List<TreeNode<Long>> treeNodeList = fileGroupMapper.selectList(Wrappers.query(fileGroup))
.stream()
.map(group -> {
TreeNode<Long> treeNode = new TreeNode<>();
treeNode.setName(group.getName());
treeNode.setId(group.getId());
treeNode.setParentId(group.getPid());
return treeNode;
})
.toList();
// 构建树形结构
List<Tree<Long>> 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.<SysFile>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);
}