wangrong
9 天以前 fb0e22c8f74ed0e3c337afa60075579a151b53eb
修复车辆行驶数据汇总统计report
1个文件已修改
54 ■■■■■ 已修改文件
src/modules/report/service/taskservicevehicle.ts 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/report/service/taskservicevehicle.ts
@@ -28,12 +28,13 @@
        let THRESHOLD_MOVING = parseInt(await this.baseSysParamService.dataByKey('vehicle.speed.threshold.moving')); //'2.0 km/h';
        let THRESHOLD_SPEEDING = parseInt(await this.baseSysParamService.dataByKey('vehicle.speed.threshold.speeding')); //'30 km/h';
        let THRESHOLD_DISPLACEMENT = parseInt(await this.baseSysParamService.dataByKey('vehicle.threshold.displacement')); //'30 km/h';
        let VEHICLE_GPS_MAX_INTERVAL_SEC = parseInt(await this.baseSysParamService.dataByKey('vehicle.gps.max.interval.sec')); //'900';
        HOUR_STARTWORK = Number.isNaN(HOUR_STARTWORK) ? 6 : HOUR_STARTWORK;
        HOUR_OFFWORK = Number.isNaN(HOUR_OFFWORK) ? 22 : HOUR_OFFWORK;
        THRESHOLD_MOVING = Number.isNaN(THRESHOLD_MOVING) ? 2 : THRESHOLD_MOVING;
        THRESHOLD_SPEEDING = Number.isNaN(THRESHOLD_SPEEDING) ? 30 : THRESHOLD_SPEEDING;
        THRESHOLD_DISPLACEMENT = Number.isNaN(THRESHOLD_DISPLACEMENT) ? 10 : THRESHOLD_DISPLACEMENT;
        VEHICLE_GPS_MAX_INTERVAL_SEC = Number.isNaN(VEHICLE_GPS_MAX_INTERVAL_SEC) ? 900 : VEHICLE_GPS_MAX_INTERVAL_SEC;
        const rawGpsList = await this.pushVehicleGpsEntity.createQueryBuilder('gps')
@@ -87,7 +88,8 @@
                HOUR_OFFWORK,
                THRESHOLD_MOVING,
                THRESHOLD_SPEEDING,
                THRESHOLD_DISPLACEMENT
                THRESHOLD_DISPLACEMENT,
                VEHICLE_GPS_MAX_INTERVAL_SEC
            );
            summariesToUpsert.push(summary);
        }
@@ -112,7 +114,8 @@
        HOUR_OFFWORK: number,
        HHRESHOLD_MOVING: number,
        THRESHOLD_SPEEDING: number,
        THRESHOLD_DISPLACEMENT: number
        THRESHOLD_DISPLACEMENT: number,
        VEHICLE_GPS_MAX_INTERVAL_SEC: number
    ): Partial<ReportDailyVehicleEntity> {
        const departmentId = points[0]?.departmentId ?? null;
@@ -131,11 +134,14 @@
        let offHoursMoveCount = 0; // 非工作时段异动次数
        let isOverspeeding = false; // 超速状态标记
        // 物理量只在「上一有效坐标点」与当前有效点之间计算,空坐标不参与
        let lastValidIdx = -1;
        for (let i = 0; i < points.length; i++) {
            const curr = points[i];
            const speed = Number(curr.speed) || 0;
            const currDate = new Date(curr.gpsTime);
            const currValid = this.isValidGpsPoint(curr);
            // ====================================================
            // 顺序 1:单点状态判断(只依赖当前点的数据)
@@ -159,18 +165,23 @@
            }
            // ====================================================
            // 顺序 2:相邻点微分与物理量计算(必须依赖前一点 i-1)
            // 顺序 2:相邻有效点微分与物理量计算
            // ====================================================
            if (i > 0) {
                const prev = points[i - 1];
            if (!currValid) {
                continue;
            }
            if (lastValidIdx >= 0) {
                const prev = points[lastValidIdx];
                const prevDate = new Date(prev.gpsTime);
                // 计算相邻两点时间差(秒)
                const timeDiffSec = Math.floor((currDate.getTime() - prevDate.getTime()) / 1000);
                // 过滤网络断连/关机(时间差 > 120 秒 视为掉线,不参与物理微分计算)
                if (timeDiffSec > 0 && timeDiffSec <= 120) {
                // 3.4 静止停靠达到 15 分钟(900秒)算作异常怠速
                if (timeDiffSec >= 900) {
                    secondsAbnormalIdle += timeDiffSec;
                }
                // 超过配置间隔视为掉线,不参与物理微分计算
                if (timeDiffSec > 0 && timeDiffSec <= VEHICLE_GPS_MAX_INTERVAL_SEC) {
                    // ================================================
                    // 顺序 3:基于坐标位移划分为【行驶】或【静止停靠】
                    // ================================================
@@ -185,20 +196,10 @@
                        secondsMoving += timeDiffSec;
                        // 3.2 累加球面真实位移距离
                        totalMeter += this.getHaversineDistance(
                            Number(prev.latitude),
                            Number(prev.longitude),
                            Number(curr.latitude),
                            Number(curr.longitude),
                        );
                        totalMeter += distance;
                    } else {
                        // 3.3 累加静止停靠时长
                        secondsParked += timeDiffSec;
                        // 3.4 静止停靠超过 15 分钟(900秒)算作异常怠速
                        if (timeDiffSec > 900) {
                            secondsAbnormalIdle += timeDiffSec;
                        }
                    }
                    // ================================================
@@ -227,6 +228,7 @@
                    }
                }
            }
            lastValidIdx = i;
        }
        // ====================================================
@@ -296,6 +298,16 @@
    }
    /** 经纬度缺失、非数字或 (0,0) 不参与里程/时长 */
    private isValidGpsPoint(point: { latitude?: any; longitude?: any }): boolean {
        const lat = Number(point?.latitude);
        const lon = Number(point?.longitude);
        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return false;
        if (lat === 0 && lon === 0) return false;
        if (Math.abs(lat) > 90 || Math.abs(lon) > 180) return false;
        return true;
    }
    /**
     * 纯 JS 原生计算两点之间的球面距离 (单位: 米)
     */