吉安感知网项目-后端
linwei
2026-04-14 70b4182fb75db9a5acd234a0ab4c22fd8f93de92
fix: 成果下载+成果列表+飞手查询所有
12 files modified
1 files added
304 ■■■■■ changed files
drone-service/drone-gd/src/main/java/org/sxkj/gd/flyer/mapper/GdFlyerMapper.xml 13 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/flyer/vo/GdFlyerVO.java 6 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/controller/GdPatrolTaskController.java 15 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/controller/GdTaskResultController.java 12 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/mapper/GdPatrolTaskMapper.java 9 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/mapper/GdPatrolTaskMapper.xml 9 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/mapper/GdTaskResultMapper.xml 68 ●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/service/IGdPatrolTaskService.java 9 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/service/IGdTaskResultService.java 10 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/service/impl/GdPatrolTaskServiceImpl.java 6 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/service/impl/GdTaskResultServiceImpl.java 89 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/vo/GdPatrolTaskSimpleVO.java 49 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/vo/GdTaskResultVO.java 9 ●●●●● patch | view | raw | blame | history
drone-service/drone-gd/src/main/java/org/sxkj/gd/flyer/mapper/GdFlyerMapper.xml
@@ -37,11 +37,17 @@
        <result column="area_code" property="areaCode"/>
        <result column="flyer_address" property="flyerAddress"/>
        <result column="certification" property="certification" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
        <result column="area_match_flag" property="areaMatchFlag"/>
    </resultMap>
    <select id="selectGdFlyerPage" resultMap="gdFlyerVOResultMap">
        select
            *
            *,
            CASE
                WHEN #{param2.areaCode} IS NOT NULL AND #{param2.areaCode} != ''
                     AND area_code LIKE concat('%',#{param2.areaCode},'%') THEN 1
                ELSE 0
            END as area_match_flag
        from
            ja_gd_flyer
        <where>
@@ -61,10 +67,6 @@
            <if test="param2.skilledTaskType != null and param2.skilledTaskType != ''">
                and skilled_task_type = #{param2.skilledTaskType}
            </if>
            <if test="param2.areaCode != null and param2.areaCode != ''">
                and area_code like concat('%',#{param2.areaCode},'%')
            </if>
            <!-- <if test="param2.deptList != null and param2.deptList.size > 0"> -->
            <!--     AND create_dept in -->
            <!--     <foreach collection="param2.deptList" item="deptId" open="(" separator="," close=")"> -->
@@ -72,6 +74,7 @@
            <!--     </foreach> -->
            <!-- </if> -->
        </where>
        ORDER BY area_match_flag DESC, create_time DESC
    </select>
drone-service/drone-gd/src/main/java/org/sxkj/gd/flyer/vo/GdFlyerVO.java
@@ -91,4 +91,10 @@
     */
    @ApiModelProperty(value = "飞手资质证书地址列表")
    private List<String> certification;
    /**
     * 区域匹配标识(0:未匹配 1:匹配)
     */
    @ApiModelProperty(value = "区域匹配标识(0:未匹配 1:匹配)")
    private Integer areaMatchFlag;
}
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/controller/GdPatrolTaskController.java
@@ -42,6 +42,7 @@
import org.sxkj.gd.workorder.param.GdPatrolTaskAuditParam;
import org.sxkj.gd.workorder.param.GdPatrolTaskPageParam;
import org.sxkj.gd.workorder.param.GdPatrolTaskUpdateParam;
import org.sxkj.gd.workorder.vo.GdPatrolTaskSimpleVO;
import org.sxkj.gd.workorder.vo.GdPatrolTaskVO;
import org.sxkj.gd.workorder.excel.GdPatrolTaskExcel;
import org.sxkj.gd.workorder.wrapper.GdPatrolTaskWrapper;
@@ -221,4 +222,18 @@
        return R.data(cacheData);
    }
    /**
     * 根据工单ID查询巡查任务列表(仅返回id和名称)
     */
    @GetMapping("/listByWorkOrderId")
    @ApiOperationSupport(order = 17)
    @ApiOperation(value = "根据工单ID查询巡查任务列表", notes = "传入工单ID")
    public R<List<GdPatrolTaskSimpleVO>> listByWorkOrderId(@ApiParam(value = "工单ID", required = true) @RequestParam Long workOrderId) {
        if (workOrderId == null) {
            return R.fail("工单ID不能为空");
        }
        List<GdPatrolTaskSimpleVO> list = gdPatrolTaskService.selectListByWorkOrderId(workOrderId);
        return R.data(list);
    }
}
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/controller/GdTaskResultController.java
@@ -152,7 +152,7 @@
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "逻辑删除", notes = "传入ids")
    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        return R.status(gdTaskResultService.deleteLogic(Func.toLongList(ids)));
        return R.status(gdTaskResultService.removeBatchByIds(Func.toLongList(ids)));
    }
    /**
@@ -181,4 +181,14 @@
        ExcelUtil.export(response, "成果表数据" + DateUtil.time(), "成果表数据表", list, GdTaskResultExcel.class);
    }
    /**
     * 批量下载成果文件
     */
    @GetMapping("/download")
    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "批量下载成果文件", notes = "传入成果ID,多个用逗号分隔")
    public void downloadResultFiles(@ApiParam(value = "成果ID集合,多个用逗号分隔", required = true) @RequestParam String ids, HttpServletResponse response) {
        gdTaskResultService.downloadResultFiles(ids, response);
    }
}
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/mapper/GdPatrolTaskMapper.java
@@ -19,6 +19,7 @@
import org.sxkj.gd.workorder.entity.GdPatrolTaskEntity;
import org.sxkj.gd.workorder.entity.GdWorkOrderEntity;
import org.sxkj.gd.workorder.param.GdPatrolTaskPageParam;
import org.sxkj.gd.workorder.vo.GdPatrolTaskSimpleVO;
import org.sxkj.gd.workorder.vo.GdPatrolTaskVO;
import org.sxkj.gd.workorder.excel.GdPatrolTaskExcel;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@@ -82,4 +83,12 @@
     * @return
     */
    GdWorkOrderEntity getWorkOrderIdById(Long id, String code);
    /**
     * 根据工单ID查询巡查任务列表(仅id和名称)
     *
     * @param workOrderId 工单ID
     * @return 巡查任务列表
     */
    List<GdPatrolTaskSimpleVO> selectListByWorkOrderId(@Param("workOrderId") Long workOrderId);
}
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/mapper/GdPatrolTaskMapper.xml
@@ -143,4 +143,13 @@
        WHERE id = #{workOrderParam.id}
    </update>
    <!-- 根据工单ID查询巡查任务列表(仅id和名称) -->
    <select id="selectListByWorkOrderId" resultType="org.sxkj.gd.workorder.vo.GdPatrolTaskSimpleVO">
        SELECT id, patrol_task_name AS patrolTaskName
        FROM ja_gd_patrol_task
        WHERE is_deleted = 0
        AND work_order_id = #{workOrderId}::bigint
        ORDER BY create_time DESC
    </select>
