wlzboy
2025-11-09 fa5ea853099e88be253fca4fb2b0c2b7af5f396e
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
@@ -1,14 +1,19 @@
package com.ruoyi.system.service.impl;
import java.io.*;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.utils.TaskCodeGenerator;
import com.ruoyi.common.config.ImageUrlConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -31,20 +36,15 @@
import com.ruoyi.system.domain.vo.TaskUpdateVO;
import com.ruoyi.system.domain.vo.TaskStatisticsVO;
import com.ruoyi.system.domain.enums.TaskStatus;
import com.ruoyi.system.mapper.SysTaskMapper;
import com.ruoyi.system.mapper.SysTaskVehicleMapper;
import com.ruoyi.system.mapper.SysTaskAttachmentMapper;
import com.ruoyi.system.mapper.SysTaskLogMapper;
import com.ruoyi.system.mapper.SysTaskEmergencyMapper;
import com.ruoyi.system.mapper.SysTaskWelfareMapper;
import com.ruoyi.system.mapper.SysTaskAssigneeMapper;
import com.ruoyi.system.mapper.VehicleInfoMapper;
import com.ruoyi.system.domain.VehicleInfo;
import com.ruoyi.system.service.ISysTaskService;
import com.ruoyi.system.service.ILegacySystemSyncService;
import com.ruoyi.system.service.ITaskAttachmentSyncService;
import com.ruoyi.system.event.TaskCreatedEvent;
import com.ruoyi.system.event.TaskAssignedEvent;
import com.ruoyi.system.event.TaskStatusChangedEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
@@ -56,6 +56,8 @@
 */
@Service
public class SysTaskServiceImpl implements ISysTaskService {
    private static final Logger log = LoggerFactory.getLogger(SysTaskServiceImpl.class);
    
