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 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 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 selectImageDataBySOrdIDDt(Long sOrdIDDt) { return imageDataMapper.selectImageDataBySOrdIDDt(sOrdIDDt); } /** * 根据图片类型查询图片数据 * * @param imageType 图片类型 * @return 图片数据集合 */ @Override public List 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); } 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(); } } /** * 生成图片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(); } } /** * 检查文件兼容性(确保与旧系统兼容) * * @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 { 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); } return "图片上传成功,文件路径:" + originalImageUrl; } catch (Exception e) { log.error("微信图片上传处理失败:{}", e.getMessage(), e); return "处理失败:" + e.getMessage(); } } /** * 根据调度单ID和图片类型查询图片数据 * * @param dispatchOrdID 调度单ID * @param imageType 图片类型 * @return 图片数据集合 */ @Override public List selectImageDataByDOrdIDDtAndType(Long dispatchOrdID, Integer imageType) { // 创建查询条件 ImageData imageData = new ImageData(); imageData.setDOrdIDDt(dispatchOrdID); imageData.setImageType(imageType); // 查询图片数据 return imageDataMapper.selectImageDataList(imageData); } }