</mapper>
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/mapper/GdTaskResultMapper.xml
@@ -23,6 +23,7 @@
        <result column="is_deleted" property="isDeleted"/>
        <result column="distribute_user_name" property="distributeUserName"/>
        <result column="distribute_dept_name" property="distributeDeptName"/>
        <result column="patrol_task_name" property="patrolTaskName"/>
    </resultMap>
    <resultMap id="gdTaskResultExcelResultMap" type="org.sxkj.gd.workorder.excel.GdTaskResultExcel">
@@ -40,24 +41,61 @@
    <select id="selectGdTaskResultPage" resultMap="gdTaskResultResultMap">
        select * from ja_gd_task_result where is_deleted = 0
        SELECT tr.*, pt.patrol_task_name FROM ja_gd_task_result tr
        INNER JOIN ja_gd_patrol_task pt ON pt.id = tr.patrol_task_id AND pt.is_deleted = 0
        <if test="gdTaskResult.workOrderId != null">
            INNER JOIN ja_gd_work_order wo ON wo.id = pt.work_order_id AND wo.is_deleted = 0
        </if>
        WHERE tr.is_deleted = 0
        <if test="gdTaskResult.workOrderId != null">
            AND wo.id = #{gdTaskResult.workOrderId}
        </if>
        <if test="gdTaskResult.patrolTaskId != null">
            AND tr.patrol_task_id = #{gdTaskResult.patrolTaskId}
        </if>
        <if test="gdTaskResult.patrolTaskName != null and gdTaskResult.patrolTaskName != ''">
            AND pt.patrol_task_name LIKE concat('%', #{gdTaskResult.patrolTaskName}, '%')
        </if>
        <if test="gdTaskResult.resultCode != null and gdTaskResult.resultCode != ''">
            AND tr.result_code LIKE concat('%', #{gdTaskResult.resultCode}, '%')
        </if>
        <if test="gdTaskResult.distributeStatus != null">
            AND tr.distribute_status = #{gdTaskResult.distributeStatus}
        </if>
        <if test="gdTaskResult.areaCode != null and gdTaskResult.areaCode != ''">
            AND tr.area_code = #{gdTaskResult.areaCode}
        </if>
        <if test="gdTaskResult.createDept != null">
            AND tr.create_dept = #{gdTaskResult.createDept}
        </if>
        <if test="gdTaskResult.createUser != null">
            AND tr.create_user = #{gdTaskResult.createUser}
        </if>
        ORDER BY tr.create_time DESC
    </select>
    <select id="selectGdTaskResultListByPatrolTaskId" resultMap="gdTaskResultResultMap">
        SELECT tr.*,
               COALESCE(bu.real_name, bu.name) as distribute_user_name,
               bd.dept_name                  as distribute_dept_name
        FROM ja_gd_task_result tr
                 LEFT JOIN (SELECT *
                            FROM ja_gd_clue_event ce1
                            WHERE ce1.is_deleted = 0
                              AND ce1.create_time = (SELECT MAX(create_time)
                                                     FROM ja_gd_clue_event ce2
                                                     WHERE ce2.result_id::VARCHAR = ce1.result_id::VARCHAR
                                                       AND ce2.is_deleted = 0)) ce ON ce.result_id::VARCHAR = tr.id::VARCHAR
                 LEFT JOIN blade_user bu ON bu.id::VARCHAR = ce.create_user::VARCHAR AND bu.is_deleted = 0
                 LEFT JOIN blade_dept bd ON bd.id::VARCHAR = ce.create_dept::VARCHAR AND bd.is_deleted = 0
        WHERE tr.is_deleted = 0
        SELECT
            tr.*,
            COALESCE ( bu.real_name, bu.NAME ) AS distribute_user_name,
            bd.dept_name AS distribute_dept_name
        FROM
            ja_gd_task_result tr
            LEFT JOIN (
                SELECT
                    *
                FROM
                    ja_gd_clue_event ce1
                WHERE
                    ce1.is_deleted = 0
                  AND ce1.create_time = ( SELECT MAX( create_time ) FROM ja_gd_clue_event ce2 WHERE ce2.result_id :: VARCHAR = ce1.result_id :: VARCHAR AND ce2.is_deleted = 0 )
                ) ce ON ce.result_id :: VARCHAR = tr.id :: VARCHAR
            LEFT JOIN blade_user bu ON bu.id :: VARCHAR = ce.create_user :: VARCHAR
            AND bu.is_deleted = 0
            LEFT JOIN blade_dept bd ON bd.id :: VARCHAR = ce.create_dept :: VARCHAR
            AND bd.is_deleted = 0
        WHERE
            tr.is_deleted = 0
          AND tr.patrol_task_id = #{patrolTaskId}
    </select>
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/service/IGdPatrolTaskService.java
@@ -24,6 +24,7 @@
import org.sxkj.gd.workorder.excel.GdPatrolTaskExcel;
import org.sxkj.gd.workorder.param.GdPatrolTaskAuditParam;
import org.sxkj.gd.workorder.param.GdPatrolTaskPageParam;
import org.sxkj.gd.workorder.vo.GdPatrolTaskSimpleVO;
import org.sxkj.gd.workorder.vo.GdPatrolTaskVO;
import java.util.List;
@@ -103,4 +104,12 @@
     * @return
     */
    boolean updatePatrolTaskById(GdPatrolTaskEntity auditParam);
    /**
     * 根据工单ID查询巡查任务列表(仅id和名称)
     *
     * @param workOrderId 工单ID
     * @return 巡查任务列表
     */
    List<GdPatrolTaskSimpleVO> selectListByWorkOrderId(Long workOrderId);
}
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/service/IGdTaskResultService.java
@@ -22,6 +22,8 @@
import org.sxkj.gd.workorder.excel.GdTaskResultExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseService;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
@@ -65,4 +67,12 @@
     * @return 是否成功
     */
    boolean updateTaskResultById(GdTaskResultEntity taskResult);
    /**
     * 批量下载成果文件(打包成ZIP)
     *
     * @param ids      成果ID列表(逗号分隔)
     * @param response HTTP响应
     */
    void downloadResultFiles(String ids, HttpServletResponse response);
}
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/service/impl/GdPatrolTaskServiceImpl.java
@@ -54,6 +54,7 @@
import org.sxkj.gd.workorder.service.IGdTaskResultService;
import org.sxkj.gd.workorder.service.IGdWorkOrderFlowService;
import org.sxkj.gd.workorder.utils.GdPatrolReportWordUtil;
import org.sxkj.gd.workorder.vo.GdPatrolTaskSimpleVO;
import org.sxkj.gd.workorder.vo.GdPatrolTaskVO;
import org.sxkj.gd.xingtu.JianXingtuApiService;
import org.sxkj.resource.entity.Attach;
@@ -730,4 +731,9 @@
        return updateResult;
    }
    @Override
    public List<GdPatrolTaskSimpleVO> selectListByWorkOrderId(Long workOrderId) {
        return baseMapper.selectListByWorkOrderId(workOrderId);
    }
}
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/service/impl/GdTaskResultServiceImpl.java
@@ -26,7 +26,16 @@
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.utils.Func;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
 * 成果表 服务实现类
