文件存储功能开发

dev_xq_0.0.1
谢庆 3 weeks ago
parent c5cdcd4730
commit 17bc3392ad

@ -56,6 +56,12 @@ public class ApiResult<T> implements Serializable {
return apiResult; return apiResult;
} }
// public static <T> ApiResult<T> error(T data) {
// ApiResult<T> apiResult = new ApiResult<>();
// apiResult.data = data;
// return apiResult;
// }
public static <T> ApiResult<T> success(T data, Object param) { public static <T> ApiResult<T> success(T data, Object param) {
ApiResult<T> apiResult = new ApiResult<>(); ApiResult<T> apiResult = new ApiResult<>();
apiResult.data = data; apiResult.data = data;

@ -1,137 +0,0 @@
package com.sz.admin.monitor.controller;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
import com.sz.admin.monitor.pojo.dto.dataModel.DataModelDTO;
import com.sz.admin.monitor.pojo.que.dataModel.DataModelQue;
import com.sz.admin.monitor.service.impl.DataModelServiceImpl;
import com.sz.core.common.entity.ApiResult;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author xq
* @description:
* @date 2026/1/29 10:52
*/
@Slf4j
@RestController
@RequestMapping("/data/model")
public class DataModelController {
@Autowired
private DataModelServiceImpl dataModelService;
@GetMapping("/getImageUrl")
public Map<String, String> getImageUrl() {
String filePath = "G:\\fileTest\\files\\1770036631701_IMG_0755.JPG";
HashMap<String, String> result = new HashMap<>();
try {
// 使用Hutool读取文件并转换为Base64编码
byte[] fileBytes = FileUtil.readBytes(filePath);
String base64Data = Base64.encode(fileBytes);
// 根据文件扩展名确定MIME类型构造完整的data URL
String mimeType = getMimeType(filePath);
String dataUrl = "data:" + mimeType + ";base64," + base64Data;
result.put("file", dataUrl); // 完整的data URL前端可直接使用
return result;
} catch (Exception e) {
log.error("文件读取失败", e);
result.put("success", "false");
result.put("error", e.getMessage());
return result;
}
}
/**
* MIME
*/
private String getMimeType(String filePath) {
String lowerPath = filePath.toLowerCase();
if (lowerPath.endsWith(".jpg") || lowerPath.endsWith(".jpeg")) {
return "image/jpeg";
} else if (lowerPath.endsWith(".png")) {
return "image/png";
} else if (lowerPath.endsWith(".gif")) {
return "image/gif";
} else if (lowerPath.endsWith(".bmp")) {
return "image/bmp";
} else {
return "image/jpeg"; // 默认JPEG类型
}
}
@PostMapping("/saveImage")
public Map<String, Object> saveImage(@RequestParam("file") MultipartFile file) {
Map<String, Object> result = new HashMap<>();
if (file.isEmpty()) {
result.put("success", false);
result.put("message", "文件为空");
return result;
}
try {
// 获取当前操作系统的文件分隔符
String separator = File.separator;
// 使用Hutool自动创建目录
String targetDir = separator + "fileTest" + separator + "files";
FileUtil.mkdir(targetDir);
// 生成唯一文件名
String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
String filePath = targetDir + separator + fileName;
// 使用Hutool保存文件
FileUtil.writeBytes(file.getBytes(), filePath);
result.put("success", true);
result.put("message", "文件上传成功");
result.put("filePath", filePath);
result.put("fileName", fileName);
} catch (IOException e) {
result.put("success", false);
result.put("message", "文件上传失败: " + e.getMessage());
}
return result;
}
@PostMapping("/getModelData")
public ApiResult<DataModelDTO> getModelData(@RequestBody DataModelQue que) {
return dataModelService.getModelData(que);
}
/**
*
*
* @param dataModelDTO
* @return
*/
@PostMapping("/saveOrUpdate/modelData")
public ApiResult saveOrUpdateModelData(
@RequestBody DataModelDTO dataModelDTO,
HttpServletRequest request,
HttpServletResponse response) {
return dataModelService.saveOrUpdateModelData(dataModelDTO, request, response);
}
@GetMapping("/test")
public ApiResult test() {
return ApiResult.success(dataModelService.getList());
}
}

@ -0,0 +1,63 @@
package com.sz.admin.monitor.controller;
import com.sz.admin.monitor.pojo.dto.file.FileEntityDTO;
import com.sz.admin.monitor.pojo.dto.file.FileStorageDTO;
import com.sz.admin.monitor.pojo.que.file.FileStorageQue;
import com.sz.admin.monitor.service.impl.FileServiceImpl;
import com.sz.core.common.entity.ApiResult;
import com.sz.core.common.entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* @author xq
* @description:
* @date 2026/2/2 22:31
*/
@RestController
@RequestMapping("/fileStorage")
public class FileController {
@Autowired
private FileServiceImpl fileService;
@GetMapping("/deleteFileById")
public ApiResult<String> deleteFileById(@RequestParam("id") String id){
return fileService.deleteFileById(id);
}
@PostMapping("/editFileNameById")
public ApiResult<String> editFileNameById(@RequestBody FileEntityDTO dto){
return fileService.editFileNameById(dto);
}
@PostMapping("/file/list")
public ApiResult<PageResult<FileEntityDTO>> getFileObjectList(@RequestBody FileStorageQue que){
return fileService.getFileObjectList(que);
}
@GetMapping("/getPreviewFile/{id}")
public ResponseEntity<byte[]> getPreviewFile(@PathVariable String id){
return fileService.getPreviewFile(id);
}
@GetMapping("/getFile")
public ApiResult<FileStorageDTO> getFile(@RequestParam("id") String id) {
return fileService.getFile(id);
}
@PostMapping("/saveFile")
public ApiResult<FileStorageDTO> saveFile(@RequestParam("file") MultipartFile file) {
return fileService.saveFile(file);
}
@GetMapping("/test")
public void test01(){
fileService.test01();
}
}

@ -0,0 +1,8 @@
package com.sz.admin.monitor.mapper;
import com.mybatisflex.core.BaseMapper;
import com.sz.admin.monitor.pojo.po.FileStorageDO;
public interface FileStorageMapper extends BaseMapper<FileStorageDO> {
}

@ -0,0 +1,38 @@
package com.sz.admin.monitor.pojo.dto.file;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xq
* @description:
* @date 2026/2/3 14:27
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FileEntityDTO {
/**
* id
*/
private String id;
/**
*
*/
private String fileName;
/**
*
*/
private Long addTime;
/**
* path
*/
private String filePath;
}

@ -0,0 +1,61 @@
package com.sz.admin.monitor.pojo.dto.file;
import cn.hutool.core.bean.BeanUtil;
import com.sz.admin.monitor.pojo.po.FileStorageDO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* @author xq
* @description:
* @date 2026/2/2 22:18
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FileStorageDTO {
/**
* id
*/
private String id;
/**
*
*/
private String fileUrl;
/**
*
*/
private String fileSize;
/**
*
*/
private String fileName;
/**
*
*/
private String fileSuffix;
/**
* base64
*/
private String base64Data;
/**
*
*/
private Date addTime;
public static FileStorageDO dtoConvertDO(FileStorageDTO dto) {
return BeanUtil.copyProperties(dto, FileStorageDO.class);
}
}

@ -0,0 +1,69 @@
package com.sz.admin.monitor.pojo.po;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* @author xq
* @description:
* @date 2026/2/2 22:18
*/
@Table("file_storage")
@Schema(description = "文件存储数据对象")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FileStorageDO {
/**
* id
*/
@Id(keyType = KeyType.Generator, value = "uuid")
@Schema(description = "主键ID")
private String id;
/**
*
*/
@Schema(description = "文件路径")
private String fileUrl;
/**
*
*/
@Schema(description = "文件大小")
private String fileSize;
/**
*
*/
@Schema(description = "文件名称")
private String fileName;
/**
*
*/
@Schema(description = "文件后缀")
private String fileSuffix;
/**
*
*/
@Schema(description = "添加时间")
private Date addTime;
public static final String ID="id";
public static final String FILE_URL="file_url";
public static final String FILE_SIZE="file_size";
public static final String FILE_NAME="file_name";
public static final String FILE_SUFFIX="file_suffix";
public static final String ADD_TIME="add_time";
}

@ -0,0 +1,36 @@
package com.sz.admin.monitor.pojo.que;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author xq
* @description:
* @date 2026/2/3 14:21
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BasePage<T> {
private List<T> list;
/**
*
*/
private long total;
/**
*
*/
private long size;
/**
*
*/
private long current;
/**
*
*/
private long pages;
}

@ -0,0 +1,38 @@
package com.sz.admin.monitor.pojo.que;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xq
* @description:
* @date 2026/2/3 13:36
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BaseQue {
/**
*
*/
private Integer pageNum;
/**
*
*/
private Integer pageSize;
/**
*
* @param base
*/
// public static <T> Page<T> init(BaseQue base,Class<T> cla){
// if(ObjectUtil.isEmpty(base))
// return null;
// base.setPageNum(ObjectUtil.isNotEmpty(base.getPageNum())?base.getPageNum():0);
// base.setPageSize(ObjectUtil.isNotEmpty(base.getPageSize())?base.getPageSize():10);
// return new Page<>(base.getPageNum(), base.getPageSize());
// }
}

@ -0,0 +1,44 @@
package com.sz.admin.monitor.pojo.que.file;
import com.sz.admin.monitor.pojo.que.BaseQue;
import com.sz.core.common.entity.PageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* @author xq
* @description:
* @date 2026/2/3 13:35
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Schema(description = "文件查询Que")
public class FileStorageQue extends PageQuery {
/**
* id
*/
@Schema(description = "id")
private String id;
/**
*
*/
@Schema(description = "文件名称")
private String fileName;
/**
*
*/
@Schema(description = "开始时间")
private Long startTime;
/**
*
*/
@Schema(description = "结束时间")
private Long endTime;
}

@ -0,0 +1,13 @@
package com.sz.admin.monitor.service;
import com.mybatisflex.core.service.IService;
import com.sz.admin.monitor.pojo.po.FileStorageDO;
/**
* @author xq
* @description:
* @date 2026/2/2 22:18
*/
public interface FileStorageService extends IService<FileStorageDO> {
}

@ -7,7 +7,6 @@ import com.sz.admin.monitor.mapper.CameraMapper;
import com.sz.admin.monitor.mapper.CameraSnapshotMapper; import com.sz.admin.monitor.mapper.CameraSnapshotMapper;
import com.sz.admin.monitor.pojo.po.Camera; import com.sz.admin.monitor.pojo.po.Camera;
import com.sz.admin.monitor.pojo.po.CameraSnapshot; import com.sz.admin.monitor.pojo.po.CameraSnapshot;
import com.sz.admin.monitor.pojo.po.table.CameraSnapshotTableDef;
import com.sz.admin.monitor.pojo.vo.camerasnapshot.CameraSnapshotVO; import com.sz.admin.monitor.pojo.vo.camerasnapshot.CameraSnapshotVO;
import com.sz.admin.monitor.sdk.ManageNVR; import com.sz.admin.monitor.sdk.ManageNVR;
import com.sz.admin.monitor.service.CameraService; import com.sz.admin.monitor.service.CameraService;

@ -0,0 +1,267 @@
package com.sz.admin.monitor.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.sz.admin.monitor.pojo.dto.dataModel.CanvasCfgDTO;
import com.sz.admin.monitor.pojo.dto.dataModel.DataModelDTO;
import com.sz.admin.monitor.pojo.dto.dataModel.GridCfgDTO;
import com.sz.admin.monitor.pojo.dto.dataModel.ModelContentDTO;
import com.sz.admin.monitor.pojo.po.CanvasCfgDO;
import com.sz.admin.monitor.pojo.po.GridCfgDO;
import com.sz.admin.monitor.pojo.po.ModelContentDO;
import com.sz.admin.monitor.pojo.po.UserModelContentDO;
import com.sz.admin.monitor.pojo.que.dataModel.DataModelQue;
import com.sz.admin.monitor.service.CanvasCfgService;
import com.sz.admin.monitor.service.GridCfgService;
import com.sz.admin.monitor.service.ModelContentService;
import com.sz.admin.monitor.service.UserModelContentService;
import com.sz.core.common.entity.ApiResult;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author xq
* @description:
* @date 2026/1/29 10:51
*/
@Service
public class DataModelServiceImpl {
@Autowired
private CanvasCfgService canvasCfgService; // 画板
@Autowired
private GridCfgService gridCfgService; // 网格
@Autowired
private ModelContentService modelContentService; //模型
@Autowired
private UserModelContentService userModelContentService; //用户模型中间表
private static final String userId = "1";
public ApiResult<DataModelDTO> getModelData(DataModelQue que) {
if (StrUtil.isEmpty(que.getUserId()))
que.setUserId(userId);
QueryWrapper queryWrapper = QueryWrapper.create()
.from(CanvasCfgDO.class)
.where(CanvasCfgDO.USER_ID, que.getUserId())
.limit(1);
// 获取画板数据
CanvasCfgDO canvasCfgDO = canvasCfgService.getOne(queryWrapper);
// CanvasCfgDO canvasCfgDO = canvasCfgService.getOne(new QueryWrapper<CanvasCfgDO>()
// .eq(CanvasCfgDO.USER_ID, que.getUserId())
// .last("limit 1")
// );
if (ObjectUtil.isEmpty(canvasCfgDO)) {
canvasCfgDO = initCanvasCfg();
canvasCfgService.saveOrUpdate(canvasCfgDO);
}
// 获取网格数据
GridCfgDO gridCfgDO = gridCfgService.getOne(QueryWrapper.create()
.from(GridCfgDO.class)
.where(GridCfgDO.USER_ID, que.getUserId())
.limit(1)
);
// GridCfgDO gridCfgDO = gridCfgService.getOne(new QueryWrapper<GridCfgDO>()
// .eq(GridCfgDO.USER_ID, userId)
// .last("limit 1")
// );
if (ObjectUtil.isEmpty(gridCfgDO)) {
gridCfgDO = initGridCfg();
gridCfgService.saveOrUpdate(gridCfgDO);
}
//中间表
List<UserModelContentDO> userModelList = userModelContentService.list(QueryWrapper.create()
.from(UserModelContentDO.class)
.where(UserModelContentDO.USER_ID, userId)
.limit(1)
);
// List<UserModelContentDO> userModelList = userModelContentService.list(new QueryWrapper<UserModelContentDO>()
// .eq(UserModelContentDO.USER_ID, userId)
// .eq(UserModelContentDO.MENU_TYPE, que.getMenuType())
// );
ArrayList<ModelContentDTO> objects = new ArrayList<>();
if (CollectionUtil.isEmpty(userModelList)) {
DataModelDTO build = DataModelDTO.builder()
.canvasCfg(CanvasCfgDO.doConvertDTO(canvasCfgDO))
.gridCfg(GridCfgDO.doConvertDTO(gridCfgDO))
.json(objects)
.build();
return ApiResult.success(build);
}
List<String> collect = userModelList.stream()
.map(item -> item.getModelContentId())
.collect(Collectors.toList());
List<ModelContentDO> modelContentDOS = modelContentService.listByIds(collect);
for (ModelContentDO modelContentDO : modelContentDOS) {
objects.add(ModelContentDO.doConvertDTO(modelContentDO));
}
DataModelDTO build = DataModelDTO.builder()
.canvasCfg(CanvasCfgDO.doConvertDTO(canvasCfgDO))
.gridCfg(GridCfgDO.doConvertDTO(gridCfgDO))
.json(objects)
.build();
return ApiResult.success(build);
}
/**
*
*
* @return
*/
public GridCfgDO initGridCfg() {
return GridCfgDO.builder()
.userId(userId)
.enabled(true)
.align(true)
.size(10)
.build();
}
/**
*
*
* @return
*/
public CanvasCfgDO initCanvasCfg() {
return CanvasCfgDO.builder()
.width(1920)
.userId(userId)
.height(1080)
.scale(1D)
.color("")
.img("")
.guide(true)
.adsorp(true)
.adsorpDiff(5D)
.transformOrigin("{\"x\":0,\"y\":0}")
.dragOffset("{\"x\":0,\"y\":0}")
.build();
}
/**
*
*
* @param dataModelDTO
* @param request
* @param response
* @return
*/
@Transactional
public ApiResult saveOrUpdateModelData(DataModelDTO dataModelDTO, HttpServletRequest request, HttpServletResponse response) {
if (ObjectUtil.isEmpty(dataModelDTO))
throw new IllegalArgumentException("传值错误");
CanvasCfgDTO canvasCfg = dataModelDTO.getCanvasCfg();
GridCfgDTO gridCfg = dataModelDTO.getGridCfg();
List<ModelContentDTO> json = dataModelDTO.getJson();
//保存、更新面板
canvasCfg.setUserId(userId);
canvasCfgService.saveOrUpdateCanvas(canvasCfg);
//保存、更新网格
gridCfg.setUserId(userId);
gridCfgService.saveOrUpdateGrid(gridCfg);
//保存数据模型
HashMap<String, List<String>> map = modelContentService.saveOrUpdateModel(json, dataModelDTO.getMenuType());
//获取中间表
List<UserModelContentDO> list = userModelContentService.list(QueryWrapper.create()
.from(UserModelContentDO.class)
.where(UserModelContentDO.USER_ID, userId) //先写死
.eq(UserModelContentDO.MENU_TYPE, dataModelDTO.getMenuType())
);
// List<UserModelContentDO> list = userModelContentService.list(new QueryWrapper<UserModelContentDO>()
// .eq(UserModelContentDO.USER_ID, userId) //先写死
// .eq(UserModelContentDO.MENU_TYPE, dataModelDTO.getMenuType())
// );
if (CollectionUtil.isEmpty(map)) {
List<String> modelIds = list.stream()
.map(item -> item.getModelContentId())
.collect(Collectors.toList());
modelContentService.removeByIds(modelIds);
userModelContentService.remove(QueryWrapper.create()
.from(UserModelContentDO.class)
.where(UserModelContentDO.USER_ID, userId)
.eq(UserModelContentDO.MENU_TYPE, dataModelDTO.getMenuType()));
// userModelContentService.remove(new QueryWrapper<UserModelContentDO>()
// .eq(UserModelContentDO.USER_ID, userId) //先写死
// .eq(UserModelContentDO.MENU_TYPE, dataModelDTO.getMenuType()));
return ApiResult.success();
}
//增加的id集合
List<String> addIdModels = map.get("addIdModels");
//跟新的id集合
List<String> updateIdModels = map.get("updateIdModels");
if (CollectionUtil.isEmpty(addIdModels))
return ApiResult.success();
//中间表没有数据,直接添加
if (CollectionUtil.isEmpty(list)) {
List<String> allModelIds = Stream.concat(addIdModels.stream(), updateIdModels.stream())
.distinct()
.collect(Collectors.toList());
for (String modelId : allModelIds) {
UserModelContentDO build = UserModelContentDO.builder()
.userId(userId)
.menuType(dataModelDTO.getMenuType())
.modelContentId(modelId)
.build();
userModelContentService.save(build);
}
return ApiResult.success();
} else { //中间表有数据
List<String> collect = list.stream().map(UserModelContentDO::getModelContentId).collect(Collectors.toList());
collect.removeAll(updateIdModels);
modelContentService.removeByIds(collect);
List<String> targetCollect = list.stream()
.filter(item -> collect.contains(item.getModelContentId()))
.map(UserModelContentDO::getId)
.collect(Collectors.toList());
userModelContentService.removeByIds(targetCollect);
for (String addIdModel : addIdModels) {
UserModelContentDO build = UserModelContentDO.builder()
.userId(userId)
.menuType(dataModelDTO.getMenuType())
.modelContentId(addIdModel)
.build();
userModelContentService.save(build);
}
}
return ApiResult.success();
}
public List<UserModelContentDO> getList() {
return null;
}
}

@ -0,0 +1,271 @@
package com.sz.admin.monitor.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.sz.admin.monitor.pojo.dto.camera.CameraListDTO;
import com.sz.admin.monitor.pojo.dto.file.FileEntityDTO;
import com.sz.admin.monitor.pojo.dto.file.FileStorageDTO;
import com.sz.admin.monitor.pojo.po.Camera;
import com.sz.admin.monitor.pojo.po.FileStorageDO;
import com.sz.admin.monitor.pojo.po.Nvr;
import com.sz.admin.monitor.pojo.que.file.FileStorageQue;
import com.sz.admin.monitor.pojo.vo.camera.CameraVO;
import com.sz.admin.monitor.service.FileStorageService;
import com.sz.core.common.entity.ApiResult;
import com.sz.core.common.entity.PageResult;
import com.sz.core.datascope.SimpleDataScopeHelper;
import com.sz.core.util.PageUtils;
import com.sz.core.util.Utils;
import com.sz.platform.enums.AdminResponseEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.*;
/**
* @author xq
* @description:
* @date 2026/3/13 15:28
*/
@Service
public class FileServiceImpl {
@Autowired
private FileStorageService fileStorageService;
@Value("${file.object.storage.targetDir:/defaultFile}")
private String targetDir;
// 获取当前操作系统的文件分隔符
private static String separator = "/";
//获取文件流路径(请求路径)
private static String path = "/fileStorage/getPreviewFile/";
/**
*
*
* @param id
* @return
*/
public ApiResult<String> deleteFileById(String id) {
if (ObjectUtil.isEmpty(id))
return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);
FileStorageDO fileStorageDO = fileStorageService.getById(id);
if (ObjectUtil.isEmpty(fileStorageDO))
return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);
fileStorageService.removeById(id);
return ApiResult.success("删除成功");
}
/**
*
*
* @param dto
* @return
*/
public ApiResult<String> editFileNameById(FileEntityDTO dto) {
if (ObjectUtil.isEmpty(dto.getId()))
return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);
FileStorageDO fileStorageDO = fileStorageService.getById(dto.getId());
if (ObjectUtil.isEmpty(fileStorageDO))
return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);
fileStorageDO.setFileName(dto.getFileName());
fileStorageService.saveOrUpdate(fileStorageDO);
return ApiResult.success("修改成功");
}
/**
*
*
* @param que
* @return
*/
public ApiResult<PageResult<FileEntityDTO>> getFileObjectList(FileStorageQue que) {
SimpleDataScopeHelper.start(FileStorageDO.class); // 指定要追加条件的表PO实体
QueryWrapper queryWrapper = QueryWrapper.create()
.from(FileStorageDO.class)
.eq(FileStorageDO.ID, que.getId(), ObjectUtil.isNotEmpty(que.getId()))
.like(FileStorageDO.FILE_NAME, que.getFileName(), ObjectUtil.isNotEmpty(que.getFileName()))
.between(
FileStorageDO.ADD_TIME,
que.getStartTime(), que.getEndTime(),
ObjectUtil.isNotEmpty(que.getStartTime()) && ObjectUtil.isNotEmpty(que.getEndTime())
)
.orderBy(FileStorageDO.ADD_TIME, false);
Page<FileStorageDO> page = fileStorageService.pageAs(PageUtils.getPage(que), queryWrapper, FileStorageDO.class);// 调试sql
if (ObjectUtil.isEmpty(page) || page.getRecords().isEmpty())
return ApiResult.success(new PageResult<>(que.getPage().longValue(), que.getLimit().longValue(), 0, 0, new ArrayList<>()));
List<FileEntityDTO> fileEntityDTOS = new ArrayList<>();
for (FileStorageDO record : page.getRecords()) {
FileEntityDTO fileEntityDTO = BeanUtil.copyProperties(record, FileEntityDTO.class);
fileEntityDTO.setFilePath(path + record.getId());
fileEntityDTOS.add(fileEntityDTO);
}
return ApiResult.success(new PageResult<>(
page.getPageNumber(),
page.getPageSize(),
page.getTotalPage(),
page.getTotalRow(),
fileEntityDTOS));
}
// public ApiResult<PageResult<FileEntityDTO>> getFileObjectList(FileStorageQue que) {
// Page<FileStorageDO> doPage = BaseQue.init(que, FileStorageDO.class);
// Page<FileStorageDO> page = fileStorageService.page(doPage, new QueryWrapper<FileStorageDO>()
// .eq(ObjectUtil.isNotEmpty(que.getId()), FileStorageDO.ID, que.getId())
// .like(ObjectUtil.isNotEmpty(que.getFileName()), FileStorageDO.FILE_NAME, que.getFileName())
// .between(
// ObjectUtil.isNotEmpty(que.getStartTime()) && ObjectUtil.isNotEmpty(que.getEndTime())
// , FileStorageDO.ADD_TIME
// , que.getStartTime(), que.getEndTime())
// .orderByDesc(FileStorageDO.ADD_TIME)
// );
// if(ObjectUtil.isEmpty(page) || page.getRecords().isEmpty())
// return ResponseBody.ok();
//
// BasePage<FileEntityDTO> basePage = new BasePage();
// basePage.setTotal(page.getTotal());
// basePage.setSize(page.getSize());
// basePage.setCurrent(page.getCurrent());
// basePage.setPages(page.getPages());
//
// List<FileEntityDTO> fileEntityDTOS = new ArrayList<>();
// for (FileStorageDO record : page.getRecords()) {
// FileEntityDTO fileEntityDTO = BeanUtil.copyProperties(record, FileEntityDTO.class);
// fileEntityDTO.setFilePath(path+record.getId());
// fileEntityDTOS.add(fileEntityDTO);
// }
// basePage.setList(fileEntityDTOS);
// return ApiResult.success(basePage);
// }
/**
*
*
* @param id
* @return
*/
public ResponseEntity<byte[]> getPreviewFile(String id) {
FileStorageDO fileStorageDO = fileStorageService.getById(id);
String filePath = fileStorageDO.getFileUrl();
// 使用Hutool读取文件并转换为Base64编码
byte[] imageBytes = FileUtil.readBytes(filePath);
String mimeType = getMimeType(filePath);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType(mimeType));
headers.setContentLength(imageBytes.length);
return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
}
/**
*
*
* @param id
* @return
*/
public ApiResult<FileStorageDTO> getFile(String id) {
FileStorageDO fileStorageDO = fileStorageService.getById(id);
if (ObjectUtil.isEmpty(fileStorageDO))
return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);
String filePath = fileStorageDO.getFileUrl();
// 使用Hutool读取文件并转换为Base64编码
byte[] fileBytes = FileUtil.readBytes(filePath);
String base64Data = Base64.encode(fileBytes);
String mimeType = getMimeType(filePath);
String dataUrl = "data:" + mimeType + ";base64," + base64Data;
FileStorageDTO fileStorageDTO = BeanUtil.copyProperties(fileStorageDO, FileStorageDTO.class);
fileStorageDTO.setBase64Data(dataUrl);
return ApiResult.success(fileStorageDTO);
}
/**
*
*
* @param file
* @return
*/
public ApiResult<FileStorageDTO> saveFile(MultipartFile file) {
Map<String, Object> result = new HashMap<>();
if (file.isEmpty())
return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);
String path = targetDir;
try {
FileUtil.mkdir(path);
// 生成唯一文件名
String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
String filePath = path + separator + fileName;
// 使用Hutool保存文件
FileUtil.writeBytes(file.getBytes(), filePath);
String mimeType = getMimeType(filePath);
FileStorageDTO fileDTO = FileStorageDTO.builder()
.fileUrl(filePath)
.fileSize(ObjectUtil.isNotEmpty(file.getSize()) ? String.valueOf(file.getSize()) : "0")
.fileName(file.getOriginalFilename())
.fileSuffix(mimeType)
.addTime(new Date())
.build();
FileStorageDO fileStorageDO = FileStorageDTO.dtoConvertDO(fileDTO);
fileStorageService.saveOrUpdate(fileStorageDO);
fileDTO.setId(fileStorageDO.getId());
String base64Data = Base64.encode(file.getBytes());
String dataUrl = "data:" + mimeType + ";base64," + base64Data;
fileDTO.setBase64Data(dataUrl);
return ApiResult.success(fileDTO);
} catch (IOException e) {
result.put("success", false);
result.put("message", "文件上传失败: " + e.getMessage());
return ApiResult.error(null);
}
}
public void test01() {
fileStorageService.list().forEach(System.out::println);
}
/**
* MIME
*/
private String getMimeType(String filePath) {
String lowerPath = filePath.toLowerCase();
if (lowerPath.endsWith(".jpg") || lowerPath.endsWith(".jpeg")) {
return "image/jpeg";
} else if (lowerPath.endsWith(".png")) {
return "image/png";
} else if (lowerPath.endsWith(".gif")) {
return "image/gif";
} else if (lowerPath.endsWith(".bmp")) {
return "image/bmp";
} else {
return "image/jpeg"; // 默认JPEG类型
}
}
}

