1
0

feat(web): 实现文件上传和下载功能

- 在 DataFileController 中添加文件上传和下载接口- 更新 WareController 中的图标处理逻辑
- 在 DataFile 实体中添加文件类型字段
- 更新 DataFileService 中的文件信息更新方法
- 在前端组件中添加文件上传和下载相关配置
This commit is contained in:
2024-12-17 10:31:34 +08:00
parent 94a3be2b58
commit 420651c073
6 changed files with 69 additions and 12 deletions

View File

@@ -1,5 +1,5 @@
export const information = { export const information = {
debug: false, debug: true,
// baseUrl: '', // baseUrl: '',
baseUrl: 'http://127.0.0.1:20080', baseUrl: 'http://127.0.0.1:20080',
title: '可信供给中心', title: '可信供给中心',
@@ -347,7 +347,12 @@ const formInputFileStaticColumns = [
type: 'action', type: 'action',
label: '下载', label: '下载',
level: 'link', level: 'link',
icon: 'fa fa-download' icon: 'fa fa-download',
actionType: 'ajax',
api: {
...apiGet('${base}/upload/download/${id}'),
responseType: 'blob',
}
} }
] ]
} }

View File

@@ -21,6 +21,10 @@ function detailForm() {
name: 'icon', name: 'icon',
label: '图标', label: '图标',
required: true, required: true,
receiver: apiPost("${base}/upload"),
autoFill: {
iconId: '${id}',
}
}, },
{ {
type: 'picker', type: 'picker',
@@ -75,6 +79,7 @@ function detailForm() {
name: 'content', name: 'content',
label: '商品详情', label: '商品详情',
required: true, required: true,
receiver: '',
options: { options: {
min_height: 300, min_height: 300,
} }

View File

@@ -1,10 +1,12 @@
package com.eshore.gringotts.web.domain.controller; package com.eshore.gringotts.web.domain.controller;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.SecureUtil;
import com.eshore.gringotts.web.configuration.UploadConfiguration; import com.eshore.gringotts.web.configuration.UploadConfiguration;
import com.eshore.gringotts.web.configuration.amis.AmisResponse; import com.eshore.gringotts.web.configuration.amis.AmisResponse;
import com.eshore.gringotts.web.domain.entity.DataFile;
import com.eshore.gringotts.web.domain.service.DataFileService; import com.eshore.gringotts.web.domain.service.DataFileService;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@@ -13,12 +15,15 @@ import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import javax.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.collections.api.list.ImmutableList; import org.eclipse.collections.api.list.ImmutableList;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@@ -50,6 +55,40 @@ public class DataFileController {
this.sliceFolderPath = StrUtil.format("{}/slice", uploadFolderPath); this.sliceFolderPath = StrUtil.format("{}/slice", uploadFolderPath);
} }
@PostMapping("")
public AmisResponse<FinishResponse> upload(@RequestParam("file") MultipartFile file) throws IOException {
String filename = file.getOriginalFilename();
Long id = dataFileService.initialDataFile(filename);
String url = StrUtil.format("/upload/download/{}", id);
byte[] bytes = file.getBytes();
String originMd5 = SecureUtil.md5(new ByteArrayInputStream(bytes));
File targetFile = new File(StrUtil.format("{}/{}", uploadFolderPath, originMd5));
if (targetFile.exists()) {
dataFileService.updateDataFile(id, FileUtil.getAbsolutePath(targetFile), FileUtil.size(targetFile), originMd5, file.getContentType());
return AmisResponse.responseSuccess(new FinishResponse(id, filename, url, url));
}
File cacheFile = new File(StrUtil.format("{}/{}", cacheFolderPath, id));
cacheFile = FileUtil.writeBytes(bytes, cacheFile);
String targetMd5 = SecureUtil.md5(cacheFile);
if (!StrUtil.equals(originMd5, targetMd5)) {
throw new RuntimeException("文件上传失败,校验不匹配");
}
FileUtil.move(cacheFile, targetFile, true);
dataFileService.updateDataFile(id, FileUtil.getAbsolutePath(targetFile), FileUtil.size(targetFile), targetMd5, file.getContentType());
return AmisResponse.responseSuccess(new FinishResponse(id, filename, url, url));
}
@GetMapping("/download/{id}")
public void download(@PathVariable Long id, HttpServletResponse response) throws IOException {
DataFile dataFile = dataFileService.detailOrThrow(id);
File targetFile = new File(dataFile.getPath());
response.setHeader("Access-Control-Expose-Headers", "Content-Type");
response.setHeader("Content-Type", dataFile.getType());
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-Disposition", StrUtil.format("attachment; filename={}", dataFile.getFilename()));
IoUtil.copy(new FileInputStream(targetFile), response.getOutputStream());
}
@PostMapping("/start") @PostMapping("/start")
public AmisResponse<StartResponse> start(@RequestBody StartRequest request) { public AmisResponse<StartResponse> start(@RequestBody StartRequest request) {
logger.info("Request: {}", request); logger.info("Request: {}", request);
@@ -107,12 +146,19 @@ public class DataFileController {
if (!targetFile.exists()) { if (!targetFile.exists()) {
FileUtil.move(cacheFile, targetFile, true); FileUtil.move(cacheFile, targetFile, true);
} }
dataFileService.updateDataFile(request.uploadId, FileUtil.getAbsolutePath(targetFile), FileUtil.size(targetFile), SecureUtil.md5(targetFile)); String absolutePath = FileUtil.getAbsolutePath(targetFile);
dataFileService.updateDataFile(
request.uploadId,
absolutePath,
FileUtil.size(targetFile),
SecureUtil.md5(targetFile),
FileUtil.getMimeType(absolutePath)
);
return AmisResponse.responseSuccess(new FinishResponse( return AmisResponse.responseSuccess(new FinishResponse(
request.uploadId, request.uploadId,
request.filename, request.filename,
request.uploadId, request.uploadId.toString(),
StrUtil.format("https://localhost:9090") StrUtil.format("/upload/download/{}", request.uploadId)
)); ));
} else { } else {
throw new RuntimeException("合并文件失败"); throw new RuntimeException("合并文件失败");
@@ -166,7 +212,7 @@ public class DataFileController {
public static final class FinishResponse { public static final class FinishResponse {
private Long id; private Long id;
private String filename; private String filename;
private Long value; private String value;
private String url; private String url;
} }
} }

View File

@@ -1,7 +1,6 @@
package com.eshore.gringotts.web.domain.controller; package com.eshore.gringotts.web.domain.controller;
import com.eshore.gringotts.web.domain.base.controller.SimpleControllerSupport; import com.eshore.gringotts.web.domain.base.controller.SimpleControllerSupport;
import com.eshore.gringotts.web.domain.base.entity.FileInfo;
import com.eshore.gringotts.web.domain.base.entity.SimpleListItem; import com.eshore.gringotts.web.domain.base.entity.SimpleListItem;
import com.eshore.gringotts.web.domain.base.entity.SimpleSaveItem; import com.eshore.gringotts.web.domain.base.entity.SimpleSaveItem;
import com.eshore.gringotts.web.domain.entity.Ware; import com.eshore.gringotts.web.domain.entity.Ware;
@@ -36,9 +35,9 @@ public class WareController extends SimpleControllerSupport<Ware, WareController
protected Ware fromSaveItem(SaveItem saveItem) throws Exception { protected Ware fromSaveItem(SaveItem saveItem) throws Exception {
Ware ware = new Ware(); Ware ware = new Ware();
ware.setResource(dataResourceService.detailOrThrow(saveItem.getResourceId())); ware.setResource(dataResourceService.detailOrThrow(saveItem.getResourceId()));
ware.setName(ware.getName()); ware.setName(saveItem.getName());
ware.setDescription(saveItem.getDescription()); ware.setDescription(saveItem.getDescription());
ware.setIcon(dataFileService.detailOrThrow(saveItem.getIcon().getValue())); ware.setIcon(dataFileService.detailOrThrow(saveItem.getIconId()));
ware.setContent(saveItem.getContent()); ware.setContent(saveItem.getContent());
return ware; return ware;
} }
@@ -59,7 +58,7 @@ public class WareController extends SimpleControllerSupport<Ware, WareController
private Long resourceId; private Long resourceId;
private String name; private String name;
private String description; private String description;
private FileInfo icon; private Long iconId;
private String content; private String content;
} }
@@ -93,7 +92,7 @@ public class WareController extends SimpleControllerSupport<Ware, WareController
this.setResourceName(ware.getResource().getName()); this.setResourceName(ware.getResource().getName());
this.setName(ware.getName()); this.setName(ware.getName());
this.setDescription(ware.getDescription()); this.setDescription(ware.getDescription());
this.setIcon(new FileInfo(ware.getIcon())); this.setIconId(ware.getIcon().getId());
this.setContent(ware.getContent()); this.setContent(ware.getContent());
} }
} }

View File

@@ -30,4 +30,5 @@ public class DataFile extends LogicDeleteEntity {
private Long size; private Long size;
private String md5; private String md5;
private String path; private String path;
private String type;
} }

View File

@@ -74,11 +74,12 @@ public class DataFileService extends SimpleServiceSupport<DataFile> {
return dataFileRepository.save(dataFile).getId(); return dataFileRepository.save(dataFile).getId();
} }
public void updateDataFile(Long id, String path, Long size, String md5) { public void updateDataFile(Long id, String path, Long size, String md5, String type) {
DataFile dataFile = dataFileRepository.findById(id).orElseThrow(UpdateDataFileFailedException::new); DataFile dataFile = dataFileRepository.findById(id).orElseThrow(UpdateDataFileFailedException::new);
dataFile.setSize(size); dataFile.setSize(size);
dataFile.setMd5(md5); dataFile.setMd5(md5);
dataFile.setPath(path); dataFile.setPath(path);
dataFile.setType(type);
User loginUser = userService.currentLoginUser(); User loginUser = userService.currentLoginUser();
dataFile.setModifiedUser(loginUser); dataFile.setModifiedUser(loginUser);
dataFileRepository.save(dataFile); dataFileRepository.save(dataFile);