@@ -104,4 +113,84 @@
        return result;
    }
    @Override
    public void downloadResultFiles(String ids, HttpServletResponse response) {
        // 根据ID列表查询成果记录
        List<Long> idList = Func.toLongList(ids);
        List<GdTaskResultEntity> resultList = listByIds(idList);
        if (resultList == null || resultList.isEmpty()) {
            throw new RuntimeException("未找到成果数据");
        }
        // 设置响应头
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=result_files.zip");
        try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
            for (GdTaskResultEntity result : resultList) {
                String resultUrl = result.getResultUrl();
                if (resultUrl == null || resultUrl.isEmpty()) {
                    continue;
                }
                // 处理转义字符
                resultUrl = unescapeUrl(resultUrl);
                try {
                    // 从URL下载文件
                    URL url = new URL(resultUrl);
                    URLConnection connection = url.openConnection();
                    connection.setConnectTimeout(5000);
                    connection.setReadTimeout(10000);
                    // 从URL中提取文件名
                    String fileName = extractFileName(resultUrl, result.getId());
                    // 添加到ZIP
                    ZipEntry zipEntry = new ZipEntry(fileName);
                    zos.putNextEntry(zipEntry);
                    try (InputStream is = connection.getInputStream()) {
                        byte[] buffer = new byte[4096];
                        int len;
                        while ((len = is.read(buffer)) > 0) {
                            zos.write(buffer, 0, len);
                        }
                    }
                    zos.closeEntry();
                } catch (Exception e) {
                    // 单个文件下载失败,继续处理其他文件
                    // 可以记录日志
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("下载文件失败", e);
        }
    }
    /**
     * 从URL中提取文件名
     */
    private String extractFileName(String url, Long resultId) {
        if (url == null || url.isEmpty()) {
            return resultId + "_unknown";
        }
        // 从URL中提取最后一部分作为文件名
        int lastSlash = url.lastIndexOf('/');
        if (lastSlash != -1 && lastSlash < url.length() - 1) {
            String fileName = url.substring(lastSlash + 1);
            // 处理可能的查询参数
            int questionMark = fileName.indexOf('?');
            if (questionMark != -1) {
                fileName = fileName.substring(0, questionMark);
            }
            return resultId + "_" + fileName;
        }
        return resultId + "_file";
    }
}
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/vo/GdPatrolTaskSimpleVO.java
New file
@@ -0,0 +1,49 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.sxkj.gd.workorder.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
 * 巡查任务简单VO(用于下拉列表)
 *
 * @author lw
 * @since 2026-04-14
 */
@Data
public class GdPatrolTaskSimpleVO implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 主键ID
     */
    @ApiModelProperty("主键ID")
    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;
    /**
     * 巡查任务名称
     */
    @ApiModelProperty("巡查任务名称")
    private String patrolTaskName;
}
drone-service/drone-gd/src/main/java/org/sxkj/gd/workorder/vo/GdTaskResultVO.java
@@ -37,6 +37,11 @@
    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;
    /**
     * 关联工单任务表ID
     */
    @ApiModelProperty(value = "关联工单任务表ID")
    private Long workOrderId;
    /**
     * 关联巡查任务表ID
     */
@@ -110,4 +115,8 @@
    @ApiModelProperty(value = "逻辑删除")
    private Integer isDeleted;
    // patrol_task_name
    @ApiModelProperty(value = "巡查任务名称")
    private String patrolTaskName;
}