@ -0,0 +1,17 @@
package com.sz.admin.monitor.service.impl;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.sz.admin.monitor.mapper.FileStorageMapper;
import com.sz.admin.monitor.pojo.po.FileStorageDO;
import com.sz.admin.monitor.service.FileStorageService;
import org.springframework.stereotype.Service;
/**
* @author xq
* @description:
* @date 2026/2/2 22:18
*/
@Service
public class FileStorageServiceImpl extends ServiceImpl<FileStorageMapper, FileStorageDO> implements FileStorageService {
}

@ -74,4 +74,10 @@ management:
include: "health,info" include: "health,info"
endpoint: endpoint:
health: health:
show-details: "never" show-details: "never"
file:
object:
storage:
targetDir: D:/work/images

@ -9,10 +9,10 @@ create table user_model_content
create table model_content create table model_content
( (
id varchar(32) not null comment '模型id' id varchar(32) not null comment '模型id'
primary key, primary key,
title varchar(32) null comment '模型名称', title varchar(32) null comment '模型名称',
type varchar(32) null comment '模型类型', type varchar(32) null comment '模型类型',
binfo varchar(128) null comment '位置json', binfo varchar(128) null comment '位置json',
resize tinyint(1) null comment '调整大小(bool)', resize tinyint(1) null comment '调整大小(bool)',
rotate tinyint(1) null comment '锁定(bool)', rotate tinyint(1) null comment '锁定(bool)',
@ -22,38 +22,49 @@ create table model_content
tag varchar(128) null comment 'vue组件名称', tag varchar(128) null comment 'vue组件名称',
common_animations varchar(128) null comment '动画(json)', common_animations varchar(128) null comment '动画(json)',
events varchar(128) null comment '事件' events varchar(128) null comment '事件'
) comment '模型内容'; ) comment '模型内容';
create table canvas_cfg create table canvas_cfg
( (
id varchar(32) not null comment '面板id' primary key, id varchar(32) not null comment '面板id' primary key,
user_id varchar(32) null comment '用户id', user_id varchar(32) null comment '用户id',
width int null comment '宽度', width int null comment '宽度',
height int null comment '高度', height int null comment '高度',
scale int null comment '比例', scale int null comment '比例',
color varchar(32) null comment '颜色', color varchar(32) null comment '颜色',
img varchar(32) null comment '图片', img varchar(32) null comment '图片',
guide varchar(32) null, guide varchar(32) null,
adsorp boolean null comment '吸附(bool)', adsorp boolean null comment '吸附(bool)',
adsorp_diff int null comment '吸附差分', adsorp_diff int null comment '吸附差分',
transform_origin text null comment '原点(json)', transform_origin text null comment '原点(json)',
drag_offset text null comment '拖拽(json)' drag_offset text null comment '拖拽(json)'
) ) comment '面板';
comment '面板';
create table grid_cfg create table grid_cfg
( (
id varchar(32) not null id varchar(32) not null
primary key, primary key,
user_id varchar(32) null comment '用户id', user_id varchar(32) null comment '用户id',
enabled boolean null comment '网格(bool)', enabled boolean null comment '网格(bool)',
align boolean null comment '对齐(bool)', align boolean null comment '对齐(bool)',
size int null comment '大小' size int null comment '大小'
) comment '网格';
-- auto-generated definition
create table file_storage
(
id varchar(32) not null
primary key,
file_url varchar(356) null comment '文件路径',
file_size varchar(32) null comment '文件大小',
file_name varchar(32) null comment '文件名称',
file_suffix varchar(128) null comment '文件后缀',
add_time date null comment '添加时间'
) )
comment '网格'; comment '文件存储';

Loading…
Cancel
Save