新增 用户文件上传
This commit is contained in:
parent
143d9c4576
commit
d724f23d36
@ -2,20 +2,16 @@ package cn.iocoder.yudao.module.infra.api.file;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.module.infra.api.file.dto.FileCreateReqDTO;
|
import cn.iocoder.yudao.module.infra.api.file.dto.FileCreateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.infra.api.file.dto.UserFileUpdateReqDTO;
|
||||||
import cn.iocoder.yudao.module.infra.enums.ApiConstants;
|
import cn.iocoder.yudao.module.infra.enums.ApiConstants;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|
||||||
|
|
||||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||||
@Tag(name = "RPC 服务 - 文件")
|
@Tag(name = "RPC 服务 - 文件")
|
||||||
public interface FileApi {
|
public interface FileApi {
|
||||||
@ -80,8 +76,12 @@ public interface FileApi {
|
|||||||
@RequestParam("name") String name,
|
@RequestParam("name") String name,
|
||||||
@RequestBody byte[] content) ;
|
@RequestBody byte[] content) ;
|
||||||
|
|
||||||
@DeleteMapping("/deleteBpmFile")
|
@DeleteMapping(PREFIX + "/deleteBpmFile")
|
||||||
@Operation(summary = "删除工作流附件")
|
@Operation(summary = "删除工作流附件")
|
||||||
@Parameter(name = "url", description = "附件URL地址", required = true)
|
@Parameter(name = "url", description = "附件URL地址", required = true)
|
||||||
CommonResult<Boolean> deleteBpmFile(@RequestParam("url") String url) throws Exception;
|
CommonResult<Boolean> deleteBpmFile(@RequestParam("url") String url) throws Exception;
|
||||||
|
|
||||||
|
@PutMapping(PREFIX + "/updateUserFile")
|
||||||
|
@Operation(summary = "修改用户文件绑定 用户编号")
|
||||||
|
CommonResult<Boolean> updateUserFileUserId(@RequestBody UserFileUpdateReqDTO updateReqVO);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.api.file.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "RPC 服务 - 用户文件 Request DTO")
|
||||||
|
@Data
|
||||||
|
public class UserFileUpdateReqDTO {
|
||||||
|
|
||||||
|
@Schema(description = "附件地址", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "附件地址不能为空")
|
||||||
|
private List<String> urls;
|
||||||
|
|
||||||
|
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "用户编号不能为空")
|
||||||
|
private Long userId;
|
||||||
|
}
|
@ -1,8 +1,11 @@
|
|||||||
package cn.iocoder.yudao.module.infra.api.file;
|
package cn.iocoder.yudao.module.infra.api.file;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.infra.api.file.dto.FileCreateReqDTO;
|
import cn.iocoder.yudao.module.infra.api.file.dto.FileCreateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.infra.api.file.dto.UserFileUpdateReqDTO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.BpmFileUploadReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.BpmFileUploadReqVO;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.UserFileUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@ -59,4 +62,12 @@ public class FileApiImpl implements FileApi {
|
|||||||
|
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> updateUserFileUserId(UserFileUpdateReqDTO updateReqVO) {
|
||||||
|
|
||||||
|
UserFileUpdateReqVO reqVO = BeanUtils.toBean(updateReqVO, UserFileUpdateReqVO.class);
|
||||||
|
fileService.updateUserFileUserId(reqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.*;
|
|||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BpmFileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BpmFileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BusinessFileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BusinessFileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.UserFileDO;
|
||||||
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
@ -140,4 +141,19 @@ public class FileController {
|
|||||||
return "success" ;
|
return "success" ;
|
||||||
}
|
}
|
||||||
//add by yj 2024 04-11 End
|
//add by yj 2024 04-11 End
|
||||||
|
|
||||||
|
@PostMapping("/userFileUpload")
|
||||||
|
@Operation(summary = "上传用户文件")
|
||||||
|
@OperateLog(logArgs = false) // 上传文件,没有记录操作日志的必要
|
||||||
|
public CommonResult<UserFileDO> userFileUpload(@RequestParam("uploadFiles") MultipartFile file) {
|
||||||
|
return success(fileService.createUserReturnFile(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/deleteUserFile")
|
||||||
|
@Operation(summary = "删除用户文件")
|
||||||
|
@Parameter(name = "url", description = "附件URL地址", required = true)
|
||||||
|
public CommonResult<Boolean> deleteUserFile(@RequestParam("url") String url) throws Exception {
|
||||||
|
fileService.deleteUserFile(url);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.file.vo.file;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 用户文件绑定 用户编号 Request VO")
|
||||||
|
@Data
|
||||||
|
public class UserFileUpdateReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "附件地址", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "附件地址不能为空")
|
||||||
|
private List<String> urls;
|
||||||
|
|
||||||
|
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "用户编号不能为空")
|
||||||
|
private Long userId;
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.dal.dataobject.file;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件表
|
||||||
|
* 每次文件上传,都会记录一条记录到该表中
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableName("system_user_file")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class UserFileDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号,数据库自增
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 配置编号
|
||||||
|
*
|
||||||
|
* 关联 {@link FileConfigDO#getId()}
|
||||||
|
*/
|
||||||
|
private Long configId;
|
||||||
|
/**
|
||||||
|
* 原文件名
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 路径,即文件名
|
||||||
|
*/
|
||||||
|
private String path;
|
||||||
|
/**
|
||||||
|
* 访问地址
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
/**
|
||||||
|
* 文件的 MIME 类型,例如 "application/octet-stream"
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
/**
|
||||||
|
* 文件大小
|
||||||
|
*/
|
||||||
|
private Integer size;
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.dal.mysql.file;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.UserFileDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface UserFileMapper extends BaseMapperX<UserFileDO> {
|
||||||
|
}
|
@ -4,9 +4,11 @@ import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.BpmFileUpload
|
|||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.BusinessFileUploadReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.BusinessFileUploadReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.UserFileUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BpmFileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BpmFileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BusinessFileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BusinessFileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.UserFileDO;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,4 +129,24 @@ public interface FileService {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
String updateBusinessFileContent(String url, Long businessType, String name, byte[] content) ;
|
String updateBusinessFileContent(String url, Long businessType, String name, byte[] content) ;
|
||||||
|
|
||||||
|
/**3
|
||||||
|
* 保存用户文件,并返回文件对象
|
||||||
|
*
|
||||||
|
* @param file 上传文件对象
|
||||||
|
* @return 文件路径
|
||||||
|
*/
|
||||||
|
UserFileDO createUserReturnFile(MultipartFile file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除用户文件
|
||||||
|
* @param url 文件URL地址
|
||||||
|
*/
|
||||||
|
void deleteUserFile(String url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户文件 UserId
|
||||||
|
* @param updateReqVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateUserFileUserId(UserFileUpdateReqVO updateReqVO);
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,12 @@ import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
|||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.BpmFileUploadReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.BpmFileUploadReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.BusinessFileUploadReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.BusinessFileUploadReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.UserFileUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BpmFileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BpmFileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BusinessFileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.BusinessFileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.BpmFileMapper;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.UserFileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.BusinessFileMapper;
|
import cn.iocoder.yudao.module.infra.dal.mysql.file.*;
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileContentMapper;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -50,6 +49,9 @@ public class FileServiceImpl implements FileService {
|
|||||||
@Resource
|
@Resource
|
||||||
private FileContentMapper fileContentMapper;
|
private FileContentMapper fileContentMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UserFileMapper userFileMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<FileDO> getFilePage(FilePageReqVO pageReqVO) {
|
public PageResult<FileDO> getFilePage(FilePageReqVO pageReqVO) {
|
||||||
return fileMapper.selectPage(pageReqVO);
|
return fileMapper.selectPage(pageReqVO);
|
||||||
@ -396,4 +398,74 @@ public class FileServiceImpl implements FileService {
|
|||||||
}
|
}
|
||||||
return url ;
|
return url ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public UserFileDO createUserReturnFile(MultipartFile file) {
|
||||||
|
|
||||||
|
long timestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
String name = file.getOriginalFilename();
|
||||||
|
String path = null;
|
||||||
|
byte[] content = IoUtil.readBytes(file.getInputStream());
|
||||||
|
|
||||||
|
// 计算默认的 path 名
|
||||||
|
String type = FileTypeUtils.getMineType(content, name);
|
||||||
|
|
||||||
|
// 如果 name 为空,则使用 path 填充
|
||||||
|
if (!StrUtil.isEmpty(name)) {
|
||||||
|
String beginPath = name.split("\\.")[0];
|
||||||
|
path = beginPath + "_" + timestamp + "." + FileNameUtil.extName(name);
|
||||||
|
}else {
|
||||||
|
name = "File" + timestamp;
|
||||||
|
path = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传到文件存储器
|
||||||
|
FileClient client = fileConfigService.getMasterFileClient();
|
||||||
|
Assert.notNull(client, "客户端(master) 不能为空");
|
||||||
|
String url = client.upload(content, path, type);
|
||||||
|
|
||||||
|
// 插入 system_user_file
|
||||||
|
UserFileDO fileDo = new UserFileDO();
|
||||||
|
fileDo.setConfigId(client.getId());
|
||||||
|
fileDo.setName(name);
|
||||||
|
fileDo.setPath(path);
|
||||||
|
fileDo.setUrl(url);
|
||||||
|
fileDo.setType(type);
|
||||||
|
fileDo.setSize(content.length);
|
||||||
|
userFileMapper.insert(fileDo);
|
||||||
|
|
||||||
|
return fileDo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public void deleteUserFile(String url) {
|
||||||
|
|
||||||
|
String path = url.substring(url.lastIndexOf("/") + 1);
|
||||||
|
UserFileDO file = userFileMapper.selectOne(UserFileDO::getPath, path);
|
||||||
|
if (file == null) {
|
||||||
|
throw exception(FILE_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从文件存储器中删除
|
||||||
|
FileClient client = fileConfigService.getFileClient(file.getConfigId());
|
||||||
|
Assert.notNull(client, "客户端({}) 不能为空", file.getConfigId());
|
||||||
|
client.delete(file.getPath());
|
||||||
|
|
||||||
|
// 删除记录
|
||||||
|
userFileMapper.deleteById(file.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateUserFileUserId(UserFileUpdateReqVO updateReqVO) {
|
||||||
|
|
||||||
|
LambdaUpdateWrapper<UserFileDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
|
||||||
|
lambdaUpdateWrapper.in(UserFileDO::getUrl, updateReqVO.getUrls());
|
||||||
|
lambdaUpdateWrapper.set(UserFileDO::getUserId, updateReqVO.getUserId()); // 假设 bid 是要更新的 bid 值
|
||||||
|
|
||||||
|
// 调用 MyBatis Plus 的 update 方法执行批量更新
|
||||||
|
userFileMapper.update(null, lambdaUpdateWrapper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user