    @Autowired
    private SysTaskMapper sysTaskMapper;
@@ -86,6 +88,15 @@
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    @Autowired
    private ImageUrlConfig imageUrlConfig;
    @Autowired(required = false)
    private ITaskAttachmentSyncService taskAttachmentSyncService;
    @Autowired
    private SysUserMapper sysUserMapper;
    /**
     * 查询任务管理
@@ -496,37 +507,183 @@
     * 
     * @param taskId 任务ID
     * @param file 文件
     * @param category 附件分类
     * @return 结果
     */
    @Override
    @Transactional
    public int uploadAttachment(Long taskId, MultipartFile file) {
    public Long uploadAttachment(Long taskId, MultipartFile file, String category) {
        try {
            // 上传文件
            String fileName = FileUploadUtils.upload("/task", file);
            String filePath = FileUploadUtils.getDefaultBaseDir() + fileName;
            // 上传文件,返回相对路径(如:/task/2025/01/15/xxx.jpg)
            String fileName = category+"_"+System.currentTimeMillis()+"_"+file.getOriginalFilename();
            fileName=saveLocalPath(fileName,file.getInputStream());
            
            SysTaskAttachment attachment = new SysTaskAttachment();
            attachment.setTaskId(taskId);
            attachment.setFileName(file.getOriginalFilename());
            attachment.setFilePath(filePath);
            // 保存相对路径,不包含 baseDir
            attachment.setFilePath(fileName);
            attachment.setFileSize(file.getSize());
            attachment.setFileType(getFileType(file.getOriginalFilename()));
            attachment.setAttachmentCategory(category);
            attachment.setUploadTime(DateUtils.getNowDate());
            attachment.setUploadBy(SecurityUtils.getUsername());
            
            int result = sysTaskAttachmentMapper.insertSysTaskAttachment(attachment);
            Long result = sysTaskAttachmentMapper.insertSysTaskAttachment(attachment);
            
            // 记录操作日志
            if (result > 0) {
                String categoryDesc = getCategoryDesc(category);
                recordTaskLog(taskId, "UPDATE", "上传附件", null, 
                             "上传文件:" + file.getOriginalFilename(),
                             "上传文件:" + file.getOriginalFilename() + "(分类:" + categoryDesc + ")",
                             SecurityUtils.getUserId(), SecurityUtils.getUsername());
            }
            
            return result;
            return attachment.getAttachmentId();
        } catch (IOException e) {
            throw new RuntimeException("文件上传失败:" + e.getMessage());
        }
    }
    /**
     * 从微信mediaId上传任务附件
     *
     * @param taskId 任务ID
     * @param accessToken 微信AccessToken
     * @param mediaId 微信mediaId
     * @param category 附件分类
     * @return 返回附件ID
     */
    @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("从微信下载文件失败");
            }
            // 生成文件名(使用mediaId作为文件名的一部分)
            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);
            // 记录操作日志
            if (result > 0) {
                String categoryDesc = getCategoryDesc(category);
                recordTaskLog(taskId, "UPDATE", "上传附件", null,
                             "通过微信上传文件:" + fileName + "(分类:" + categoryDesc + ")",
                             SecurityUtils.getUserId(), SecurityUtils.getUsername());
            }
            return attachment.getAttachmentId();
        } catch (Exception e) {
            throw new RuntimeException("从微信上传文件失败:" + e.getMessage());
        }
    }
    private static 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);
        }
        // 生成相对路径(不包含baseDir)
        String relativeFilePath = "/task/" + datePath + "/" + fileName;
        return relativeFilePath;
    }
    private String saveLocalPath(String fileName,InputStream stream){
        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;
       //将inputstream写入文件
        try (OutputStream os = new FileOutputStream(filePath)) {
            byte[] buffer = new byte[1024]; // 缓冲区,减少 IO 次数
            int bytesRead;
            // 循环读取输入流中的数据,写入输出流
            while ((bytesRead = stream.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.flush(); // 强制刷新缓冲区,确保数据写入文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 生成相对路径(不包含baseDir)
        String relativeFilePath = "/task/" + datePath + "/" + fileName;
        return relativeFilePath;
    }
    /**
     * 从 URL 下载文件
     */
    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;
            java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            return outputStream.toByteArray();
        } finally {
            connection.disconnect();
        }
    }
@@ -561,6 +718,27 @@
        }
        
        return result;
    }
    /**
     * 根据ID获取附件详情
     *
     * @param attachmentId 附件ID
     * @return 附件详情
     */
    @Override
    public SysTaskAttachment getAttachmentById(Long attachmentId) {
        SysTaskAttachment attachment = sysTaskAttachmentMapper.selectSysTaskAttachmentByAttachmentId(attachmentId);
        if (attachment != null) {
            // 拼接完整URL
            buildAttachmentUrl(attachment);
        }
        return attachment;
    }
    @Override
    public List<SysTaskAttachment> getAttachmentsByTaskId(Long taskId) {
        return sysTaskAttachmentMapper.selectSysTaskAttachmentByTaskId(taskId);
    }
    /**
@@ -694,6 +872,7 @@
            VehicleInfo queryParam = new VehicleInfo();
            queryParam.setStatus("0"); // 0表示正常状态
            // 不设置deptId,查询所有部门的车辆
            queryParam.setDeptId(deptId);
            
            List<VehicleInfo> vehicles = vehicleInfoMapper.selectVehicleInfoList(queryParam);
            
@@ -760,7 +939,12 @@
            // 查询关联车辆
            task.setAssignedVehicles(sysTaskVehicleMapper.selectSysTaskVehicleByTaskId(taskId));
            // 查询附件
            task.setAttachments(sysTaskAttachmentMapper.selectSysTaskAttachmentByTaskId(taskId));
            List<SysTaskAttachment> attachments = sysTaskAttachmentMapper.selectSysTaskAttachmentByTaskId(taskId);
            // 为每个附件拼接完整URL
            if (attachments != null && !attachments.isEmpty()) {
                attachments.forEach(this::buildAttachmentUrl);
            }
            task.setAttachments(attachments);
            // 查询操作日志
            task.setOperationLogs(sysTaskLogMapper.selectSysTaskLogByTaskId(taskId));
            // 加载急救转运扩展信息
@@ -1054,4 +1238,45 @@
        
        sysTaskWelfareMapper.insertSysTaskWelfare(welfareInfo);
    }
    /**
     * 获取附件分类描述
     *
     * @param category 附件分类代码
     * @return 分类描述
     */
    private 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 "其他";
        }
    }
    /**
     * 构建附件的完整URL
     *
     * @param attachment 附件对象
     */
    private void buildAttachmentUrl(SysTaskAttachment attachment) {
        if (attachment != null && StringUtils.isNotEmpty(attachment.getFilePath())) {
            String imageUrl = imageUrlConfig.getImageUrl();
            if (StringUtils.isNotEmpty(imageUrl)) {
                // 拼接完整URL:域名 + 相对路径
                attachment.setFileUrl(imageUrl + attachment.getFilePath());
            } else {
                // 如果未配置域名,直接使用相对路径
                attachment.setFileUrl(attachment.getFilePath());
            }
        }
    }
}