人脸识别与大模型问答
This commit is contained in:
parent
b56b55ad3d
commit
96d23b943e
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.bonus.ai.config;
|
||||||
|
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class CustomMultipartFile implements MultipartFile {
|
||||||
|
private final File file;
|
||||||
|
|
||||||
|
public CustomMultipartFile(File file) {
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return file.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOriginalFilename() {
|
||||||
|
return file.getName(); // 或根据需要返回不同的名称
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContentType() {
|
||||||
|
// 根据文件扩展名返回内容类型
|
||||||
|
String name = file.getName();
|
||||||
|
if (name.endsWith(".jpg") || name.endsWith(".jpeg")) {
|
||||||
|
return "image/jpeg";
|
||||||
|
} else if (name.endsWith(".png")) {
|
||||||
|
return "image/png";
|
||||||
|
}
|
||||||
|
return null; // 或者抛出异常
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return file.length() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSize() {
|
||||||
|
return file.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBytes() throws IOException {
|
||||||
|
try (FileInputStream fis = new FileInputStream(file)) {
|
||||||
|
byte[] bytes = new byte[(int) file.length()];
|
||||||
|
fis.read(bytes);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return new FileInputStream(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transferTo(File dest) throws IOException, IllegalStateException {
|
||||||
|
// 实现文件传输的逻辑
|
||||||
|
try (FileInputStream fis = new FileInputStream(file);
|
||||||
|
FileOutputStream fos = new FileOutputStream(dest)) {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int length;
|
||||||
|
while ((length = fis.read(buffer)) > 0) {
|
||||||
|
fos.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,20 +1,34 @@
|
||||||
package com.bonus.ai.controller;
|
package com.bonus.ai.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.IoUtil;
|
||||||
|
import com.bonus.ai.config.CustomMultipartFile;
|
||||||
import com.bonus.ai.domain.*;
|
import com.bonus.ai.domain.*;
|
||||||
import com.bonus.ai.service.DataSetService;
|
import com.bonus.ai.service.DataSetService;
|
||||||
|
import com.bonus.common.core.utils.StringUtils;
|
||||||
import com.bonus.common.core.web.controller.BaseController;
|
import com.bonus.common.core.web.controller.BaseController;
|
||||||
import com.bonus.common.core.web.domain.AjaxResult;
|
import com.bonus.common.core.web.domain.AjaxResult;
|
||||||
import com.bonus.common.core.web.page.TableDataInfo;
|
import com.bonus.common.core.web.page.TableDataInfo;
|
||||||
import com.bonus.system.api.RemoteFileService;
|
import com.bonus.system.api.RemoteFileService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.apache.poi.openxml4j.opc.internal.FileHelper;
|
||||||
|
import org.aspectj.util.FileUtil;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.commons.CommonsMultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author bonus
|
* @author bonus
|
||||||
|
|
@ -357,7 +371,7 @@ public class DataSetController extends BaseController {
|
||||||
* @return 影响的行数
|
* @return 影响的行数
|
||||||
*/
|
*/
|
||||||
@PostMapping("/insertModel")
|
@PostMapping("/insertModel")
|
||||||
public AjaxResult insertModel(@RequestBody AiModelEntity entity) {
|
public AjaxResult insertModel(AiModelEntity entity) {
|
||||||
return dataSetService.insertModel(entity);
|
return dataSetService.insertModel(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -368,7 +382,7 @@ public class DataSetController extends BaseController {
|
||||||
* @return 影响的行数
|
* @return 影响的行数
|
||||||
*/
|
*/
|
||||||
@PostMapping("/updateModel")
|
@PostMapping("/updateModel")
|
||||||
public AjaxResult updateModel(@RequestBody AiModelEntity entity) {
|
public AjaxResult updateModel(AiModelEntity entity) {
|
||||||
return dataSetService.updateModel(entity);
|
return dataSetService.updateModel(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -474,4 +488,117 @@ public class DataSetController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/uploadZipFiles")
|
||||||
|
public AjaxResult uploadZipFiles(@RequestParam("files") MultipartFile[] files, @RequestParam("datasetId") Long datasetId) {
|
||||||
|
List<MultipartFile> multipartFiles = new ArrayList<>();
|
||||||
|
Path tempDir;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 创建一个临时目录用于存放解压后的文件
|
||||||
|
tempDir = Files.createTempDirectory("uploads");
|
||||||
|
|
||||||
|
// 遍历上传的压缩文件
|
||||||
|
for (MultipartFile file : files) {
|
||||||
|
processZipFile(file, multipartFiles, tempDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理完成后删除临时文件夹
|
||||||
|
deleteTempDirectory(tempDir);
|
||||||
|
|
||||||
|
// 将 List 转换为数组,方便后续上传
|
||||||
|
MultipartFile[] resultFiles = multipartFiles.toArray(new MultipartFile[0]);
|
||||||
|
return handleFileUpload(resultFiles, datasetId);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// 如果创建临时目录失败,返回错误信息
|
||||||
|
return AjaxResult.error("Failed to create temporary directory: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理每个压缩文件,解压并将图片文件添加到列表中
|
||||||
|
private void processZipFile(MultipartFile file, List<MultipartFile> multipartFiles, Path tempDir) {
|
||||||
|
try (ZipInputStream zis = new ZipInputStream(file.getInputStream())) {
|
||||||
|
ZipEntry entry;
|
||||||
|
// 逐个读取压缩文件中的条目
|
||||||
|
while ((entry = zis.getNextEntry()) != null) {
|
||||||
|
// 如果条目不是目录且是图片文件
|
||||||
|
if (!entry.isDirectory() && isImageFile(entry.getName())) {
|
||||||
|
// 创建解压后的图片文件
|
||||||
|
File imgFile = new File(tempDir.toFile(), entry.getName());
|
||||||
|
imgFile.getParentFile().mkdirs(); // 确保目录存在
|
||||||
|
// 将条目内容写入到文件
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(imgFile)) {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int length;
|
||||||
|
while ((length = zis.read(buffer)) >= 0) {
|
||||||
|
fos.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建 MultipartFile 对象并添加到列表中
|
||||||
|
MultipartFile multipartFile = new CustomMultipartFile(imgFile);
|
||||||
|
multipartFiles.add(multipartFile);
|
||||||
|
}
|
||||||
|
zis.closeEntry(); // 关闭当前条目
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// 抛出运行时异常,包含原始文件名的信息
|
||||||
|
throw new RuntimeException("Error processing file: " + file.getOriginalFilename(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理文件上传及数据库插入
|
||||||
|
private AjaxResult handleFileUpload(MultipartFile[] resultFiles, Long datasetId) {
|
||||||
|
// 调用远程服务上传文件
|
||||||
|
AjaxResult ajaxResult = remoteFileService.uploadFile(resultFiles);
|
||||||
|
if (ajaxResult.isSuccess()) {
|
||||||
|
// 上传成功,处理返回的数据
|
||||||
|
List<Map<String, String>> data = (List<Map<String, String>>) ajaxResult.get("data");
|
||||||
|
for (Map<String, String> map : data) {
|
||||||
|
// 创建数据集文件实体并插入到数据库
|
||||||
|
DataSetFileEntity entity = new DataSetFileEntity();
|
||||||
|
// 文件地址
|
||||||
|
entity.setFileAddress(map.get("url"));
|
||||||
|
// 关联的数据集 ID
|
||||||
|
entity.setDatasetId(datasetId);
|
||||||
|
// 文件名
|
||||||
|
entity.setFileName(map.get("name"));
|
||||||
|
dataSetService.insertFile(entity);
|
||||||
|
}
|
||||||
|
// 返回成功结果
|
||||||
|
return AjaxResult.success();
|
||||||
|
} else {
|
||||||
|
// 上传失败,返回错误信息
|
||||||
|
return AjaxResult.error("上传文件失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件名是否为图片文件
|
||||||
|
private boolean isImageFile(String fileName) {
|
||||||
|
String[] extensions = {".jpg", ".jpeg", ".png"};
|
||||||
|
// 遍历扩展名,检查文件名是否符合
|
||||||
|
for (String ext : extensions) {
|
||||||
|
if (fileName.toLowerCase().endsWith(ext)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false; // 不是图片文件
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除临时目录及其中的文件
|
||||||
|
private void deleteTempDirectory(Path tempDir) {
|
||||||
|
try {
|
||||||
|
// 遍历临时目录,删除所有文件和子目录
|
||||||
|
Files.walk(tempDir)
|
||||||
|
.sorted(Comparator.reverseOrder())
|
||||||
|
.forEach(path -> {
|
||||||
|
try {
|
||||||
|
Files.delete(path);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace(); // 打印错误信息
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace(); // 打印错误信息
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import com.bonus.common.core.web.domain.BaseEntity;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
@ -13,7 +14,7 @@ import java.util.Date;
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class AiModelEntity extends BaseEntity {
|
public class AiModelEntity {
|
||||||
/**
|
/**
|
||||||
* 模型唯一id
|
* 模型唯一id
|
||||||
*/
|
*/
|
||||||
|
|
@ -26,10 +27,6 @@ public class AiModelEntity extends BaseEntity {
|
||||||
* 模型版本
|
* 模型版本
|
||||||
*/
|
*/
|
||||||
private String modelVersion;
|
private String modelVersion;
|
||||||
/**
|
|
||||||
* 分任务类型id
|
|
||||||
*/
|
|
||||||
private Long subTaskTypeId;
|
|
||||||
/**
|
/**
|
||||||
* 模型类型
|
* 模型类型
|
||||||
*/
|
*/
|
||||||
|
|
@ -57,10 +54,13 @@ public class AiModelEntity extends BaseEntity {
|
||||||
/**
|
/**
|
||||||
* 模型相对地址
|
* 模型相对地址
|
||||||
*/
|
*/
|
||||||
|
private MultipartFile[] modelFile;
|
||||||
|
|
||||||
private String modelAddress;
|
private String modelAddress;
|
||||||
/**
|
/**
|
||||||
* 使用手册相对地址
|
* 使用手册相对地址
|
||||||
*/
|
*/
|
||||||
|
private MultipartFile[] userGuideFile;
|
||||||
private String userGuide;
|
private String userGuide;
|
||||||
/**
|
/**
|
||||||
* 描述
|
* 描述
|
||||||
|
|
@ -70,4 +70,8 @@ public class AiModelEntity extends BaseEntity {
|
||||||
* 算法选择
|
* 算法选择
|
||||||
*/
|
*/
|
||||||
private String algorithm;
|
private String algorithm;
|
||||||
|
|
||||||
|
private String createBy;
|
||||||
|
|
||||||
|
private Date createTime;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,9 @@ public interface DataSetMapper {
|
||||||
* @param datasetFile 数据集文件实体
|
* @param datasetFile 数据集文件实体
|
||||||
* @return 影响的行数
|
* @return 影响的行数
|
||||||
*/
|
*/
|
||||||
int updateFile(DataSetFileEntity datasetFile);
|
int updateFile(@Param("datasetId") Long datasetId,
|
||||||
|
@Param("updateBy") String updateBy,
|
||||||
|
@Param("fileIds") Long[] fileIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据 ID 删除数据集文件(逻辑删除)
|
* 根据 ID 删除数据集文件(逻辑删除)
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,19 @@ package com.bonus.ai.service.impl;
|
||||||
import com.bonus.ai.domain.*;
|
import com.bonus.ai.domain.*;
|
||||||
import com.bonus.ai.mapper.DataSetMapper;
|
import com.bonus.ai.mapper.DataSetMapper;
|
||||||
import com.bonus.ai.service.DataSetService;
|
import com.bonus.ai.service.DataSetService;
|
||||||
|
import com.bonus.common.core.domain.R;
|
||||||
import com.bonus.common.core.web.domain.AjaxResult;
|
import com.bonus.common.core.web.domain.AjaxResult;
|
||||||
import com.bonus.common.security.utils.SecurityUtils;
|
import com.bonus.common.security.utils.SecurityUtils;
|
||||||
|
import com.bonus.system.api.RemoteFileService;
|
||||||
|
import com.bonus.system.api.domain.SysFile;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author bonus
|
* @author bonus
|
||||||
|
|
@ -21,6 +26,9 @@ public class DataSetServiceImpl implements DataSetService {
|
||||||
@Resource
|
@Resource
|
||||||
private DataSetMapper mapper;
|
private DataSetMapper mapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RemoteFileService remoteFileService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据数据集 ID 查询对应的数据集信息。
|
* 根据数据集 ID 查询对应的数据集信息。
|
||||||
*
|
*
|
||||||
|
|
@ -230,7 +238,7 @@ public class DataSetServiceImpl implements DataSetService {
|
||||||
@Override
|
@Override
|
||||||
public AjaxResult updateFile(DataSetFileEntity datasetFile) {
|
public AjaxResult updateFile(DataSetFileEntity datasetFile) {
|
||||||
try {
|
try {
|
||||||
int i = mapper.updateFile(datasetFile);
|
int i = mapper.updateFile(datasetFile.getDatasetId(), datasetFile.getUpdateBy(), datasetFile.getFileIds());
|
||||||
return i > 0 ? AjaxResult.success("移动成功") : AjaxResult.error("移动失败");
|
return i > 0 ? AjaxResult.success("移动成功") : AjaxResult.error("移动失败");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return AjaxResult.error("移动失败");
|
return AjaxResult.error("移动失败");
|
||||||
|
|
@ -382,6 +390,26 @@ public class DataSetServiceImpl implements DataSetService {
|
||||||
public AjaxResult insertModel(AiModelEntity entity) {
|
public AjaxResult insertModel(AiModelEntity entity) {
|
||||||
try {
|
try {
|
||||||
entity.setCreateBy(SecurityUtils.getUsername());
|
entity.setCreateBy(SecurityUtils.getUsername());
|
||||||
|
AjaxResult ajaxResult = remoteFileService.uploadFile(entity.getModelFile());
|
||||||
|
if (ajaxResult.isSuccess()) {
|
||||||
|
List<Map<String, String>> data = (List<Map<String, String>>) ajaxResult.get("data");
|
||||||
|
for (Map<String, String> map : data) {
|
||||||
|
entity.setModelAddress(map.get("url"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return AjaxResult.error("上传文件失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
AjaxResult userGuide = remoteFileService.uploadFile(entity.getUserGuideFile());
|
||||||
|
if (userGuide.isSuccess()) {
|
||||||
|
List<Map<String, String>> data = (List<Map<String, String>>) userGuide.get("data");
|
||||||
|
for (Map<String, String> map : data) {
|
||||||
|
entity.setUserGuide(map.get("url"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return AjaxResult.error("上传文件失败");
|
||||||
|
}
|
||||||
int i = mapper.insertModel(entity);
|
int i = mapper.insertModel(entity);
|
||||||
return i > 0 ? AjaxResult.success("新增成功") : AjaxResult.error("新增失败");
|
return i > 0 ? AjaxResult.success("新增成功") : AjaxResult.error("新增失败");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
@ -398,6 +426,29 @@ public class DataSetServiceImpl implements DataSetService {
|
||||||
@Override
|
@Override
|
||||||
public AjaxResult updateModel(AiModelEntity entity) {
|
public AjaxResult updateModel(AiModelEntity entity) {
|
||||||
try {
|
try {
|
||||||
|
if (entity.getModelFile().length > 0) {
|
||||||
|
AjaxResult ajaxResult = remoteFileService.uploadFile(entity.getModelFile());
|
||||||
|
if (ajaxResult.isSuccess()) {
|
||||||
|
List<Map<String, String>> data = (List<Map<String, String>>) ajaxResult.get("data");
|
||||||
|
for (Map<String, String> map : data) {
|
||||||
|
entity.setModelAddress(map.get("url"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return AjaxResult.error("上传文件失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entity.getUserGuideFile().length > 0) {
|
||||||
|
AjaxResult userGuide = remoteFileService.uploadFile(entity.getUserGuideFile());
|
||||||
|
if (userGuide.isSuccess()) {
|
||||||
|
List<Map<String, String>> data = (List<Map<String, String>>) userGuide.get("data");
|
||||||
|
for (Map<String, String> map : data) {
|
||||||
|
entity.setUserGuide(map.get("url"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return AjaxResult.error("上传文件失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
int i = mapper.updateModel(entity);
|
int i = mapper.updateModel(entity);
|
||||||
return i > 0 ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
|
return i > 0 ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue