Ver código fonte

APP端-首页-消息推送

chenshudong 2 semanas atrás
pai
commit
6758d3423b

+ 73 - 0
airport-admin/src/main/java/com/sundot/airport/web/controller/item/SeizureMessagePushController.java

@@ -0,0 +1,73 @@
1
+package com.sundot.airport.web.controller.item;
2
+
3
+import com.sundot.airport.common.core.controller.BaseController;
4
+import com.sundot.airport.common.core.domain.AjaxResult;
5
+import com.sundot.airport.common.core.domain.model.LoginUser;
6
+import com.sundot.airport.common.utils.DateUtils;
7
+import com.sundot.airport.common.utils.SecurityUtils;
8
+import com.sundot.airport.item.domain.push.SeizureMessagePushDTO;
9
+import com.sundot.airport.item.service.ISeizureMessagePushService;
10
+import io.swagger.annotations.Api;
11
+import io.swagger.annotations.ApiOperation;
12
+import lombok.extern.slf4j.Slf4j;
13
+import org.springframework.beans.factory.annotation.Autowired;
14
+import org.springframework.web.bind.annotation.GetMapping;
15
+import org.springframework.web.bind.annotation.RequestMapping;
16
+import org.springframework.web.bind.annotation.RequestParam;
17
+import org.springframework.web.bind.annotation.RestController;
18
+
19
+import java.util.Date;
20
+
21
+/**
22
+ * 查获消息推送 Controller
23
+ *
24
+ * @author wangxx
25
+ * @date 2026-03-31
26
+ */
27
+@Slf4j
28
+@RestController
29
+@RequestMapping("/item/seizure/push")
30
+@Api(tags = "查获消息推送")
31
+public class SeizureMessagePushController extends BaseController {
32
+
33
+    @Autowired
34
+    private ISeizureMessagePushService seizureMessagePushService;
35
+
36
+    /**
37
+     * 获取查获消息推送数据
38
+     *
39
+     * @param startDate 开始日期(可选,格式:yyyy-MM-dd)
40
+     * @param endDate   结束日期(可选,格式:yyyy-MM-dd)
41
+     * @return 查获消息推送数据
42
+     */
43
+    @ApiOperation("获取查获消息推送数据")
44
+    @GetMapping("/message")
45
+    public AjaxResult getMessagePushData(@RequestParam(required = false) String startDate,
46
+                                         @RequestParam(required = false) String endDate) {
47
+        try {
48
+            LoginUser loginUser = SecurityUtils.getLoginUser();
49
+            Long userId = loginUser.getUserId();
50
+            Long deptId = loginUser.getDeptId();
51
+
52
+            Date startDateTime;
53
+            Date endDateTime;
54
+
55
+            if (startDate == null || endDate == null) {
56
+                // 默认近 15 天(不包含今天)
57
+                endDateTime = DateUtils.addDays(new Date(), -1);
58
+                startDateTime = DateUtils.addDays(endDateTime, -14);
59
+            } else {
60
+                startDateTime = DateUtils.parseDate(startDate);
61
+                endDateTime = DateUtils.parseDate(endDate);
62
+            }
63
+
64
+            SeizureMessagePushDTO result = seizureMessagePushService.getSeizureMessagePushData(
65
+                    userId, deptId, startDateTime, endDateTime);
66
+
67
+            return AjaxResult.success(result);
68
+        } catch (Exception e) {
69
+            log.error("获取查获消息推送数据失败,error: ", e);
70
+            return AjaxResult.error("获取查获消息推送数据失败:" + e.getMessage());
71
+        }
72
+    }
73
+}

+ 19 - 0
airport-attendance/src/main/java/com/sundot/airport/attendance/calculator/AttendancePersonCountCalculator.java

@@ -2,10 +2,13 @@ package com.sundot.airport.attendance.calculator;
2 2
 
3 3
 import com.sundot.airport.attendance.domain.AttendanceRecord;
4 4
 import com.sundot.airport.attendance.mapper.AttendanceRecordMapper;
5
+import com.sundot.airport.common.core.domain.entity.SysDept;
6
+import com.sundot.airport.common.enums.DeptTypeEnum;
5 7
 import com.sundot.airport.common.enums.IndicatorTypeEnum;
6 8
 import com.sundot.airport.common.statistics.AbstractIndicatorCalculator;
7 9
 import com.sundot.airport.common.statistics.IndicatorCalculationParams;
8 10
 import com.sundot.airport.common.statistics.TimeDimensionProcessor;
11
+import com.sundot.airport.system.mapper.SysDeptMapper;
9 12
 import org.springframework.beans.factory.annotation.Autowired;
10 13
 import org.springframework.stereotype.Component;
11 14
 
@@ -25,6 +28,9 @@ public class AttendancePersonCountCalculator extends AbstractIndicatorCalculator
25 28
     @Autowired
26 29
     private TimeDimensionProcessor timeDimensionProcessor;
27 30
 
31
+    @Autowired
32
+    private SysDeptMapper sysDeptMapper;
33
+
28 34
     @Override
29 35
     public BigDecimal calculate(IndicatorCalculationParams params) {
30 36
         // 确保时间范围已计算
@@ -34,6 +40,19 @@ public class AttendancePersonCountCalculator extends AbstractIndicatorCalculator
34 40
         AttendanceRecord record = new AttendanceRecord();
35 41
         record.setAttendanceDateStart(params.getStartTime());
36 42
         record.setAttendanceDateEnd(params.getEndTime());
43
+        if (params.getDeptId() != null) {
44
+            // 按部门统计(大队、科室、班组等)
45
+            SysDept sysDept = sysDeptMapper.selectDeptById(params.getDeptId());
46
+            if (DeptTypeEnum.TEAMS.getCode().equals(sysDept.getDeptType())) {
47
+                record.setTeamCode(params.getDeptId().toString());
48
+            } else if (DeptTypeEnum.MANAGER.getCode().equals(sysDept.getDeptType())) {
49
+                record.setDepartmentCode(params.getDeptId().toString());
50
+            } else if (DeptTypeEnum.BRIGADE.getCode().equals(sysDept.getDeptType())) {
51
+                record.setBrigadeCode(params.getDeptId().toString());
52
+            } else if (DeptTypeEnum.STATION.getCode().equals(sysDept.getDeptType())) {
53
+                record.setStationCode(params.getDeptId().toString());
54
+            }
55
+        }
37 56
 
38 57
         // 查询考勤记录
39 58
         List<AttendanceRecord> records = attendanceRecordMapper.selectAttendanceRecordList(record);

+ 110 - 0
airport-item/src/main/java/com/sundot/airport/item/domain/push/SeizureMessagePushDTO.java

@@ -0,0 +1,110 @@
1
+package com.sundot.airport.item.domain.push;
2
+
3
+import io.swagger.annotations.ApiModel;
4
+import io.swagger.annotations.ApiModelProperty;
5
+import lombok.Data;
6
+
7
+import java.math.BigDecimal;
8
+import java.util.List;
9
+
10
+/**
11
+ * 查获消息推送数据传输对象
12
+ * 用于向登录用户推送其名下的全站查获信息
13
+ */
14
+@Data
15
+@ApiModel(value = "SeizureMessagePushDTO", description = "查获消息推送数据")
16
+public class SeizureMessagePushDTO {
17
+
18
+    /**
19
+     * 移交公安违禁品 TOP3
20
+     */
21
+    @ApiModelProperty("移交公安违禁品 TOP3")
22
+    private List<ProhibitedItemTop3> prohibitedItemsTop3;
23
+
24
+    /**
25
+     * 故意隐匿物品藏匿部位 TOP3
26
+     */
27
+    @ApiModelProperty("故意隐匿物品藏匿部位 TOP3")
28
+    private List<ConcealmentPositionTop3> concealmentPositionsTop3;
29
+
30
+    /**
31
+     * 移交公安违禁品高发通道 TOP3
32
+     */
33
+    @ApiModelProperty("移交公安违禁品高发通道 TOP3")
34
+    private List<HighRiskChannelTop3> highRiskChannelsTop3;
35
+
36
+    /**
37
+     * 移交公安违禁品 TOP3
38
+     */
39
+    @Data
40
+    @ApiModel(value = "ProhibitedItemTop3", description = "移交公安违禁品 TOP3")
41
+    public static class ProhibitedItemTop3 {
42
+
43
+        @ApiModelProperty("排名")
44
+        private Integer rank;
45
+
46
+        @ApiModelProperty("违禁品一级分类编码")
47
+        private String categoryCodeOne;
48
+
49
+        @ApiModelProperty("违禁品一级分类名称")
50
+        private String categoryNameOne;
51
+
52
+        @ApiModelProperty("违禁品二级分类编码")
53
+        private String categoryCodeTwo;
54
+
55
+        @ApiModelProperty("违禁品二级分类名称")
56
+        private String categoryNameTwo;
57
+
58
+        @ApiModelProperty("查获数量")
59
+        private BigDecimal seizureCount;
60
+    }
61
+
62
+    /**
63
+     * 故意隐匿物品藏匿部位 TOP3
64
+     */
65
+    @Data
66
+    @ApiModel(value = "ConcealmentPositionTop3", description = "故意隐匿物品藏匿部位 TOP3")
67
+    public static class ConcealmentPositionTop3 {
68
+
69
+        @ApiModelProperty("排名")
70
+        private Integer rank;
71
+
72
+        @ApiModelProperty("藏匿部位一级分类编码")
73
+        private String positionCodeOne;
74
+
75
+        @ApiModelProperty("藏匿部位一级分类名称")
76
+        private String positionNameOne;
77
+
78
+        @ApiModelProperty("藏匿部位二级分类编码")
79
+        private String positionCodeTwo;
80
+
81
+        @ApiModelProperty("藏匿部位二级分类名称")
82
+        private String positionNameTwo;
83
+
84
+        @ApiModelProperty("隐匿次数")
85
+        private BigDecimal concealmentCount;
86
+    }
87
+
88
+    /**
89
+     * 移交公安违禁品高发通道 TOP3
90
+     */
91
+    @Data
92
+    @ApiModel(value = "HighRiskChannelTop3", description = "移交公安违禁品高发通道 TOP3")
93
+    public static class HighRiskChannelTop3 {
94
+
95
+        @ApiModelProperty("排名")
96
+        private Integer rank;
97
+
98
+        @ApiModelProperty("航站楼")
99
+        private String terminalName;
100
+
101
+        @ApiModelProperty("区域")
102
+        private String areaName;
103
+
104
+        @ApiModelProperty("具体通道名称")
105
+        private String channelName;
106
+
107
+        @ApiModelProperty("移交公安数")
108
+        private BigDecimal transferToPoliceCount;
109
+    }
110
+}

+ 26 - 0
airport-item/src/main/java/com/sundot/airport/item/mapper/ItemLargeScreenMapper.java

@@ -5,6 +5,7 @@ import com.sundot.airport.common.core.domain.SysUsageReportSeizureDto;
5 5
 import com.sundot.airport.item.domain.*;
6 6
 import com.sundot.airport.item.domain.dto.ConcealmentPositionTop1DTO;
7 7
 import com.sundot.airport.item.domain.dto.ProhibitedItemsTop3DTO;
8
+import com.sundot.airport.item.domain.push.SeizureMessagePushDTO;
8 9
 import org.apache.ibatis.annotations.Param;
9 10
 
10 11
 import java.math.BigDecimal;
@@ -230,4 +231,29 @@ public interface ItemLargeScreenMapper {
230 231
      */
231 232
     List<ItemXRayMissCheckUserStatsDto> xRayMissCheckUserStatsTop3(BaseLargeScreenQueryParamDto dto);
232 233
 
234
+
235
+    /**
236
+     * 查询移交公安违禁品 TOP3
237
+     *
238
+     * @param dto 查询参数
239
+     * @return 移交公安违禁品 TOP3 列表
240
+     */
241
+    List<SeizureMessagePushDTO.ProhibitedItemTop3> selectProhibitedItemsTop3ForPush(BaseLargeScreenQueryParamDto dto);
242
+
243
+    /**
244
+     * 查询故意隐匿物品藏匿部位 TOP3
245
+     *
246
+     * @param dto 查询参数
247
+     * @return 故意隐匿物品藏匿部位 TOP3 列表
248
+     */
249
+    List<SeizureMessagePushDTO.ConcealmentPositionTop3> selectConcealmentPositionsTop3ForPush(BaseLargeScreenQueryParamDto dto);
250
+
251
+    /**
252
+     * 查询移交公安违禁品高发通道 TOP3
253
+     *
254
+     * @param dto 查询参数
255
+     * @return 移交公安违禁品高发通道 TOP3 列表
256
+     */
257
+    List<SeizureMessagePushDTO.HighRiskChannelTop3> selectHighRiskChannelsTop3ForPush(BaseLargeScreenQueryParamDto dto);
258
+
233 259
 }

+ 25 - 0
airport-item/src/main/java/com/sundot/airport/item/service/ISeizureMessagePushService.java

@@ -0,0 +1,25 @@
1
+package com.sundot.airport.item.service;
2
+
3
+import com.sundot.airport.item.domain.push.SeizureMessagePushDTO;
4
+
5
+import java.util.Date;
6
+
7
+/**
8
+ * 查获消息推送服务接口
9
+ *
10
+ * @author wangxx
11
+ * @date 2026-03-31
12
+ */
13
+public interface ISeizureMessagePushService {
14
+
15
+    /**
16
+     * 获取查获消息推送数据
17
+     *
18
+     * @param userId    用户 ID
19
+     * @param deptId    部门 ID
20
+     * @param startDate 开始日期
21
+     * @param endDate   结束日期
22
+     * @return 查获消息推送数据
23
+     */
24
+    SeizureMessagePushDTO getSeizureMessagePushData(Long userId, Long deptId, Date startDate, Date endDate);
25
+}

+ 144 - 0
airport-item/src/main/java/com/sundot/airport/item/service/impl/SeizureMessagePushServiceImpl.java

@@ -0,0 +1,144 @@
1
+package com.sundot.airport.item.service.impl;
2
+
3
+import cn.hutool.core.collection.CollUtil;
4
+import com.sundot.airport.common.core.domain.BaseLargeScreenQueryParamDto;
5
+import com.sundot.airport.common.core.domain.entity.SysDept;
6
+import com.sundot.airport.common.exception.ServiceException;
7
+import com.sundot.airport.item.domain.push.SeizureMessagePushDTO;
8
+import com.sundot.airport.item.mapper.ItemLargeScreenMapper;
9
+import com.sundot.airport.item.service.ISeizureMessagePushService;
10
+import com.sundot.airport.system.service.ISysDeptService;
11
+import lombok.extern.slf4j.Slf4j;
12
+import org.springframework.beans.factory.annotation.Autowired;
13
+import org.springframework.stereotype.Service;
14
+
15
+import java.util.Date;
16
+import java.util.List;
17
+
18
+/**
19
+ * 查获消息推送服务实现类
20
+ *
21
+ * @author wangxx
22
+ * @date 2026-03-31
23
+ */
24
+@Slf4j
25
+@Service
26
+public class SeizureMessagePushServiceImpl implements ISeizureMessagePushService {
27
+
28
+    @Autowired
29
+    private ItemLargeScreenMapper itemLargeScreenMapper;
30
+
31
+    @Autowired
32
+    private ISysDeptService sysDeptService;
33
+
34
+    /**
35
+     * 获取查获消息推送数据
36
+     *
37
+     * @param userId    用户 ID
38
+     * @param deptId    部门 ID
39
+     * @param startDate 开始日期
40
+     * @param endDate   结束日期
41
+     * @return 查获消息推送数据
42
+     */
43
+    @Override
44
+    public SeizureMessagePushDTO getSeizureMessagePushData(Long userId, Long deptId, Date startDate, Date endDate) {
45
+        try {
46
+            // 1. 获取用户所在的站点 ID
47
+            Long stationId = getStationIdByUserId(userId, deptId);
48
+            if (stationId == null) {
49
+                throw new ServiceException("未找到用户所属的站点信息");
50
+            }
51
+
52
+            // 2. 构建查询参数(直接使用站点 ID 查询全站数据)
53
+            BaseLargeScreenQueryParamDto queryDto = new BaseLargeScreenQueryParamDto();
54
+            queryDto.setInspectStationId(stationId);
55
+            queryDto.setStartDate(startDate);
56
+            queryDto.setEndDate(endDate);
57
+
58
+            // 3. 查询移交公安违禁品 TOP3
59
+            List<SeizureMessagePushDTO.ProhibitedItemTop3> prohibitedItemsTop3 = getProhibitedItemsTop3(queryDto);
60
+
61
+            // 4. 查询故意隐匿物品藏匿部位 TOP3
62
+            List<SeizureMessagePushDTO.ConcealmentPositionTop3> concealmentPositionsTop3 = getConcealmentPositionsTop3(queryDto);
63
+
64
+            // 5. 查询移交公安违禁品高发通道 TOP3
65
+            List<SeizureMessagePushDTO.HighRiskChannelTop3> highRiskChannelsTop3 = getHighRiskChannelsTop3(queryDto);
66
+
67
+            // 6. 组装返回结果
68
+            SeizureMessagePushDTO result = new SeizureMessagePushDTO();
69
+            result.setProhibitedItemsTop3(prohibitedItemsTop3);
70
+            result.setConcealmentPositionsTop3(concealmentPositionsTop3);
71
+            result.setHighRiskChannelsTop3(highRiskChannelsTop3);
72
+
73
+            return result;
74
+        } catch (Exception e) {
75
+            log.error("获取查获消息推送数据失败,userId: {}, deptId: {}, error: {}", userId, deptId, e.getMessage());
76
+            throw new ServiceException("获取查获消息推送数据失败:" + e.getMessage());
77
+        }
78
+    }
79
+
80
+    /**
81
+     * 根据用户 ID 获取所在站点 ID
82
+     */
83
+    private Long getStationIdByUserId(Long userId, Long deptId) {
84
+        try {
85
+            // 从当前用户的部门向上查找站点
86
+            SysDept currentDept = sysDeptService.selectDeptById(deptId);
87
+            while (currentDept != null && !"STATION".equals(currentDept.getDeptType())) {
88
+                currentDept = sysDeptService.selectDeptById(currentDept.getParentId());
89
+            }
90
+            return currentDept != null ? currentDept.getDeptId() : null;
91
+        } catch (Exception e) {
92
+            log.error("获取站点 ID 失败,userId: {}, deptId: {}, error: {}", userId, deptId, e.getMessage());
93
+            return null;
94
+        }
95
+    }
96
+
97
+    /**
98
+     * 获取移交公安违禁品 TOP3
99
+     */
100
+    private List<SeizureMessagePushDTO.ProhibitedItemTop3> getProhibitedItemsTop3(BaseLargeScreenQueryParamDto dto) {
101
+        List<SeizureMessagePushDTO.ProhibitedItemTop3> resultList = itemLargeScreenMapper.selectProhibitedItemsTop3ForPush(dto);
102
+
103
+        // 设置排名
104
+        if (CollUtil.isNotEmpty(resultList)) {
105
+            for (int i = 0; i < resultList.size(); i++) {
106
+                resultList.get(i).setRank(i + 1);
107
+            }
108
+        }
109
+
110
+        return resultList;
111
+    }
112
+
113
+    /**
114
+     * 获取故意隐匿物品藏匿部位 TOP3
115
+     */
116
+    private List<SeizureMessagePushDTO.ConcealmentPositionTop3> getConcealmentPositionsTop3(BaseLargeScreenQueryParamDto dto) {
117
+        List<SeizureMessagePushDTO.ConcealmentPositionTop3> resultList = itemLargeScreenMapper.selectConcealmentPositionsTop3ForPush(dto);
118
+
119
+        // 设置排名
120
+        if (CollUtil.isNotEmpty(resultList)) {
121
+            for (int i = 0; i < resultList.size(); i++) {
122
+                resultList.get(i).setRank(i + 1);
123
+            }
124
+        }
125
+
126
+        return resultList;
127
+    }
128
+
129
+    /**
130
+     * 获取移交公安违禁品高发通道 TOP3
131
+     */
132
+    private List<SeizureMessagePushDTO.HighRiskChannelTop3> getHighRiskChannelsTop3(BaseLargeScreenQueryParamDto dto) {
133
+        List<SeizureMessagePushDTO.HighRiskChannelTop3> resultList = itemLargeScreenMapper.selectHighRiskChannelsTop3ForPush(dto);
134
+
135
+        // 设置排名
136
+        if (CollUtil.isNotEmpty(resultList)) {
137
+            for (int i = 0; i < resultList.size(); i++) {
138
+                resultList.get(i).setRank(i + 1);
139
+            }
140
+        }
141
+
142
+        return resultList;
143
+    }
144
+}

+ 108 - 0
airport-item/src/main/resources/mapper/item/ItemLargeScreenMapper.xml

@@ -772,4 +772,112 @@
772 772
         limit 3
773 773
     </select>
774 774
 
775
+    <!-- 查询移交公安违禁品 TOP3(用于消息推送) -->
776
+    <select id="selectProhibitedItemsTop3ForPush"
777
+            resultType="com.sundot.airport.item.domain.push.SeizureMessagePushDTO$ProhibitedItemTop3">
778
+        SELECT
779
+        isi.category_code_one AS categoryCodeOne,
780
+        isi.category_name_one AS categoryNameOne,
781
+        isi.category_code_two AS categoryCodeTwo,
782
+        isi.category_name_two AS categoryNameTwo,
783
+        SUM(isi.quantity) AS seizureCount,
784
+        0 AS rank
785
+        FROM item_seizure_record isr
786
+        LEFT JOIN item_seizure_items isi ON isr.id = isi.record_id
787
+        WHERE isr.process_status = 3
788
+        <if test="inspectStationId != null">
789
+            AND isr.inspect_station_id = #{inspectStationId}
790
+        </if>
791
+        <if test="inspectBrigadeId != null">
792
+            and isr.inspect_brigade_id = #{inspectBrigadeId}
793
+        </if>
794
+        <if test="inspectDepartmentId != null">
795
+            and isr.inspect_department_id = #{inspectDepartmentId}
796
+        </if>
797
+        <if test="inspectTeamId != null">
798
+            and isr.inspect_team_id = #{inspectTeamId}
799
+        </if>
800
+        <if test="startDate != null and endDate != null">
801
+            AND isr.seizure_time &gt;= #{startDate}
802
+            AND isr.seizure_time &lt; date_add(#{endDate}, interval 1 day)
803
+        </if>
804
+        AND isi.handling_method = 'TRANSFER_TO_AIRPORT_POLICE'
805
+        GROUP BY isi.category_code_one, isi.category_name_one, isi.category_code_two, isi.category_name_two
806
+        ORDER BY seizureCount DESC
807
+        LIMIT 3
808
+    </select>
809
+
810
+    <!-- 查询故意隐匿物品藏匿部位 TOP3(用于消息推送) -->
811
+    <select id="selectConcealmentPositionsTop3ForPush"
812
+            resultType="com.sundot.airport.item.domain.push.SeizureMessagePushDTO$ConcealmentPositionTop3">
813
+        SELECT
814
+        isi.check_position_code_one AS positionCodeOne,
815
+        isi.check_position_name_one AS positionNameOne,
816
+        isi.check_position_code_two AS positionCodeTwo,
817
+        isi.check_position_name_two AS positionNameTwo,
818
+        SUM(isi.quantity) AS concealmentCount,
819
+        0 AS rank
820
+        FROM item_seizure_record isr
821
+        LEFT JOIN item_seizure_items isi ON isr.id = isi.record_id
822
+        WHERE isr.process_status = 3
823
+        <if test="inspectStationId != null">
824
+            AND isr.inspect_station_id = #{inspectStationId}
825
+        </if>
826
+        <if test="inspectBrigadeId != null">
827
+            and isr.inspect_brigade_id = #{inspectBrigadeId}
828
+        </if>
829
+        <if test="inspectDepartmentId != null">
830
+            and isr.inspect_department_id = #{inspectDepartmentId}
831
+        </if>
832
+        <if test="inspectTeamId != null">
833
+            and isr.inspect_team_id = #{inspectTeamId}
834
+        </if>
835
+        <if test="startDate != null and endDate != null">
836
+            AND isr.seizure_time &gt;= #{startDate}
837
+            AND isr.seizure_time &lt; date_add(#{endDate}, interval 1 day)
838
+        </if>
839
+        AND isi.is_active_concealment = 1
840
+        GROUP BY isi.check_position_code_one, isi.check_position_name_one, isi.check_position_code_two,
841
+        isi.check_position_name_two
842
+        ORDER BY concealmentCount DESC
843
+        LIMIT 3
844
+    </select>
845
+
846
+    <!-- 查询移交公安违禁品高发通道 TOP3(用于消息推送) -->
847
+    <select id="selectHighRiskChannelsTop3ForPush"
848
+            resultType="com.sundot.airport.item.domain.push.SeizureMessagePushDTO$HighRiskChannelTop3">
849
+        SELECT
850
+        isr.terminl_name AS terminalName,
851
+        isr.regional_name AS areaName,
852
+        isr.channel_name AS channelName,
853
+        SUM(isi.quantity) AS transferToPoliceCount,
854
+        0 AS rank
855
+        FROM item_seizure_record isr
856
+        LEFT JOIN item_seizure_items isi ON isr.id = isi.record_id
857
+        WHERE isr.process_status = 3
858
+        <if test="inspectStationId != null">
859
+            AND isr.inspect_station_id = #{inspectStationId}
860
+        </if>
861
+        <if test="inspectBrigadeId != null">
862
+            and isr.inspect_brigade_id = #{inspectBrigadeId}
863
+        </if>
864
+        <if test="inspectDepartmentId != null">
865
+            and isr.inspect_department_id = #{inspectDepartmentId}
866
+        </if>
867
+        <if test="inspectTeamId != null">
868
+            and isr.inspect_team_id = #{inspectTeamId}
869
+        </if>
870
+        <if test="startDate != null and endDate != null">
871
+            AND isr.seizure_time &gt;= #{startDate}
872
+            AND isr.seizure_time &lt; date_add(#{endDate}, interval 1 day)
873
+        </if>
874
+        AND isi.handling_method = 'TRANSFER_TO_AIRPORT_POLICE'
875
+        AND isr.terminl_name IS NOT NULL
876
+        AND isr.regional_name IS NOT NULL
877
+        AND isr.channel_name IS NOT NULL
878
+        GROUP BY isr.terminl_name, isr.regional_name, isr.channel_name
879
+        ORDER BY transferToPoliceCount DESC
880
+        LIMIT 3
881
+    </select>
882
+
775 883
 </mapper>