图像模型
This commit is contained in:
111
src/main/java/com/rj/service/IImageModelService.java
Normal file
111
src/main/java/com/rj/service/IImageModelService.java
Normal file
@@ -0,0 +1,111 @@
|
||||
package com.rj.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.rj.entity.ImageModel;
|
||||
|
||||
/**
|
||||
* 图像模型服务接口
|
||||
*
|
||||
* 提供图像模型相关的业务逻辑接口,包括:
|
||||
* - 图像模型记录的增删改查操作
|
||||
* - 根据不同条件查询图像模型记录
|
||||
* - 图像模型数据的业务处理逻辑
|
||||
*
|
||||
* 继承MyBatis-Plus的IService接口,获得基础的CRUD能力,
|
||||
* 同时定义特定的业务方法。
|
||||
*
|
||||
* @author 系统生成
|
||||
* @date 2025/1/30
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface IImageModelService extends IService<ImageModel> {
|
||||
|
||||
/**
|
||||
* 保存图像模型记录
|
||||
*
|
||||
* 将图像模型数据保存到数据库中,包括完整的业务逻辑处理。
|
||||
* 该方法会进行数据验证、日志记录等操作。
|
||||
*
|
||||
* @param imageModel 图像模型记录对象,包含所有必要的字段信息
|
||||
* @return 是否保存成功,true表示保存成功,false表示保存失败
|
||||
*/
|
||||
boolean saveImageModel(ImageModel imageModel);
|
||||
|
||||
/**
|
||||
* 根据UUID查询图像模型记录
|
||||
*
|
||||
* 通过唯一标识符查询对应的图像模型记录。
|
||||
* UUID是主键,查询结果唯一。
|
||||
*
|
||||
* @param uuid 唯一标识符,对应数据库主键
|
||||
* @return 图像模型记录,如果未找到则返回null
|
||||
*/
|
||||
ImageModel getByUuid(String uuid);
|
||||
|
||||
/**
|
||||
* 根据请求ID查询图像模型记录
|
||||
*
|
||||
* 通过请求ID查询对应的图像模型记录。
|
||||
* 一个请求ID可能对应多条记录,此方法返回最新的一条。
|
||||
*
|
||||
* @param requestId 请求ID,用于追踪处理请求
|
||||
* @return 图像模型记录,如果未找到则返回null
|
||||
*/
|
||||
ImageModel getByRequestId(String requestId);
|
||||
|
||||
/**
|
||||
* 根据任务ID查询图像模型记录
|
||||
*
|
||||
* 通过任务ID查询对应的图像模型记录。
|
||||
* 一个任务ID可能对应多条记录,此方法返回最新的一条。
|
||||
*
|
||||
* @param taskId 任务ID,用于追踪异步处理任务
|
||||
* @return 图像模型记录,如果未找到则返回null
|
||||
*/
|
||||
ImageModel getByTaskId(String taskId);
|
||||
|
||||
/**
|
||||
* 根据所属人电话查询图像模型记录
|
||||
*
|
||||
* 通过所属人电话查询对应的图像模型记录。
|
||||
* 一个电话号码可能对应多条记录,此方法返回最新的一条。
|
||||
*
|
||||
* @param ownerPhone 所属人电话,用于查询特定用户的记录
|
||||
* @return 图像模型记录,如果未找到则返回null
|
||||
*/
|
||||
ImageModel getByOwnerPhone(String ownerPhone);
|
||||
|
||||
/**
|
||||
* 去除图像中的中英文字符或常见水印
|
||||
*
|
||||
* 处理图像去除水印的业务逻辑,包括:
|
||||
* - 图像预处理和参数设置
|
||||
* - 调用AI模型进行水印去除
|
||||
* - 结果处理和URL生成
|
||||
* - 记录保存和状态更新
|
||||
*
|
||||
* @param imageModel 图像模型记录对象,包含处理参数和结果信息
|
||||
* @return 处理后的图像模型记录,包含结果URL等信息
|
||||
*/
|
||||
ImageModel removeWatermar(ImageModel imageModel);
|
||||
|
||||
/**
|
||||
* 上传图片素材
|
||||
*
|
||||
* 处理图片素材上传的完整业务逻辑,包括:
|
||||
* - 文件验证和格式检查
|
||||
* - 上传到MinIO存储
|
||||
* - 生成永久URL和临时URL
|
||||
* - 保存上传记录到数据库
|
||||
*
|
||||
* @param file 上传的图片文件
|
||||
* @param ownerName 所属人姓名
|
||||
* @param ownerPhone 所属人电话
|
||||
* @param imageType 图片类型
|
||||
* @return 图像模型记录,包含上传结果和URL信息
|
||||
*/
|
||||
ImageModel uploadImageMaterial(org.springframework.web.multipart.MultipartFile file,
|
||||
String ownerName, String ownerPhone, String imageType,String imageName);
|
||||
|
||||
boolean removeByUuid(String uuid);
|
||||
}
|
||||
@@ -84,6 +84,11 @@ public interface ICustomerProfileAnalysisService extends IService<CustomerProfil
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -119,6 +119,11 @@ public class CustomerProfileAnalysisServiceImpl extends ServiceImpl<CustomerProf
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
476
src/main/java/com/rj/service/impl/ImageModelServiceImpl.java
Normal file
476
src/main/java/com/rj/service/impl/ImageModelServiceImpl.java
Normal file
@@ -0,0 +1,476 @@
|
||||
package com.rj.service.impl;
|
||||
|
||||
import ai.djl.util.JsonUtils;
|
||||
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
|
||||
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisParam;
|
||||
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisResult;
|
||||
import com.alibaba.dashscope.exception.ApiException;
|
||||
import com.alibaba.dashscope.exception.NoApiKeyException;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.rj.entity.ImageModel;
|
||||
import com.rj.mapper.ImageModelMapper;
|
||||
import com.rj.service.IImageModelService;
|
||||
import com.rj.service.MinIOService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 图像模型服务实现类
|
||||
*
|
||||
* 实现IImageModelService接口中定义的所有业务方法。
|
||||
* 该类负责处理图像模型相关的业务逻辑,包括:
|
||||
* - 图像模型记录的保存、查询、更新、删除操作
|
||||
* - 根据各种条件查询图像模型记录
|
||||
* - 异常处理和日志记录
|
||||
*
|
||||
* 继承ServiceImpl获得MyBatis-Plus提供的基础CRUD能力,
|
||||
* 同时实现自定义的业务方法。
|
||||
*
|
||||
* @author 系统生成
|
||||
* @date 2025/1/30
|
||||
* @version 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ImageModelServiceImpl extends ServiceImpl<ImageModelMapper, ImageModel>
|
||||
implements IImageModelService {
|
||||
|
||||
@Autowired
|
||||
private MinIOService minIOService;
|
||||
|
||||
/**
|
||||
* 保存图像模型记录
|
||||
*
|
||||
* 将图像模型数据保存到数据库中,包含完整的异常处理和日志记录。
|
||||
* 该方法会记录操作开始、成功或失败的日志信息。
|
||||
*
|
||||
* @param imageModel 图像模型记录对象,包含所有必要的字段信息
|
||||
* @return 是否保存成功,true表示保存成功,false表示保存失败
|
||||
*/
|
||||
@Override
|
||||
public boolean saveImageModel(ImageModel imageModel) {
|
||||
try {
|
||||
log.info("保存图像模型记录开始,参数:{}", imageModel);
|
||||
boolean result = this.save(imageModel);
|
||||
if (result) {
|
||||
log.info("图像模型记录保存成功,ID: {}", imageModel.getUuid());
|
||||
} else {
|
||||
log.error("图像模型记录保存失败");
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.error("保存图像模型记录异常", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据UUID查询图像模型记录
|
||||
*
|
||||
* 通过唯一标识符查询对应的图像模型记录。
|
||||
* 使用LambdaQueryWrapper构建查询条件,确保类型安全。
|
||||
*
|
||||
* @param uuid 唯一标识符,对应数据库主键
|
||||
* @return 图像模型记录,如果未找到则返回null
|
||||
*/
|
||||
@Override
|
||||
public ImageModel getByUuid(String uuid) {
|
||||
try {
|
||||
LambdaQueryWrapper<ImageModel> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(ImageModel::getUuid, uuid);
|
||||
return this.getOne(queryWrapper);
|
||||
} catch (Exception e) {
|
||||
log.error("根据ID查询图像模型记录异常", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据请求ID查询图像模型记录
|
||||
*
|
||||
* 通过请求ID查询对应的图像模型记录。
|
||||
* 由于一个请求ID可能对应多条记录,此方法返回最新的一条。
|
||||
* 查询结果按创建时间降序排列,取第一条记录。
|
||||
*
|
||||
* @param requestId 请求ID,用于追踪处理请求
|
||||
* @return 图像模型记录,如果未找到则返回null
|
||||
*/
|
||||
@Override
|
||||
public ImageModel getByRequestId(String requestId) {
|
||||
try {
|
||||
LambdaQueryWrapper<ImageModel> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(ImageModel::getRequestId, requestId)
|
||||
.orderByDesc(ImageModel::getCreateTime)
|
||||
.last("LIMIT 1");
|
||||
return this.getOne(queryWrapper);
|
||||
} catch (Exception e) {
|
||||
log.error("根据请求ID查询图像模型记录异常", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据任务ID查询图像模型记录
|
||||
*
|
||||
* 通过任务ID查询对应的图像模型记录。
|
||||
* 由于一个任务ID可能对应多条记录,此方法返回最新的一条。
|
||||
* 查询结果按创建时间降序排列,取第一条记录。
|
||||
*
|
||||
* @param taskId 任务ID,用于追踪异步处理任务
|
||||
* @return 图像模型记录,如果未找到则返回null
|
||||
*/
|
||||
@Override
|
||||
public ImageModel getByTaskId(String taskId) {
|
||||
try {
|
||||
LambdaQueryWrapper<ImageModel> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(ImageModel::getTaskId, taskId)
|
||||
.orderByDesc(ImageModel::getCreateTime)
|
||||
.last("LIMIT 1");
|
||||
return this.getOne(queryWrapper);
|
||||
} catch (Exception e) {
|
||||
log.error("根据任务ID查询图像模型记录异常", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据所属人电话查询图像模型记录
|
||||
*
|
||||
* 通过所属人电话查询对应的图像模型记录。
|
||||
* 由于一个电话号码可能对应多条记录,此方法返回最新的一条。
|
||||
* 查询结果按创建时间降序排列,取第一条记录。
|
||||
*
|
||||
* @param ownerPhone 所属人电话,用于查询特定用户的记录
|
||||
* @return 图像模型记录,如果未找到则返回null
|
||||
*/
|
||||
@Override
|
||||
public ImageModel getByOwnerPhone(String ownerPhone) {
|
||||
try {
|
||||
LambdaQueryWrapper<ImageModel> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(ImageModel::getOwnerPhone, ownerPhone)
|
||||
.orderByDesc(ImageModel::getCreateTime)
|
||||
.last("LIMIT 1");
|
||||
return this.getOne(queryWrapper);
|
||||
} catch (Exception e) {
|
||||
log.error("根据所属人电话查询图像模型记录异常", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除图像中的中英文字符或常见水印
|
||||
*
|
||||
* 实现图像水印去除的核心业务逻辑,包括:
|
||||
* 1. 参数验证和预处理
|
||||
* 2. 调用AI模型进行水印检测和去除
|
||||
* 3. 处理结果并生成访问URL
|
||||
* 4. 保存处理记录到数据库
|
||||
* 5. 返回处理结果
|
||||
*
|
||||
* @param imageModel 图像模型记录对象,包含处理参数和结果信息
|
||||
* @return 处理后的图像模型记录,包含结果URL等信息
|
||||
*/
|
||||
@Override
|
||||
public ImageModel removeWatermar(ImageModel imageModel) {
|
||||
try {
|
||||
log.info("开始去除图像水印,参数:{}", imageModel);
|
||||
|
||||
// 1. 参数验证
|
||||
if (imageModel.getMaterialTempUrl() == null || imageModel.getMaterialTempUrl().trim().isEmpty()) {
|
||||
log.error("素材URL不能为空");
|
||||
throw new IllegalArgumentException("素材URL不能为空");
|
||||
}
|
||||
imageModel.setPrompt("去除图像中的文字");
|
||||
imageModel.setModelName("wanx2.1-imageedit");
|
||||
imageModel.setFunctionName("remove_watermark");
|
||||
// 3. 模拟AI模型处理(实际项目中这里会调用真实的AI服务)
|
||||
log.info("调用AI模型进行水印去除处理...");
|
||||
/**
|
||||
* {
|
||||
* "input": {
|
||||
* "function": "remove_watermark",
|
||||
* "prompt": "去除图像中的文字",
|
||||
* "base_image_url": "http://wanx.alicdn.com/material/20250318/remove_watermark_1.png"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
// 若没有配置环境变量,请用百炼API Key将下行替换为:apiKey="sk-xxx"
|
||||
String apiKey = System.getenv("DASHSCOPE_API_KEY");
|
||||
Map<String, Object> parameters = new HashMap<>();
|
||||
parameters.put("prompt_extend", true);
|
||||
|
||||
ImageSynthesisParam param =
|
||||
ImageSynthesisParam.builder()
|
||||
.apiKey(apiKey)
|
||||
.model(imageModel.getModelName())
|
||||
.function(imageModel.getFunctionName())
|
||||
.prompt(imageModel.getPrompt())
|
||||
.baseImageUrl(imageModel.getMaterialTempUrl().trim())
|
||||
.n(1)
|
||||
.size("1024*1024")
|
||||
.parameters(parameters)
|
||||
.build();
|
||||
|
||||
ImageSynthesis imageSynthesis = new ImageSynthesis();
|
||||
ImageSynthesisResult result = null;
|
||||
try {
|
||||
System.out.println("---sync call, please wait a moment----");
|
||||
log.info("开始同步调用,参数是:{} ",param);
|
||||
result = imageSynthesis.call(param);
|
||||
log.info("返回结果 : ", result);
|
||||
System.out.println(JsonUtils.toJson(result));
|
||||
|
||||
|
||||
result.getOutput().getResults().forEach(resultItem -> {
|
||||
|
||||
imageModel.setResultImageUrl(resultItem.get("url"));
|
||||
});
|
||||
} catch (ApiException | NoApiKeyException e){
|
||||
log.error("api call error", e);
|
||||
}
|
||||
System.out.println(JsonUtils.toJson(result));
|
||||
|
||||
// 4. 下载AI处理结果图片并上传到MinIO
|
||||
if (result != null && result.getOutput() != null && !result.getOutput().getResults().isEmpty()) {
|
||||
String resultImageUrl = result.getOutput().getResults().get(0).get("url");
|
||||
if (resultImageUrl != null && !resultImageUrl.trim().isEmpty()) {
|
||||
log.info("开始下载AI处理结果图片: {}", resultImageUrl);
|
||||
|
||||
try {
|
||||
// 下载图片到字节数组
|
||||
byte[] imageBytes = downloadImageToBytes(resultImageUrl);
|
||||
log.info("图片下载成功,大小: {} bytes", imageBytes.length);
|
||||
|
||||
// 生成唯一文件名
|
||||
String resultFileName = generateUniqueFileName("jpg");
|
||||
|
||||
// 上传到MinIO
|
||||
String resultImageMinIOUrl = minIOService.uploadFile(imageBytes, resultFileName, "image/jpeg");
|
||||
log.info("图片上传到MinIO成功: {}", resultImageMinIOUrl);
|
||||
|
||||
// 生成7天临时访问链接
|
||||
String resultImageTempUrl = minIOService.generateTempUrl(resultFileName);
|
||||
log.info("生成7天临时访问链接: {}", resultImageTempUrl);
|
||||
|
||||
// 更新ImageModel对象
|
||||
imageModel.setResultImageUrl(resultImageMinIOUrl);
|
||||
imageModel.setResultImageTempUrl(resultImageTempUrl);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("下载或上传AI处理结果图片失败", e);
|
||||
throw new RuntimeException("处理结果图片失败: " + e.getMessage(), e);
|
||||
}
|
||||
} else {
|
||||
log.warn("AI处理结果中没有有效的图片URL");
|
||||
}
|
||||
} else {
|
||||
log.warn("AI处理结果为空或无效");
|
||||
}
|
||||
|
||||
// 6. 保存处理记录
|
||||
boolean saveResult = this.updateById(imageModel);
|
||||
if (!saveResult) {
|
||||
log.error("保存水印去除记录失败");
|
||||
throw new RuntimeException("保存水印去除记录失败");
|
||||
}
|
||||
|
||||
log.info("水印去除处理完成,ID: {}, 结果URL: {}",
|
||||
imageModel.getUuid(), imageModel.getResultImageTempUrl());
|
||||
|
||||
return imageModel;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("去除图像水印异常", e);
|
||||
throw new RuntimeException("去除图像水印失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图片素材
|
||||
*
|
||||
* 实现图片素材上传的完整业务逻辑,包括:
|
||||
* 1. 文件验证和格式检查
|
||||
* 2. 上传到MinIO存储
|
||||
* 3. 生成永久URL和临时URL
|
||||
* 4. 保存上传记录到数据库
|
||||
*
|
||||
* @param file 上传的图片文件
|
||||
* @param ownerName 所属人姓名
|
||||
* @param ownerPhone 所属人电话
|
||||
* @param imageType 图片类型
|
||||
* @return 图像模型记录,包含上传结果和URL信息
|
||||
*/
|
||||
@Override
|
||||
public ImageModel uploadImageMaterial(MultipartFile file, String ownerName, String ownerPhone, String imageType,String imageName) {
|
||||
try {
|
||||
log.info("开始上传图片素材,文件名:{},所属人:{},电话:{}",
|
||||
file.getOriginalFilename(), ownerName, ownerPhone);
|
||||
|
||||
// 1. 文件验证
|
||||
validateImageFile(file);
|
||||
|
||||
// 2. 生成唯一文件名
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
String fileExtension = getFileExtension(originalFilename);
|
||||
String uniqueFileName = generateUniqueFileName(fileExtension);
|
||||
|
||||
// 3. 上传到MinIO
|
||||
log.info("开始上传文件到MinIO,文件名:{}", uniqueFileName);
|
||||
String materialUrl = minIOService.uploadFileWithName(file, uniqueFileName);
|
||||
String materialTempUrl = minIOService.generateTempUrl(uniqueFileName);
|
||||
|
||||
// 4. 构建图像模型记录
|
||||
ImageModel imageModel = new ImageModel();
|
||||
imageModel.setImageName(originalFilename);
|
||||
imageModel.setOwnerName(ownerName);
|
||||
imageModel.setOwnerPhone(ownerPhone);
|
||||
imageModel.setImageType(imageType);
|
||||
imageModel.setMaterialUrl(materialUrl);
|
||||
imageModel.setMaterialTempUrl(materialTempUrl);
|
||||
imageModel.setCreateTime(LocalDateTime.now());
|
||||
imageModel.setUpdateTime(LocalDateTime.now());
|
||||
|
||||
if ( imageName!=null && !imageName.trim().isEmpty()){
|
||||
imageModel.setImageName(imageName);
|
||||
}
|
||||
// 5. 保存到数据库
|
||||
boolean saveResult = this.saveImageModel(imageModel);
|
||||
if (!saveResult) {
|
||||
log.error("保存图片素材上传记录失败");
|
||||
throw new RuntimeException("保存图片素材上传记录失败");
|
||||
}
|
||||
|
||||
log.info("图片素材上传成功,ID: {},永久URL: {},临时URL: {}",
|
||||
imageModel.getUuid(), materialUrl, materialTempUrl);
|
||||
|
||||
return imageModel;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("上传图片素材异常", e);
|
||||
throw new RuntimeException("上传图片素材失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeByUuid(String uuid) {
|
||||
boolean b = this.removeById(uuid);
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证图片文件
|
||||
*
|
||||
* 检查文件格式、大小等是否符合要求
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @throws IllegalArgumentException 文件不符合要求时抛出异常
|
||||
*/
|
||||
private void validateImageFile(MultipartFile file) {
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new IllegalArgumentException("上传文件不能为空");
|
||||
}
|
||||
|
||||
// 检查文件大小(限制为10MB)
|
||||
long maxSize = 10 * 1024 * 1024; // 10MB
|
||||
if (file.getSize() > maxSize) {
|
||||
throw new IllegalArgumentException("文件大小不能超过10MB");
|
||||
}
|
||||
|
||||
// 检查文件格式
|
||||
String contentType = file.getContentType();
|
||||
if (contentType == null || !contentType.startsWith("image/")) {
|
||||
throw new IllegalArgumentException("只能上传图片文件");
|
||||
}
|
||||
|
||||
// 检查文件扩展名
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
if (originalFilename == null || originalFilename.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("文件名不能为空");
|
||||
}
|
||||
|
||||
String extension = getFileExtension(originalFilename).toLowerCase();
|
||||
String[] allowedExtensions = {"jpg", "jpeg", "png", "gif", "bmp", "webp"};
|
||||
boolean isValidExtension = false;
|
||||
for (String allowedExt : allowedExtensions) {
|
||||
if (extension.equals(allowedExt)) {
|
||||
isValidExtension = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValidExtension) {
|
||||
throw new IllegalArgumentException("不支持的图片格式,支持的格式:jpg, jpeg, png, gif, bmp, webp");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件扩展名
|
||||
*
|
||||
* @param filename 文件名
|
||||
* @return 文件扩展名
|
||||
*/
|
||||
private String getFileExtension(String filename) {
|
||||
if (filename == null || filename.lastIndexOf('.') == -1) {
|
||||
return "";
|
||||
}
|
||||
return filename.substring(filename.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成唯一文件名
|
||||
*
|
||||
* 格式:时间戳_UUID.扩展名
|
||||
*
|
||||
* @param extension 文件扩展名
|
||||
* @return 唯一文件名
|
||||
*/
|
||||
private String generateUniqueFileName(String extension) {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
String uuid = UUID.randomUUID().toString().replace("-", "");
|
||||
return timestamp + "_" + uuid + "." + extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载图片到字节数组
|
||||
*
|
||||
* 从指定URL下载图片并返回字节数组
|
||||
*
|
||||
* @param imageUrl 图片URL
|
||||
* @return 图片字节数组
|
||||
* @throws IOException 下载失败时抛出异常
|
||||
*/
|
||||
private byte[] downloadImageToBytes(String imageUrl) throws IOException {
|
||||
try {
|
||||
log.info("开始下载图片: {}", imageUrl);
|
||||
|
||||
URL url = new URL(imageUrl);
|
||||
try (InputStream inputStream = url.openStream();
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
byte[] imageBytes = outputStream.toByteArray();
|
||||
log.info("图片下载完成,大小: {} bytes", imageBytes.length);
|
||||
return imageBytes;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("下载图片失败: {}", imageUrl, e);
|
||||
throw new IOException("下载图片失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -91,6 +91,11 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IM
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -91,6 +91,11 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -91,6 +91,11 @@ public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> i
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user