mirror of
https://gitee.com/czh-dev/upload-hub
synced 2026-09-06 16:07:07 +08:00
feat:新增共享文件功能
This commit is contained in:
@@ -2,6 +2,7 @@ package cn.czh.controller;
|
|||||||
|
|
||||||
import cn.czh.base.Result;
|
import cn.czh.base.Result;
|
||||||
import cn.czh.entity.StorageConfig;
|
import cn.czh.entity.StorageConfig;
|
||||||
|
import cn.czh.service.IAuthService;
|
||||||
import cn.czh.service.IStorageConfigService;
|
import cn.czh.service.IStorageConfigService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@@ -14,6 +15,8 @@ public class ConfigController {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private IStorageConfigService storageConfigService;
|
private IStorageConfigService storageConfigService;
|
||||||
|
@Resource
|
||||||
|
private IAuthService authService;
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public Result<?> getConfig(String type) {
|
public Result<?> getConfig(String type) {
|
||||||
@@ -31,4 +34,10 @@ public class ConfigController {
|
|||||||
storageConfigService.testStorageConfig(config);
|
storageConfigService.testStorageConfig(config);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/set-password")
|
||||||
|
public Result<?> setPassword(@RequestBody String password) {
|
||||||
|
authService.setMainUserPassword(password);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,30 @@ package cn.czh.controller;
|
|||||||
|
|
||||||
import cn.czh.base.Result;
|
import cn.czh.base.Result;
|
||||||
import cn.czh.entity.StorageConfig;
|
import cn.czh.entity.StorageConfig;
|
||||||
|
import cn.czh.service.IAuthService;
|
||||||
import cn.czh.service.IFileService;
|
import cn.czh.service.IFileService;
|
||||||
import cn.czh.service.IStorageConfigService;
|
import cn.czh.service.IStorageConfigService;
|
||||||
import cn.czh.utils.FileTypeUtil;
|
import cn.czh.utils.FileTypeUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.core.io.ByteArrayResource;
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.Inet4Address;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/file")
|
@RequestMapping("/file")
|
||||||
public class FileController {
|
public class FileController {
|
||||||
@@ -29,6 +34,13 @@ public class FileController {
|
|||||||
private IStorageConfigService storageConfigService;
|
private IStorageConfigService storageConfigService;
|
||||||
@Resource
|
@Resource
|
||||||
private IFileService fileService;
|
private IFileService fileService;
|
||||||
|
@Resource
|
||||||
|
private IAuthService authService;
|
||||||
|
|
||||||
|
@Value("${server.port}")
|
||||||
|
private String serverPort;
|
||||||
|
|
||||||
|
private static boolean enableShare = false;
|
||||||
|
|
||||||
@GetMapping("/preview/{storageType}/**")
|
@GetMapping("/preview/{storageType}/**")
|
||||||
public ResponseEntity<?> previewFile(
|
public ResponseEntity<?> previewFile(
|
||||||
@@ -76,7 +88,11 @@ public class FileController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
public Result<?> pageFiles(Integer page, Integer pageSize, String storageType, String fileName) {
|
public Result<?> pageFiles(HttpServletRequest request, Integer page, Integer pageSize, String storageType, String fileName) {
|
||||||
|
if (!authService.isMainUser(request.getRemoteAddr())) {
|
||||||
|
return Result.error("权限不足");
|
||||||
|
}
|
||||||
|
|
||||||
if (page == null) {
|
if (page == null) {
|
||||||
page = 1;
|
page = 1;
|
||||||
}
|
}
|
||||||
@@ -85,4 +101,83 @@ public class FileController {
|
|||||||
}
|
}
|
||||||
return Result.success(fileService.pageFiles(page, pageSize, storageType, fileName));
|
return Result.success(fileService.pageFiles(page, pageSize, storageType, fileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/sharedFile")
|
||||||
|
public Result<?> listSharedFiles(@RequestParam String fileIdentifier) {
|
||||||
|
fileService.addSharedFile(fileIdentifier);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/unShareFile")
|
||||||
|
public Result<?> unShareFile(HttpServletRequest request, @RequestParam String fileIdentifier) {
|
||||||
|
if (!authService.isMainUser(request.getRemoteAddr())) {
|
||||||
|
return Result.error("非主用户不能取消分享");
|
||||||
|
}
|
||||||
|
fileService.removeSharedFile(fileIdentifier);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/sharedFiles")
|
||||||
|
public Result<?> getSharedFiles(HttpServletRequest request, @RequestHeader("Authorization") String password) {
|
||||||
|
boolean isMainUser = authService.isMainUser(request.getRemoteAddr());
|
||||||
|
String mainUserPassword = authService.getMainUserPassword();
|
||||||
|
|
||||||
|
if (!isMainUser && !mainUserPassword.equals(password)) {
|
||||||
|
return Result.error("密码错误");
|
||||||
|
}
|
||||||
|
if (!isMainUser && !enableShare) {
|
||||||
|
return Result.error("分享功能未开启");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.success(fileService.listSharedFiles());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/enableShare")
|
||||||
|
public Result<?> enableShare(HttpServletRequest request, @RequestParam Boolean enable) {
|
||||||
|
if (!authService.isMainUser(request.getRemoteAddr())) {
|
||||||
|
return Result.error("非主用户不能修改分享状态");
|
||||||
|
}
|
||||||
|
enableShare = enable;
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/getShareStatus")
|
||||||
|
public Result<?> getShareStatus() {
|
||||||
|
return Result.success(enableShare);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/shareAddress")
|
||||||
|
public Result<?> getShareAddress() {
|
||||||
|
String ip;
|
||||||
|
try {
|
||||||
|
ip = getLocalIpAddress();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取本地IP地址失败:{}", e.getMessage(), e);
|
||||||
|
ip = "localhost";
|
||||||
|
}
|
||||||
|
return Result.success("http://" + ip + ":" + serverPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLocalIpAddress() throws Exception {
|
||||||
|
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
|
||||||
|
while (interfaces.hasMoreElements()) {
|
||||||
|
NetworkInterface networkInterface = interfaces.nextElement();
|
||||||
|
// 跳过回环接口和未启用的接口
|
||||||
|
if (networkInterface.isLoopback() || !networkInterface.isUp()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
|
||||||
|
while (addresses.hasMoreElements()) {
|
||||||
|
InetAddress addr = addresses.nextElement();
|
||||||
|
if (addr instanceof Inet4Address && !addr.isLoopbackAddress()) {
|
||||||
|
String ip = addr.getHostAddress();
|
||||||
|
if (ip.startsWith("192.168.") || ip.startsWith("10.") ||
|
||||||
|
(ip.startsWith("172.") && Integer.parseInt(ip.split("\\.")[1]) >= 16 && Integer.parseInt(ip.split("\\.")[1]) <= 31)) {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ import cn.czh.base.Result;
|
|||||||
import cn.czh.dto.req.CreateMultipartUpload;
|
import cn.czh.dto.req.CreateMultipartUpload;
|
||||||
import cn.czh.entity.StorageConfig;
|
import cn.czh.entity.StorageConfig;
|
||||||
import cn.czh.entity.UploadFile;
|
import cn.czh.entity.UploadFile;
|
||||||
|
import cn.czh.service.IAuthService;
|
||||||
import cn.czh.service.IStorageService;
|
import cn.czh.service.IStorageService;
|
||||||
import cn.czh.service.StorageServiceFactory;
|
import cn.czh.service.StorageServiceFactory;
|
||||||
import cn.czh.utils.FileTypeUtil;
|
import cn.czh.utils.FileTypeUtil;
|
||||||
@@ -27,6 +28,8 @@ public class UploadController {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private StorageServiceFactory storageServiceFactory;
|
private StorageServiceFactory storageServiceFactory;
|
||||||
|
@Resource
|
||||||
|
private IAuthService authService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从请求中获取存储类型(示例:从请求头获取)
|
* 从请求中获取存储类型(示例:从请求头获取)
|
||||||
@@ -83,9 +86,10 @@ public class UploadController {
|
|||||||
|
|
||||||
@PostMapping("/merge")
|
@PostMapping("/merge")
|
||||||
public Result<?> merge(HttpServletRequest request, String identifier) {
|
public Result<?> merge(HttpServletRequest request, String identifier) {
|
||||||
|
boolean mainUser = authService.isMainUser(request.getRemoteAddr());
|
||||||
String storageType = getStorageTypeFromRequest(request);
|
String storageType = getStorageTypeFromRequest(request);
|
||||||
IStorageService storageService = storageServiceFactory.getStorageService(storageType);
|
IStorageService storageService = storageServiceFactory.getStorageService(storageType);
|
||||||
return Result.success(storageService.merge(identifier));
|
return Result.success(storageService.merge(identifier, mainUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@@ -101,6 +105,8 @@ public class UploadController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean mainUser = authService.isMainUser(request.getRemoteAddr());
|
||||||
|
|
||||||
String md5 = SecureUtil.md5(file.getInputStream());
|
String md5 = SecureUtil.md5(file.getInputStream());
|
||||||
synchronized (md5.intern()) {
|
synchronized (md5.intern()) {
|
||||||
String dateFormat = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
|
String dateFormat = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
|
||||||
@@ -109,7 +115,7 @@ public class UploadController {
|
|||||||
dateFormat + "/" + md5 + "." + FileTypeUtil.getFileSuffix(filename);
|
dateFormat + "/" + md5 + "." + FileTypeUtil.getFileSuffix(filename);
|
||||||
String storageType = getStorageTypeFromRequest(request);
|
String storageType = getStorageTypeFromRequest(request);
|
||||||
IStorageService storageService = storageServiceFactory.getStorageService(storageType);
|
IStorageService storageService = storageServiceFactory.getStorageService(storageType);
|
||||||
return Result.success(storageService.uploadFile(file, md5, objectName));
|
return Result.success(storageService.uploadFile(file, md5, objectName, mainUser));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package cn.czh.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("shared_file")
|
||||||
|
public class SharedFile {
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
private String fileIdentifier;
|
||||||
|
private String createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package cn.czh.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("user_config")
|
||||||
|
public class UserConfig {
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private Integer isMainUser; // 0 or 1
|
||||||
|
private String createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package cn.czh.mapper;
|
||||||
|
|
||||||
|
import cn.czh.entity.SharedFile;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface ShareFileMapper extends BaseMapper<SharedFile> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package cn.czh.mapper;
|
||||||
|
|
||||||
|
import cn.czh.entity.UserConfig;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface UserConfigMapper extends BaseMapper<UserConfig> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package cn.czh.service;
|
||||||
|
|
||||||
|
public interface IAuthService {
|
||||||
|
|
||||||
|
String getMainUserPassword();
|
||||||
|
|
||||||
|
void setMainUserPassword(String password);
|
||||||
|
|
||||||
|
boolean isMainUser(String remoteAddress);
|
||||||
|
}
|
||||||
@@ -3,8 +3,16 @@ package cn.czh.service;
|
|||||||
import cn.czh.entity.UploadFile;
|
import cn.czh.entity.UploadFile;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface IFileService {
|
public interface IFileService {
|
||||||
|
|
||||||
IPage<UploadFile> pageFiles(Integer page, Integer pageSize, String storageType, String fileName);
|
IPage<UploadFile> pageFiles(Integer page, Integer pageSize, String storageType, String fileName);
|
||||||
|
|
||||||
|
List<UploadFile> listSharedFiles();
|
||||||
|
|
||||||
|
void addSharedFile(String identifier);
|
||||||
|
|
||||||
|
void removeSharedFile(String fileIdentifier);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public interface IStorageService {
|
|||||||
/**
|
/**
|
||||||
* 普通文件上传
|
* 普通文件上传
|
||||||
*/
|
*/
|
||||||
FileRecordDTO uploadFile(MultipartFile file, String md5, String objectName);
|
FileRecordDTO uploadFile(MultipartFile file, String md5, String objectName, Boolean admin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件上传进度
|
* 获取文件上传进度
|
||||||
@@ -29,7 +29,7 @@ public interface IStorageService {
|
|||||||
/**
|
/**
|
||||||
* 合并分片文件
|
* 合并分片文件
|
||||||
*/
|
*/
|
||||||
UploadFile merge(String identifier);
|
UploadFile merge(String identifier, Boolean admin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据md5标识获取分片上传任务
|
* 根据md5标识获取分片上传任务
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package cn.czh.service.impl;
|
||||||
|
|
||||||
|
import cn.czh.entity.UserConfig;
|
||||||
|
import cn.czh.mapper.UserConfigMapper;
|
||||||
|
import cn.czh.service.IAuthService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AuthServiceImpl implements IAuthService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UserConfigMapper userConfigMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMainUserPassword() {
|
||||||
|
UserConfig user = userConfigMapper.selectOne(
|
||||||
|
new LambdaQueryWrapper<UserConfig>()
|
||||||
|
.eq(UserConfig::getIsMainUser, 1)
|
||||||
|
);
|
||||||
|
if (user == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return user.getPassword() == null || user.getPassword().trim().isEmpty() ? "" : user.getPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMainUserPassword(String password) {
|
||||||
|
UserConfig user = userConfigMapper.selectOne(
|
||||||
|
new LambdaQueryWrapper<UserConfig>()
|
||||||
|
.eq(UserConfig::getIsMainUser, 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
user = new UserConfig();
|
||||||
|
user.setUsername("admin");
|
||||||
|
user.setIsMainUser(1);
|
||||||
|
user.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||||
|
|
||||||
|
}
|
||||||
|
user.setPassword(password != null && password.trim().isEmpty() ? null : password);
|
||||||
|
if (user.getId() == null) {
|
||||||
|
userConfigMapper.insert(user);
|
||||||
|
} else {
|
||||||
|
userConfigMapper.updateById(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMainUser(String remoteAddress) {
|
||||||
|
return "127.0.0.1".equals(remoteAddress) || "0:0:0:0:0:0:0:1".equals(remoteAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +1,70 @@
|
|||||||
package cn.czh.service.impl;
|
package cn.czh.service.impl;
|
||||||
|
|
||||||
|
import cn.czh.entity.SharedFile;
|
||||||
import cn.czh.entity.UploadFile;
|
import cn.czh.entity.UploadFile;
|
||||||
|
import cn.czh.mapper.ShareFileMapper;
|
||||||
import cn.czh.mapper.UploadFileMapper;
|
import cn.czh.mapper.UploadFileMapper;
|
||||||
import cn.czh.service.IFileService;
|
import cn.czh.service.IFileService;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class FileServiceImpl implements IFileService {
|
public class FileServiceImpl implements IFileService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private UploadFileMapper uploadFileMapper;
|
private UploadFileMapper uploadFileMapper;
|
||||||
|
@Resource
|
||||||
|
private ShareFileMapper shareFileMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPage<UploadFile> pageFiles(Integer page, Integer pageSize, String storageType, String fileName) {
|
public IPage<UploadFile> pageFiles(Integer page, Integer pageSize, String storageType, String fileName) {
|
||||||
return uploadFileMapper.pageFiles(new Page<>(page, pageSize), storageType, fileName);
|
return uploadFileMapper.pageFiles(new Page<>(page, pageSize), storageType, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UploadFile> listSharedFiles() {
|
||||||
|
|
||||||
|
List<SharedFile> sharedFiles = shareFileMapper.selectList(null);
|
||||||
|
Set<String> files = sharedFiles.stream()
|
||||||
|
.map(SharedFile::getFileIdentifier)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
List<UploadFile> uploadFiles = uploadFileMapper.selectList(null);
|
||||||
|
if (uploadFiles != null) {
|
||||||
|
return uploadFiles.stream()
|
||||||
|
.filter(uploadFile -> files.contains(uploadFile.getFileIdentifier()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addSharedFile(String identifier) {
|
||||||
|
SharedFile sharedFile = shareFileMapper.selectOne(
|
||||||
|
Wrappers.lambdaQuery(SharedFile.class).eq(SharedFile::getFileIdentifier, identifier)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (sharedFile == null) {
|
||||||
|
sharedFile = new SharedFile();
|
||||||
|
sharedFile.setFileIdentifier(identifier);
|
||||||
|
sharedFile.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||||
|
shareFileMapper.insert(sharedFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSharedFile(String fileIdentifier) {
|
||||||
|
shareFileMapper.delete(Wrappers.lambdaQuery(SharedFile.class).eq(SharedFile::getFileIdentifier, fileIdentifier));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import cn.czh.dto.req.CreateMultipartUpload;
|
|||||||
import cn.czh.entity.StorageConfig;
|
import cn.czh.entity.StorageConfig;
|
||||||
import cn.czh.entity.UploadFile;
|
import cn.czh.entity.UploadFile;
|
||||||
import cn.czh.mapper.UploadFileMapper;
|
import cn.czh.mapper.UploadFileMapper;
|
||||||
|
import cn.czh.service.IFileService;
|
||||||
import cn.czh.service.IStorageConfigService;
|
import cn.czh.service.IStorageConfigService;
|
||||||
import cn.czh.service.IStorageService;
|
import cn.czh.service.IStorageService;
|
||||||
import cn.hutool.core.date.DatePattern;
|
import cn.hutool.core.date.DatePattern;
|
||||||
@@ -47,6 +48,8 @@ public class LocalStorageService implements IStorageService {
|
|||||||
private UploadFileMapper uploadFileMapper;
|
private UploadFileMapper uploadFileMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private IStorageConfigService storageConfigService;
|
private IStorageConfigService storageConfigService;
|
||||||
|
@Resource
|
||||||
|
private IFileService fileService;
|
||||||
|
|
||||||
private StorageConfig storageConfig;
|
private StorageConfig storageConfig;
|
||||||
|
|
||||||
@@ -75,7 +78,7 @@ public class LocalStorageService implements IStorageService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public FileRecordDTO uploadFile(MultipartFile file, String md5, String objectName) {
|
public FileRecordDTO uploadFile(MultipartFile file, String md5, String objectName, Boolean admin) {
|
||||||
UploadFile uploadFile = getByIdentifier(md5);
|
UploadFile uploadFile = getByIdentifier(md5);
|
||||||
if (uploadFile != null) {
|
if (uploadFile != null) {
|
||||||
FileRecordDTO fileRecord = new FileRecordDTO();
|
FileRecordDTO fileRecord = new FileRecordDTO();
|
||||||
@@ -117,6 +120,10 @@ public class LocalStorageService implements IStorageService {
|
|||||||
BeanUtils.copyProperties(uploadFile, fileRecord);
|
BeanUtils.copyProperties(uploadFile, fileRecord);
|
||||||
fileRecord.setFileId(uploadFile.getId());
|
fileRecord.setFileId(uploadFile.getId());
|
||||||
fileRecord.setOriginalName(file.getOriginalFilename());
|
fileRecord.setOriginalName(file.getOriginalFilename());
|
||||||
|
|
||||||
|
if (!admin) {
|
||||||
|
fileService.addSharedFile(md5);
|
||||||
|
}
|
||||||
return fileRecord;
|
return fileRecord;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new BusinessException("文件上传失败", e);
|
throw new BusinessException("文件上传失败", e);
|
||||||
@@ -178,7 +185,7 @@ public class LocalStorageService implements IStorageService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public UploadFile merge(String identifier) {
|
public UploadFile merge(String identifier, Boolean admin) {
|
||||||
UploadFile uploadFile = getByIdentifier(identifier);
|
UploadFile uploadFile = getByIdentifier(identifier);
|
||||||
if (uploadFile == null) {
|
if (uploadFile == null) {
|
||||||
throw new BusinessException("上传任务不存在");
|
throw new BusinessException("上传任务不存在");
|
||||||
@@ -223,6 +230,10 @@ public class LocalStorageService implements IStorageService {
|
|||||||
uploadFile.setDownloadUrl(generateWebUrl(uploadFile.getObjectKey()));
|
uploadFile.setDownloadUrl(generateWebUrl(uploadFile.getObjectKey()));
|
||||||
uploadFile.setIsFinish(1);
|
uploadFile.setIsFinish(1);
|
||||||
uploadFileMapper.updateById(uploadFile);
|
uploadFileMapper.updateById(uploadFile);
|
||||||
|
|
||||||
|
if (!admin) {
|
||||||
|
fileService.addSharedFile(uploadFile.getFileIdentifier());
|
||||||
|
}
|
||||||
return uploadFile;
|
return uploadFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import cn.czh.dto.req.CreateMultipartUpload;
|
|||||||
import cn.czh.entity.StorageConfig;
|
import cn.czh.entity.StorageConfig;
|
||||||
import cn.czh.entity.UploadFile;
|
import cn.czh.entity.UploadFile;
|
||||||
import cn.czh.mapper.UploadFileMapper;
|
import cn.czh.mapper.UploadFileMapper;
|
||||||
|
import cn.czh.service.IFileService;
|
||||||
import cn.czh.service.IStorageConfigService;
|
import cn.czh.service.IStorageConfigService;
|
||||||
import cn.czh.service.IStorageService;
|
import cn.czh.service.IStorageService;
|
||||||
import cn.czh.utils.ImgUtils;
|
import cn.czh.utils.ImgUtils;
|
||||||
@@ -61,6 +62,8 @@ public class MinioStorageService implements IStorageService {
|
|||||||
private UploadFileMapper uploadFileMapper;
|
private UploadFileMapper uploadFileMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private IStorageConfigService storageConfigService;
|
private IStorageConfigService storageConfigService;
|
||||||
|
@Resource
|
||||||
|
private IFileService fileService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预签名url过期时间: 10分钟
|
* 预签名url过期时间: 10分钟
|
||||||
@@ -122,7 +125,7 @@ public class MinioStorageService implements IStorageService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public FileRecordDTO uploadFile(MultipartFile file, String md5, String objectName) {
|
public FileRecordDTO uploadFile(MultipartFile file, String md5, String objectName, Boolean admin) {
|
||||||
|
|
||||||
UploadFile uploadFile = getByIdentifier(md5);
|
UploadFile uploadFile = getByIdentifier(md5);
|
||||||
if (ObjectUtil.isNotNull(uploadFile)) {
|
if (ObjectUtil.isNotNull(uploadFile)) {
|
||||||
@@ -164,6 +167,10 @@ public class MinioStorageService implements IStorageService {
|
|||||||
BeanUtils.copyProperties(uploadFile, fileRecord);
|
BeanUtils.copyProperties(uploadFile, fileRecord);
|
||||||
fileRecord.setFileId(uploadFile.getId());
|
fileRecord.setFileId(uploadFile.getId());
|
||||||
fileRecord.setOriginalName(filename);
|
fileRecord.setOriginalName(filename);
|
||||||
|
|
||||||
|
if (!admin) {
|
||||||
|
fileService.addSharedFile(md5);
|
||||||
|
}
|
||||||
return fileRecord;
|
return fileRecord;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new BusinessException("文件上上传失败", e);
|
throw new BusinessException("文件上上传失败", e);
|
||||||
@@ -219,7 +226,7 @@ public class MinioStorageService implements IStorageService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public UploadFile merge(String identifier) {
|
public UploadFile merge(String identifier, Boolean admin) {
|
||||||
UploadFile uploadFile = getByIdentifier(identifier);
|
UploadFile uploadFile = getByIdentifier(identifier);
|
||||||
if (uploadFile == null) {
|
if (uploadFile == null) {
|
||||||
throw new BusinessException("上传任务不存在");
|
throw new BusinessException("上传任务不存在");
|
||||||
@@ -244,6 +251,10 @@ public class MinioStorageService implements IStorageService {
|
|||||||
uploadFile.setDownloadUrl(getFileDownloadUrl(uploadFile.getObjectKey()));
|
uploadFile.setDownloadUrl(getFileDownloadUrl(uploadFile.getObjectKey()));
|
||||||
uploadFile.setIsFinish(1);
|
uploadFile.setIsFinish(1);
|
||||||
uploadFileMapper.updateById(uploadFile);
|
uploadFileMapper.updateById(uploadFile);
|
||||||
|
|
||||||
|
if (!admin) {
|
||||||
|
fileService.addSharedFile(uploadFile.getFileIdentifier());
|
||||||
|
}
|
||||||
return uploadFile;
|
return uploadFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import cn.czh.dto.req.CreateMultipartUpload;
|
|||||||
import cn.czh.entity.StorageConfig;
|
import cn.czh.entity.StorageConfig;
|
||||||
import cn.czh.entity.UploadFile;
|
import cn.czh.entity.UploadFile;
|
||||||
import cn.czh.mapper.UploadFileMapper;
|
import cn.czh.mapper.UploadFileMapper;
|
||||||
|
import cn.czh.service.IFileService;
|
||||||
import cn.czh.service.IStorageConfigService;
|
import cn.czh.service.IStorageConfigService;
|
||||||
import cn.czh.service.IStorageService;
|
import cn.czh.service.IStorageService;
|
||||||
import cn.hutool.core.date.DatePattern;
|
import cn.hutool.core.date.DatePattern;
|
||||||
@@ -49,6 +50,8 @@ public class OssStorageService implements IStorageService {
|
|||||||
private UploadFileMapper uploadFileMapper;
|
private UploadFileMapper uploadFileMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private IStorageConfigService storageConfigService;
|
private IStorageConfigService storageConfigService;
|
||||||
|
@Resource
|
||||||
|
private IFileService fileService;
|
||||||
|
|
||||||
private StorageConfig storageConfig;
|
private StorageConfig storageConfig;
|
||||||
private OSS ossClient;
|
private OSS ossClient;
|
||||||
@@ -83,7 +86,7 @@ public class OssStorageService implements IStorageService {
|
|||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public FileRecordDTO uploadFile(MultipartFile file, String md5, String objectName) {
|
public FileRecordDTO uploadFile(MultipartFile file, String md5, String objectName, Boolean admin) {
|
||||||
UploadFile uploadFile = getByIdentifier(md5);
|
UploadFile uploadFile = getByIdentifier(md5);
|
||||||
if (uploadFile != null) {
|
if (uploadFile != null) {
|
||||||
FileRecordDTO fileRecord = new FileRecordDTO();
|
FileRecordDTO fileRecord = new FileRecordDTO();
|
||||||
@@ -129,6 +132,10 @@ public class OssStorageService implements IStorageService {
|
|||||||
BeanUtils.copyProperties(uploadFile, fileRecord);
|
BeanUtils.copyProperties(uploadFile, fileRecord);
|
||||||
fileRecord.setFileId(uploadFile.getId());
|
fileRecord.setFileId(uploadFile.getId());
|
||||||
fileRecord.setOriginalName(file.getOriginalFilename());
|
fileRecord.setOriginalName(file.getOriginalFilename());
|
||||||
|
|
||||||
|
if (!admin) {
|
||||||
|
fileService.addSharedFile(md5);
|
||||||
|
}
|
||||||
return fileRecord;
|
return fileRecord;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new BusinessException("文件上传失败", e);
|
throw new BusinessException("文件上传失败", e);
|
||||||
@@ -211,7 +218,7 @@ public class OssStorageService implements IStorageService {
|
|||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public UploadFile merge(String identifier) {
|
public UploadFile merge(String identifier, Boolean admin) {
|
||||||
UploadFile uploadFile = getByIdentifier(identifier);
|
UploadFile uploadFile = getByIdentifier(identifier);
|
||||||
if (uploadFile == null) {
|
if (uploadFile == null) {
|
||||||
throw new BusinessException("上传任务不存在");
|
throw new BusinessException("上传任务不存在");
|
||||||
@@ -243,6 +250,10 @@ public class OssStorageService implements IStorageService {
|
|||||||
uploadFile.setDownloadUrl(getFileDownloadUrl(uploadFile.getObjectKey()));
|
uploadFile.setDownloadUrl(getFileDownloadUrl(uploadFile.getObjectKey()));
|
||||||
uploadFile.setIsFinish(1);
|
uploadFile.setIsFinish(1);
|
||||||
uploadFileMapper.updateById(uploadFile);
|
uploadFileMapper.updateById(uploadFile);
|
||||||
|
|
||||||
|
if (!admin) {
|
||||||
|
fileService.addSharedFile(identifier);
|
||||||
|
}
|
||||||
return uploadFile;
|
return uploadFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,55 @@ const testStorageConfig = ({ type, endpoint, accessKey, secretKey, bucket }) =>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取共享文件列表
|
||||||
|
* @param {Object} params 参数对象
|
||||||
|
* @param {string} params.password 密码
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const getSharedFiles = () => {
|
||||||
|
return http.get('/file/sharedFiles');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用或禁用共享
|
||||||
|
* @param {Object} params 参数对象
|
||||||
|
* @param {boolean} params.enable 是否启用
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const enableShare = ({ enable }) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('enable', enable);
|
||||||
|
return http.post("/file/enableShare", formData);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分享状态
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const getShareStatus = () => {
|
||||||
|
return http.get("/file/getShareStatus");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分享地址
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const shareAddress = () => {
|
||||||
|
return http.get("/file/shareAddress");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除共享文件
|
||||||
|
* @param {string} fileIdentifier
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const unShareFile = (fileIdentifier) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('fileIdentifier', fileIdentifier);
|
||||||
|
return http.post("/file/unShareFile", formData);
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getUploadProgress,
|
getUploadProgress,
|
||||||
createMultipartUpload,
|
createMultipartUpload,
|
||||||
@@ -191,5 +240,10 @@ export {
|
|||||||
getStorageConfig,
|
getStorageConfig,
|
||||||
setStorageConfig,
|
setStorageConfig,
|
||||||
testStorageConfig,
|
testStorageConfig,
|
||||||
|
getSharedFiles,
|
||||||
|
enableShare,
|
||||||
|
getShareStatus,
|
||||||
|
shareAddress,
|
||||||
|
unShareFile,
|
||||||
httpExtra
|
httpExtra
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,16 @@ const http = axios.create({
|
|||||||
baseURL: baseUrl
|
baseURL: baseUrl
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 请求拦截器 - 自动添加 Authorization
|
||||||
|
http.interceptors.request.use(config => {
|
||||||
|
// 从 localStorage 获取 password
|
||||||
|
const password = localStorage.getItem('password');
|
||||||
|
config.headers['Authorization'] = password ? password : '';
|
||||||
|
return config;
|
||||||
|
}, error => {
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
// 配置拦截器,返回 response.data
|
// 配置拦截器,返回 response.data
|
||||||
http.interceptors.response.use(response => {
|
http.interceptors.response.use(response => {
|
||||||
return response.data;
|
return response.data;
|
||||||
@@ -22,4 +32,14 @@ const httpExtra = axiosExtra.create({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
httpExtra.interceptors.request.use(config => {
|
||||||
|
const password = localStorage.getItem('password');
|
||||||
|
if (password) {
|
||||||
|
config.headers['Authorization'] = password;
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}, error => {
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
export { http, baseUrl, httpExtra };
|
export { http, baseUrl, httpExtra };
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<div class="tab-underline"></div>
|
<div class="tab-underline"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="activeTab !== 'gallery' && !isWipTab" class="upload-content">
|
<div v-if="activeTab !== 'gallery' && activeTab !== 'shared' && !isWipTab" class="upload-content">
|
||||||
<upload-file :file-list.sync="fileList" :accept="allowedFormats" :max-size="maxUploadSize" width="100%"
|
<upload-file :file-list.sync="fileList" :accept="allowedFormats" :max-size="maxUploadSize" width="100%"
|
||||||
height="400px" :storage-type="activeTab" />
|
height="400px" :storage-type="activeTab" />
|
||||||
</div>
|
</div>
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
<p v-else-if="activeTab === 'qiniu'">七牛云功能正在被疯狂调教,马上就能和大家见面啦!</p>
|
<p v-else-if="activeTab === 'qiniu'">七牛云功能正在被疯狂调教,马上就能和大家见面啦!</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<share-file v-else-if="activeTab === 'shared'" />
|
||||||
<file-gallery v-else />
|
<file-gallery v-else />
|
||||||
<settings-modal :show="showSettings" :allowed-formats="allowedFormats" :max-upload-size="maxUploadSize"
|
<settings-modal :show="showSettings" :allowed-formats="allowedFormats" :max-upload-size="maxUploadSize"
|
||||||
@save="saveSettings" @close="closeSettings" />
|
@save="saveSettings" @close="closeSettings" />
|
||||||
@@ -49,10 +50,11 @@ import FileGallery from '@/components/FileGallery/FileGallery.vue';
|
|||||||
import SettingsModal from '@/components/SettingsModal/SettingsModal.vue';
|
import SettingsModal from '@/components/SettingsModal/SettingsModal.vue';
|
||||||
import StorageConfigModal from '@/components/StorageConfigModal/StorageConfigModal.vue';
|
import StorageConfigModal from '@/components/StorageConfigModal/StorageConfigModal.vue';
|
||||||
import AboutModal from '@/components/AboutModal/AboutModal.vue';
|
import AboutModal from '@/components/AboutModal/AboutModal.vue';
|
||||||
|
import ShareFile from '@/components/ShareFile/ShareFile.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MainPage',
|
name: 'MainPage',
|
||||||
components: { UploadFile, FileGallery, SettingsModal, StorageConfigModal, AboutModal },
|
components: { UploadFile, FileGallery, SettingsModal, StorageConfigModal, AboutModal, ShareFile },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fileList: [],
|
fileList: [],
|
||||||
@@ -63,7 +65,8 @@ export default {
|
|||||||
{ label: 'OSS', value: 'oss' },
|
{ label: 'OSS', value: 'oss' },
|
||||||
{ label: 'OBS', value: 'obs' },
|
{ label: 'OBS', value: 'obs' },
|
||||||
{ label: 'QiNiu', value: 'qiniu' },
|
{ label: 'QiNiu', value: 'qiniu' },
|
||||||
{ label: '已上传文件', value: 'gallery' }
|
{ label: '已上传文件', value: 'gallery' },
|
||||||
|
{ label: '共享文件', value: 'shared' },
|
||||||
],
|
],
|
||||||
showMenu: false,
|
showMenu: false,
|
||||||
showSettings: false,
|
showSettings: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user