package com.ruoyi.system.service.impl; import com.ruoyi.common.config.ImageUrlConfig; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.file.FileUploadUtils; import com.ruoyi.common.utils.file.FileUtils; import com.ruoyi.system.domain.SysTaskAttachment; import com.ruoyi.system.mapper.SysTaskAttachmentMapper; import com.ruoyi.system.service.ISysTaskAttachmentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; @Service public class SysTaskAttachmentServiceImpl implements ISysTaskAttachmentService { @Autowired private SysTaskAttachmentMapper sysTaskAttachmentMapper; @Autowired private ImageUrlConfig imageUrlConfig; @Override @Transactional public Long uploadAttachment(Long taskId, MultipartFile file, String category) { try { String fileName = category + "_" + System.currentTimeMillis() + "_" + file.getOriginalFilename(); String relativePath = saveLocalPath(fileName, file.getInputStream()); SysTaskAttachment attachment = new SysTaskAttachment(); attachment.setTaskId(taskId); attachment.setFileName(file.getOriginalFilename()); attachment.setFilePath(relativePath); attachment.setFileSize(file.getSize()); attachment.setFileType(getFileType(file.getOriginalFilename())); attachment.setAttachmentCategory(category); attachment.setUploadTime(DateUtils.getNowDate()); attachment.setUploadBy(SecurityUtils.getUsername()); Long result = sysTaskAttachmentMapper.insertSysTaskAttachment(attachment); return result > 0 ? attachment.getAttachmentId() : 0L; } catch (IOException e) { throw new RuntimeException("文件上传失败:" + e.getMessage()); } } @Override @Transactional public Long uploadAttachmentFromWechat(Long taskId, String accessToken, String mediaId, String category) { try { String wechatUrl = String.format( "https://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s", accessToken, mediaId ); byte[] fileBytes = downloadFromUrl(wechatUrl); if (fileBytes == null || fileBytes.length == 0) { throw new RuntimeException("从微信下载文件失败"); } String fileName = "wx_" + mediaId.substring(0, Math.min(20, mediaId.length())) + "_" + System.currentTimeMillis() + ".jpg"; String relativeFilePath = saveLocalPath(fileName, fileBytes); SysTaskAttachment attachment = new SysTaskAttachment(); attachment.setTaskId(taskId); attachment.setFileName(fileName); attachment.setFilePath(relativeFilePath); attachment.setFileSize((long) fileBytes.length); attachment.setFileType("jpg"); attachment.setAttachmentCategory(category); attachment.setUploadTime(DateUtils.getNowDate()); attachment.setUploadBy(SecurityUtils.getUsername()); Long result = sysTaskAttachmentMapper.insertSysTaskAttachment(attachment); return result > 0 ? attachment.getAttachmentId() : 0L; } catch (Exception e) { throw new RuntimeException("从微信上传文件失败:" + e.getMessage()); } } @Override @Transactional public int deleteAttachment(Long attachmentId) { SysTaskAttachment attachment = sysTaskAttachmentMapper.selectSysTaskAttachmentByAttachmentId(attachmentId); if (attachment == null) { throw new RuntimeException("附件不存在"); } try { FileUtils.deleteFile(attachment.getFilePath()); } catch (Exception e) { // ignore } return sysTaskAttachmentMapper.deleteSysTaskAttachmentByAttachmentId(attachmentId); } @Override public SysTaskAttachment getAttachmentById(Long attachmentId) { SysTaskAttachment attachment = sysTaskAttachmentMapper.selectSysTaskAttachmentByAttachmentId(attachmentId); if (attachment != null) { buildAttachmentUrl(attachment); } return attachment; } @Override public List getAttachmentsByTaskId(Long taskId) { List list = sysTaskAttachmentMapper.selectSysTaskAttachmentByTaskId(taskId); if (list != null && !list.isEmpty()) { list.forEach(this::buildAttachmentUrl); } return list; } private String saveLocalPath(String fileName, InputStream stream) throws IOException { String baseDir = FileUploadUtils.getDefaultBaseDir(); String datePath = DateUtils.datePath(); String uploadDir = baseDir + "/task/" + datePath; File uploadPath = new File(uploadDir); if (!uploadPath.exists()) { uploadPath.mkdirs(); } String filePath = uploadDir + "/" + fileName; try (OutputStream os = new FileOutputStream(filePath)) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = stream.read(buffer)) != -1) { os.write(buffer, 0, bytesRead); } os.flush(); } return "/task/" + datePath + "/" + fileName; } private String saveLocalPath(String fileName, byte[] fileBytes) throws IOException { String baseDir = FileUploadUtils.getDefaultBaseDir(); String datePath = DateUtils.datePath(); String uploadDir = baseDir + "/task/" + datePath; File uploadPath = new File(uploadDir); if (!uploadPath.exists()) { uploadPath.mkdirs(); } String filePath = uploadDir + "/" + fileName; File file = new File(filePath); try (FileOutputStream fos = new FileOutputStream(file)) { fos.write(fileBytes); } return "/task/" + datePath + "/" + fileName; } private byte[] downloadFromUrl(String fileUrl) throws IOException { URL url = new URL(fileUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(10000); connection.setReadTimeout(30000); try (InputStream inputStream = connection.getInputStream()) { byte[] buffer = new byte[4096]; int bytesRead; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } return outputStream.toByteArray(); } finally { connection.disconnect(); } } private String getFileType(String fileName) { if (StringUtils.isEmpty(fileName)) { return ""; } int lastDotIndex = fileName.lastIndexOf("."); if (lastDotIndex > 0 && lastDotIndex < fileName.length() - 1) { return fileName.substring(lastDotIndex + 1).toLowerCase(); } return ""; } @Override public void buildAttachmentUrl(SysTaskAttachment attachment) { if (attachment == null || StringUtils.isEmpty(attachment.getFilePath())) { return; } String baseUrl = imageUrlConfig.getImageUrl(); if (!attachment.getFilePath().startsWith("http")) { attachment.setFileUrl(baseUrl + attachment.getFilePath()); } else { attachment.setFileUrl(attachment.getFilePath()); } } @Override public String getCategoryDesc(String category) { if (category == null || category.isEmpty()) { return "未分类"; } switch (category) { case "1": return "知情同意书"; case "2": return "病人资料"; case "3": return "操作记录"; case "4": return "出车前"; case "5": return "出车后"; case "6": return "系安全带"; default: return "其他"; } } }