package com.ruoyi.system.imagedata;
|
|
import com.ruoyi.common.annotation.DataSource;
|
import com.ruoyi.common.config.LegacySystemConfig;
|
import com.ruoyi.common.enums.DataSourceType;
|
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.system.domain.ImageData;
|
import com.ruoyi.system.domain.enums.ImageTypeEnum;
|
import com.ruoyi.system.file.FileUploadResponse;
|
import com.ruoyi.system.file.IFileUploadService;
|
import com.ruoyi.system.mapper.ImageDataMapper;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import javax.imageio.ImageIO;
|
import java.awt.*;
|
import java.awt.image.BufferedImage;
|
import java.io.File;
|
import java.io.FileOutputStream;
|
import java.io.IOException;
|
import java.util.Date;
|
import java.util.List;
|
|
@Service
|
@DataSource(DataSourceType.SQLSERVER)
|
public class ImageDataServiceImpl implements IImageDataService {
|
|
private static final Logger log = LoggerFactory.getLogger(ImageDataServiceImpl.class);
|
@Autowired
|
private ImageDataMapper imageDataMapper;
|
|
@Autowired
|
private IFileUploadService fileUploadService;
|
|
@Autowired
|
private LegacySystemConfig legacyConfig;
|
/**
|
* 查询图片数据
|
*
|
* @param id 图片数据主键
|
* @return 图片数据
|
*/
|
@Override
|
public ImageData selectImageDataById(Long id) {
|
return imageDataMapper.selectImageDataById(id);
|
}
|
|
/**
|
* 查询图片数据列表
|
*
|
* @param imageData 图片数据
|
* @return 图片数据
|
*/
|
@Override
|
public List<ImageData> selectImageDataList(ImageData imageData) {
|
return imageDataMapper.selectImageDataList(imageData);
|
}
|
|
/**
|
* 新增图片数据
|
*
|
* @param imageData 图片数据
|
* @return 结果
|
*/
|
@Override
|
public int insertImageData(ImageData imageData) {
|
return imageDataMapper.insertImageData(imageData);
|
}
|
|
/**
|
* 修改图片数据
|
*
|
* @param imageData 图片数据
|
* @return 结果
|
*/
|
@Override
|
public int updateImageData(ImageData imageData) {
|
return imageDataMapper.updateImageData(imageData);
|
}
|
|
/**
|
* 批量删除图片数据
|
*
|
* @param ids 需要删除的图片数据主键
|
* @return 结果
|
*/
|
@Override
|
public int deleteImageDataByIds(Long[] ids) {
|
return imageDataMapper.deleteImageDataByIds(ids);
|
}
|
|
/**
|
* 删除图片数据信息
|
*
|
* @param id 图片数据主键
|
* @return 结果
|
*/
|
@Override
|
public int deleteImageDataById(Long id) {
|
return imageDataMapper.deleteImageDataById(id);
|
}
|
|
/**
|
* 根据调度单ID查询图片数据
|
*
|
* @param dOrdIDDt 调度单ID
|
* @return 图片数据集合
|
*/
|
@Override
|
public List<ImageData> selectImageDataByDOrdIDDt(Long dOrdIDDt) {
|
return imageDataMapper.selectImageDataByDOrdIDDt(dOrdIDDt);
|
}
|
/**
|
* 生成与旧系统兼容的文件路径
|
*
|
* @param dispatchOrdID 调度单ID
|
* @param mediaId 媒体ID
|
* @param isThumbnail 是否为缩略图
|
* @return 兼容的文件路径
|
*/
|
|
@Override
|
public String generateCompatibleFilePath(Long dispatchOrdID, String mediaId, boolean isThumbnail) {
|
try {
|
String yearMonth = DateUtils.dateTimeNow("yyyyMM");
|
String fileName = dispatchOrdID + "_" + mediaId + ".jpg";
|
|
if (isThumbnail) {
|
fileName = "s_" + fileName;
|
}
|
|
return legacyConfig.getFileServerUrl() + "/" + yearMonth + "/" + fileName;
|
} catch (Exception e) {
|
log.error("生成兼容文件路径失败:{}", e.getMessage());
|
return null;
|
}
|
}
|
|
/**
|
* 生成与旧系统兼容的访问URL
|
*
|
* @param dispatchOrdID 调度单ID
|
* @param mediaId 媒体ID
|
* @param isThumbnail 是否为缩略图
|
* @return 兼容的访问URL
|
*/
|
@Override
|
public String generateCompatibleUrl(Long dispatchOrdID, String mediaId, boolean isThumbnail) {
|
try {
|
String yearMonth = DateUtils.dateTimeNow("yyyyMM");
|
String fileName = dispatchOrdID + "_" + mediaId + ".jpg";
|
|
if (isThumbnail) {
|
fileName = "s_" + fileName;
|
}
|
|
return legacyConfig.getFileServerUrl() + "/" + yearMonth + "/" + fileName;
|
} catch (Exception e) {
|
log.error("生成兼容URL失败:{}", e.getMessage());
|
return null;
|
}
|
}
|
/**
|
* 根据服务单ID查询图片数据
|
*
|
* @param sOrdIDDt 服务单ID
|
* @return 图片数据集合
|
*/
|
@Override
|
public List<ImageData> selectImageDataBySOrdIDDt(Long sOrdIDDt) {
|
return imageDataMapper.selectImageDataBySOrdIDDt(sOrdIDDt);
|
}
|
|
/**
|
* 根据图片类型查询图片数据
|
*
|
* @param imageType 图片类型
|
* @return 图片数据集合
|
*/
|
@Override
|
public List<ImageData> selectImageDataByType(Integer imageType) {
|
ImageData imageData = new ImageData();
|
imageData.setImageType(imageType);
|
return imageDataMapper.selectImageDataList(imageData);
|
}
|
|
/**
|
* 标记图片为删除状态
|
*
|
* @param id 图片数据主键
|
* @return 结果
|
*/
|
@Override
|
public int markImageDataAsDeleted(Long id) {
|
ImageData imageData = new ImageData();
|
imageData.setId(id);
|
imageData.setImageDel(1); // 1表示已删除
|
return imageDataMapper.updateImageData(imageData);
|
}
|
|
|
/**
|
* 微信图片上传处理(原ASP代码转换)
|
*
|
* @param dispatchOrdID 调度单ID
|
* @param serviceOrdID 服务单ID
|
* @param oaid OA用户ID
|
* @param mediaId 微信媒体ID
|
* @param imageType 图片类型
|
* @param adminId 当前管理员ID
|
* @return 处理结果
|
*/
|
|
public String uploadWxImage(Long dispatchOrdID, Long serviceOrdID, Integer oaid,
|
String mediaId, Integer imageType, Integer adminId) {
|
try {
|
// 获取图片类型枚举
|
ImageTypeEnum imageTypeEnum = ImageTypeEnum.getByCode(imageType);
|
|
// 如果有调度单ID,则处理调度单相关图片
|
if (dispatchOrdID != null && dispatchOrdID > 0) {
|
return processDispatchOrderImage(dispatchOrdID, serviceOrdID, mediaId, imageTypeEnum, adminId);
|
}
|
// 如果只有OA用户ID,则更新用户头像
|
else if (oaid != null && oaid > 0) {
|
return updateUserAvatar(oaid, mediaId);
|
}
|
else {
|
return "参数错误:缺少必要的参数";
|
}
|
} catch (Exception e) {
|
return "处理失败:" + e.getMessage();
|
}
|
}
|
|
/**
|
* 处理调度单相关图片上传
|
*/
|
private String processDispatchOrderImage(Long dispatchOrdID, Long serviceOrdID,
|
String mediaId, ImageTypeEnum imageTypeEnum, Integer adminId) {
|
try {
|
// 生成图片URL路径
|
String imageUrl = generateImageUrl(dispatchOrdID, mediaId, false);
|
String imageUrls = generateImageUrl(dispatchOrdID, mediaId, true);
|
|
// 创建图片数据对象
|
ImageData imageData = new ImageData();
|
imageData.setDOrdIDDt(dispatchOrdID);
|
imageData.setSOrdIDDt(serviceOrdID);
|
imageData.setImageType(imageTypeEnum.getCode());
|
imageData.setImageUrl(imageUrl);
|
imageData.setImageUrls(imageUrls);
|
imageData.setUpImageTime(new Date());
|
imageData.setUpImageOAid(adminId);
|
imageData.setImageDel(0); // 0表示未删除
|
|
// 插入图片数据
|
int result = imageDataMapper.insertImageData(imageData);
|
if (result <= 0) {
|
return "图片数据保存失败";
|
}
|
|
|
return "图片上传成功,ID: " + imageData.getId() + ",类型: " + imageTypeEnum.getDescription();
|
|
} catch (Exception e) {
|
return "处理调度单图片失败:" + e.getMessage();
|
}
|
}
|
|
/**
|
* 更新用户头像
|
*/
|
private String updateUserAvatar(Integer oaid, String mediaId) {
|
try {
|
// 这里需要调用OA用户服务来更新头像
|
// 由于没有OA用户服务的具体实现,这里只是示例
|
String avatarUrl = "/upload/" + oaid + "_" + mediaId + ".jpg";
|
|
// TODO: 调用OA用户服务更新头像
|
// oaUserService.updateAvatar(oaid, avatarUrl);
|
|
return "用户头像更新成功";
|
} catch (Exception e) {
|
return "更新用户头像失败:" + e.getMessage();
|
}
|
}
|
|
/**
|
* 生成图片URL
|
*/
|
private String generateImageUrl(Long dispatchOrdID, String mediaId, boolean isThumbnail) {
|
Date now = new Date();
|
int year = now.getYear() + 1900; // Java的年份需要加1900
|
int month = now.getMonth() + 1; // Java的月份从0开始
|
|
String monthStr = String.format("%02d", month);
|
String prefix = isThumbnail ? "/upload/" + year + monthStr + "/s_" : "/upload/" + year + monthStr + "/";
|
|
return prefix + dispatchOrdID + "_" + mediaId + ".jpg";
|
}
|
|
|
|
|
/**
|
* 保存微信文件到本地(原PHP代码转换)
|
*
|
* @param filename 文件名
|
* @param fileContent 文件内容
|
* @return 是否保存成功
|
*/
|
public boolean saveWeixinFile(String filename, byte[] fileContent) {
|
FileOutputStream localFile = null;
|
try {
|
// 确保目录存在
|
File file = new File(filename);
|
File parentDir = file.getParentFile();
|
if (!parentDir.exists()) {
|
parentDir.mkdirs();
|
}
|
|
localFile = new FileOutputStream(filename);
|
localFile.write(fileContent);
|
localFile.flush();
|
|
log.info("成功保存微信文件:{}", filename);
|
return true;
|
} catch (Exception e) {
|
log.error("保存微信文件失败:{}", e.getMessage(), e);
|
return false;
|
} finally {
|
if (localFile != null) {
|
try {
|
localFile.close();
|
} catch (IOException e) {
|
log.error("关闭文件流失败:{}", e.getMessage());
|
}
|
}
|
}
|
}
|
|
/**
|
* 生成缩略图(原PHP代码转换)
|
*
|
* @param bigImgPath 原始大图路径
|
* @param width 缩略图宽度
|
* @param height 缩略图高度(0表示按比例计算)
|
* @param smallImgPath 缩略图保存路径
|
* @return 是否生成成功
|
*/
|
public boolean createThumbnail(String bigImgPath, int width, int height, String smallImgPath) {
|
try {
|
// 读取原始图片
|
BufferedImage originalImage = ImageIO.read(new File(bigImgPath));
|
if (originalImage == null) {
|
log.error("无法读取原始图片:{}", bigImgPath);
|
return false;
|
}
|
|
int srcWidth = originalImage.getWidth();
|
int srcHeight = originalImage.getHeight();
|
|
// 计算缩略图尺寸
|
if (height == 0) {
|
height = (int) Math.floor((double) width / srcWidth * srcHeight);
|
} else if (width == 0) {
|
width = (int) Math.floor((double) height / srcHeight * srcWidth);
|
}
|
|
// 创建缩略图
|
BufferedImage thumbnail = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
Graphics2D g = thumbnail.createGraphics();
|
|
// 设置渲染质量
|
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
// 绘制缩略图
|
g.drawImage(originalImage, 0, 0, width, height, null);
|
g.dispose();
|
|
// 确保目录存在
|
File smallImgFile = new File(smallImgPath);
|
File parentDir = smallImgFile.getParentFile();
|
if (!parentDir.exists()) {
|
parentDir.mkdirs();
|
}
|
|
// 保存缩略图
|
ImageIO.write(thumbnail, "jpg", smallImgFile);
|
|
log.info("成功生成缩略图:{} -> {} ({}x{})", bigImgPath, smallImgPath, width, height);
|
return true;
|
} catch (Exception e) {
|
log.error("生成缩略图失败:{}", e.getMessage(), e);
|
return false;
|
}
|
}
|
|
|
/**
|
* 处理调度单相关图片上传(包含文件URL)
|
*/
|
private String processDispatchOrderImageWithFiles(Long dispatchOrdID, Long serviceOrdID,
|
String mediaId, ImageTypeEnum imageTypeEnum,
|
Integer adminId, String originalImageUrl, String thumbnailUrl) {
|
try {
|
// 创建图片数据对象
|
ImageData imageData = new ImageData();
|
imageData.setDOrdIDDt(dispatchOrdID);
|
imageData.setSOrdIDDt(serviceOrdID);
|
imageData.setImageType(imageTypeEnum.getCode());
|
imageData.setImageUrl(originalImageUrl);
|
imageData.setImageUrls(thumbnailUrl);
|
imageData.setUpImageTime(new Date());
|
imageData.setUpImageOAid(adminId);
|
imageData.setImageDel(0); // 0表示未删除
|
|
// 插入图片数据
|
int result = imageDataMapper.insertImageData(imageData);
|
if (result <= 0) {
|
return "图片数据保存失败";
|
}
|
|
|
return "图片上传成功,ID: " + imageData.getId() + ",类型: " + imageTypeEnum.getDescription() +
|
",原始图片URL: " + originalImageUrl + ",缩略图URL: " + thumbnailUrl;
|
|
} catch (Exception e) {
|
return "处理调度单图片失败:" + e.getMessage();
|
}
|
}
|
|
/**
|
* 更新用户头像(包含文件URL)
|
*/
|
private String updateUserAvatarWithFile(Integer oaid, String mediaId, String imageUrl) {
|
try {
|
// 这里需要调用OA用户服务来更新头像
|
// TODO: 调用OA用户服务更新头像
|
// oaUserService.updateAvatar(oaid, imageUrl);
|
|
return "用户头像更新成功,URL:" + imageUrl;
|
} catch (Exception e) {
|
return "更新用户头像失败:" + e.getMessage();
|
}
|
}
|
|
/**
|
* 检查文件兼容性(确保与旧系统兼容)
|
*
|
* @param filePath 文件路径
|
* @return 兼容性检查结果
|
*/
|
public String checkFileCompatibility(String filePath) {
|
try {
|
File file = new File(filePath);
|
|
if (!file.exists()) {
|
return "文件不存在:" + filePath;
|
}
|
|
// 检查文件命名是否符合旧系统规范
|
String fileName = file.getName();
|
if (!fileName.matches("^(\\d+|[A-Z]+)_[A-Za-z0-9_]+\\.jpg$")) {
|
return "文件命名不符合旧系统规范:" + fileName;
|
}
|
|
// 检查目录结构是否符合旧系统规范
|
String parentDir = file.getParentFile().getName();
|
if (!parentDir.matches("^\\d{6}$")) { // 年月格式:202412
|
return "目录结构不符合旧系统规范:" + parentDir;
|
}
|
|
return "文件兼容性检查通过:" + filePath;
|
} catch (Exception e) {
|
return "兼容性检查失败:" + e.getMessage();
|
}
|
}
|
|
/**
|
* 验证URL格式是否与旧系统兼容
|
*
|
* @param url 图片URL
|
* @return 是否兼容
|
*/
|
public boolean isUrlCompatible(String url) {
|
try {
|
// 检查URL格式是否符合旧系统规范
|
// 旧系统格式:/upload/年月/文件名.jpg
|
return url.matches("^/upload/\\d{6}/[A-Za-z0-9_]+\\.jpg$");
|
} catch (Exception e) {
|
log.error("URL兼容性检查失败:{}", e.getMessage());
|
return false;
|
}
|
}
|
|
|
|
/**
|
* 通过图片URL上传处理(允许直接传入图片URL)
|
*
|
* @param dispatchOrdID 调度单ID
|
* @param serviceOrdID 服务单ID
|
* @param oaid OA用户ID
|
* @param imageUrl 图片URL
|
* @param thumbnailUrl 缩略图URL(可选)
|
* @param imageType 图片类型
|
* @param adminId 当前管理员ID
|
* @return 处理结果
|
*/
|
@Override
|
|
public String uploadImageByUrl(Long dispatchOrdID, Long serviceOrdID, Integer oaid,
|
String imageUrl, String thumbnailUrl, Integer imageType, Integer adminId) {
|
try {
|
// 验证参数
|
if (imageUrl == null || imageUrl.trim().isEmpty()) {
|
return "图片URL不能为空";
|
}
|
|
// 处理业务逻辑
|
if (dispatchOrdID != null && dispatchOrdID > 0) {
|
// 调度单相关图片
|
ImageTypeEnum imageTypeEnum = ImageTypeEnum.getByCode(imageType);
|
return processDispatchOrderImageWithFiles(dispatchOrdID, serviceOrdID, null,
|
imageTypeEnum, adminId, imageUrl, thumbnailUrl);
|
} else if (oaid != null && oaid > 0) {
|
// OA用户头像
|
return updateUserAvatarWithFile(oaid, null, imageUrl);
|
} else {
|
return "参数错误:缺少必要的参数(调度单ID或OA用户ID)";
|
}
|
} catch (Exception e) {
|
log.error("通过URL上传图片失败:{}", e.getMessage(), e);
|
return "处理失败:" + e.getMessage();
|
}
|
}
|
|
/**
|
* 通过图片URL上传处理(简化版本,自动生成缩略图URL)
|
*
|
* @param dispatchOrdID 调度单ID
|
* @param serviceOrdID 服务单ID
|
* @param oaid OA用户ID
|
* @param imageUrl 图片URL
|
* @param imageType 图片类型
|
* @param adminId 当前管理员ID
|
* @return 处理结果
|
*/
|
@Override
|
|
public String uploadImageByUrlSimple(Long dispatchOrdID, Long serviceOrdID, Integer oaid,
|
String imageUrl, Integer imageType, Integer adminId) {
|
try {
|
// 验证参数
|
if (imageUrl == null || imageUrl.trim().isEmpty()) {
|
return "图片URL不能为空";
|
}
|
|
// 自动生成缩略图URL(如果原图URL包含文件名)
|
String thumbnailUrl = null;
|
if (imageUrl.contains("/")) {
|
String fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
|
if (fileName.contains(".")) {
|
String nameWithoutExt = fileName.substring(0, fileName.lastIndexOf("."));
|
String extension = fileName.substring(fileName.lastIndexOf("."));
|
String thumbnailFileName = "s_" + nameWithoutExt + extension;
|
thumbnailUrl = imageUrl.substring(0, imageUrl.lastIndexOf("/") + 1) + thumbnailFileName;
|
}
|
}
|
|
// 调用完整版本的方法
|
return uploadImageByUrl(dispatchOrdID, serviceOrdID, oaid, imageUrl, thumbnailUrl, imageType, adminId);
|
} catch (Exception e) {
|
log.error("通过URL上传图片(简化版)失败:{}", e.getMessage(), e);
|
return "处理失败:" + e.getMessage();
|
}
|
}
|
|
@Override
|
public String uploadWxImageWithDownload(String accessToken, String mediaId, Long dispatchOrdID, Integer oaid, Integer imageType, Integer adminId) {
|
try {
|
// 确定目标路径
|
String targetPath;
|
if (dispatchOrdID != null && dispatchOrdID > 0) {
|
// 调度单相关图片:按年月组织目录
|
String yearMonth = DateUtils.dateTimeNow("yyyyMM");
|
targetPath = yearMonth + "/" + dispatchOrdID;
|
} else if (oaid != null && oaid > 0) {
|
// OA用户头像
|
targetPath = "avatar/" + oaid;
|
} else {
|
return "参数错误:缺少必要的参数";
|
}
|
|
// 使用文件上传服务从微信下载并上传文件
|
FileUploadResponse uploadResponse = fileUploadService.uploadFromWechat(accessToken, mediaId, targetPath);
|
if (!uploadResponse.isSuccess()) {
|
return "文件上传失败:" + uploadResponse.getMessage();
|
}
|
|
// 获取上传后的文件路径
|
String originalImageUrl = uploadResponse.getFilePath();
|
String thumbnailUrl = uploadResponse.getThumbnailPath();
|
|
// 处理业务逻辑
|
if (dispatchOrdID != null && dispatchOrdID > 0) {
|
return processDispatchOrderImageWithFiles(dispatchOrdID, null, mediaId,
|
ImageTypeEnum.getByCode(imageType), adminId, originalImageUrl, thumbnailUrl);
|
} else if (oaid != null && oaid > 0) {
|
return updateUserAvatarWithFile(oaid, mediaId, originalImageUrl);
|
}
|
|
return "图片上传成功,文件路径:" + originalImageUrl;
|
} catch (Exception e) {
|
log.error("微信图片上传处理失败:{}", e.getMessage(), e);
|
return "处理失败:" + e.getMessage();
|
}
|
}
|
|
/**
|
* 根据调度单ID和图片类型查询图片数据
|
*
|
* @param dispatchOrdID 调度单ID
|
* @param imageType 图片类型
|
* @return 图片数据集合
|
*/
|
@Override
|
public List<ImageData> selectImageDataByDOrdIDDtAndType(Long dispatchOrdID, Integer imageType) {
|
// 创建查询条件
|
ImageData imageData = new ImageData();
|
imageData.setDOrdIDDt(dispatchOrdID);
|
imageData.setImageType(imageType);
|
|
// 查询图片数据
|
return imageDataMapper.selectImageDataList(imageData);
|
}
|
|
}
|