开发资产:医废全流程追溯系统
概述
在开发这个场景的过程中,我们沉淀了以下可复用的开发资产:
- Cursor Skill - GPS 轨迹验证规则
- PROMPT 模板 - 蓝牙设备集成逻辑生成
- 实施指南 - 如何快速复现这个场景
这些资产可以帮助快速复用这个场景的开发经验。
1. Cursor Skill:GPS 轨迹验证规则
使用场景
当你需要开发类似的"GPS 轨迹验证/路线验证"场景时,可以使用这个 Skill 让 AI 理解业务规则。
Skill 内容
markdown
# GPS 轨迹验证规则
## 业务场景
医废转运、巡检、配送等场景中,需要验证人员/车辆是否按规定的路线行走,防止违规操作。
## 核心业务规则
### 1. 路线验证规则
**规则一:偏离距离检测**
```typescript
// 计算点到线段的距离
function pointToLineDistance(
point: { lat: number; lng: number },
lineStart: { lat: number; lng: number },
lineEnd: { lat: number; lng: number }
): number {
// 使用 Haversine 公式计算距离(米)
const R = 6371000; // 地球半径(米)
const dLat1 = (lineEnd.lat - lineStart.lat) * Math.PI / 180;
const dLng1 = (lineEnd.lng - lineStart.lng) * Math.PI / 180;
const a = Math.sin(dLat1 / 2) * Math.sin(dLat1 / 2) +
Math.cos(lineStart.lat * Math.PI / 180) *
Math.cos(lineEnd.lat * Math.PI / 180) *
Math.sin(dLng1 / 2) * Math.sin(dLng1 / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = R * c;
return distance;
}
// 计算点到路线的最近距离
function distanceToRoute(
point: { lat: number; lng: number },
route: Array<{ lat: number; lng: number }>
): number {
let minDistance = Infinity;
for (let i = 0; i < route.length - 1; i++) {
const distance = pointToLineDistance(
point,
route[i],
route[i + 1]
);
minDistance = Math.min(minDistance, distance);
}
return minDistance;
}规则二:路线偏离检测
typescript
async function checkRouteDeviation(
trajectory: Array<{ lat: number; lng: number; time: Date }>,
plannedRoute: Array<{ lat: number; lng: number }>,
maxDeviation: number = 50 // 最大允许偏离距离(米)
): Promise<DeviationResult> {
const deviations = [];
for (const point of trajectory) {
const distance = distanceToRoute(point, plannedRoute);
if (distance > maxDeviation) {
deviations.push({
point,
distance,
time: point.time,
severity: distance > 100 ? 'critical' : 'warning'
});
}
}
return {
hasDeviation: deviations.length > 0,
deviations,
maxDeviation: deviations.length > 0
? Math.max(...deviations.map(d => d.distance))
: 0,
shouldAlert: deviations.some(d => d.severity === 'critical')
};
}2. 速度验证规则
规则一:速度合理性检测
typescript
function checkSpeedReasonableness(
trajectory: Array<{ lat: number; lng: number; time: Date }>
): SpeedCheckResult {
const speeds = [];
for (let i = 1; i < trajectory.length; i++) {
const point1 = trajectory[i - 1];
const point2 = trajectory[i];
const distance = calculateDistance(point1, point2);
const time = (point2.time.getTime() - point1.time.getTime()) / 1000; // 秒
if (time > 0) {
const speed = (distance / time) * 3.6; // 转换为 km/h
speeds.push({ speed, time: point2.time });
}
}
// 检查异常速度(步行速度应该在 3-6 km/h)
const abnormalSpeeds = speeds.filter(s => s.speed < 1 || s.speed > 10);
return {
avgSpeed: speeds.reduce((sum, s) => sum + s.speed, 0) / speeds.length,
maxSpeed: Math.max(...speeds.map(s => s.speed)),
minSpeed: Math.min(...speeds.map(s => s.speed)),
hasAbnormalSpeed: abnormalSpeeds.length > 0,
abnormalSpeeds
};
}规则二:轨迹跳跃检测
typescript
function checkTrajectoryJump(
trajectory: Array<{ lat: number; lng: number; time: Date }>
): JumpCheckResult {
const jumps = [];
for (let i = 1; i < trajectory.length; i++) {
const point1 = trajectory[i - 1];
const point2 = trajectory[i];
const distance = calculateDistance(point1, point2);
const time = (point2.time.getTime() - point1.time.getTime()) / 1000; // 秒
// 如果距离超过 100 米且时间少于 10 秒,可能是跳跃
if (distance > 100 && time < 10) {
jumps.push({
from: point1,
to: point2,
distance,
time,
speed: (distance / time) * 3.6 // km/h
});
}
}
return {
hasJump: jumps.length > 0,
jumps,
isSuspicious: jumps.length > 3 // 超过3次跳跃视为可疑
};
}3. 时间窗口验证规则
规则一:时间窗口检测
typescript
async function checkTimeWindow(
startTime: Date,
endTime: Date,
plannedStartTime: Date,
plannedEndTime: Date,
timeWindow: number = 30 // 时间窗口(分钟)
): Promise<TimeWindowResult> {
const actualDuration = (endTime.getTime() - startTime.getTime()) / (1000 * 60); // 分钟
const plannedDuration = (plannedEndTime.getTime() - plannedStartTime.getTime()) / (1000 * 60);
// 检查开始时间是否在时间窗口内
const startDeviation = Math.abs(
(startTime.getTime() - plannedStartTime.getTime()) / (1000 * 60)
);
// 检查结束时间是否在时间窗口内
const endDeviation = Math.abs(
(endTime.getTime() - plannedEndTime.getTime()) / (1000 * 60)
);
// 检查总时长是否合理
const durationDeviation = Math.abs(actualDuration - plannedDuration);
return {
isInTimeWindow: startDeviation <= timeWindow && endDeviation <= timeWindow,
startDeviation,
endDeviation,
durationDeviation,
isTimeout: startDeviation > timeWindow || endDeviation > timeWindow,
shouldAlert: durationDeviation > plannedDuration * 0.5 // 超过计划时长的50%
};
}4. 停留检测规则
规则一:异常停留检测
typescript
function checkAbnormalStay(
trajectory: Array<{ lat: number; lng: number; time: Date }>,
maxStayTime: number = 10 // 最大允许停留时间(分钟)
): StayCheckResult {
const stays = [];
let currentStay: { start: Date; location: { lat: number; lng: number }; points: any[] } | null = null;
for (let i = 1; i < trajectory.length; i++) {
const point1 = trajectory[i - 1];
const point2 = trajectory[i];
const distance = calculateDistance(point1, point2);
const time = (point2.time.getTime() - point1.time.getTime()) / (1000 * 60); // 分钟
// 如果距离小于 10 米,视为停留
if (distance < 10) {
if (!currentStay) {
currentStay = {
start: point1.time,
location: { lat: point1.lat, lng: point1.lng },
points: [point1, point2]
};
} else {
currentStay.points.push(point2);
}
} else {
if (currentStay) {
const stayDuration = (currentStay.points[currentStay.points.length - 1].time.getTime() -
currentStay.start.getTime()) / (1000 * 60);
if (stayDuration > maxStayTime) {
stays.push({
...currentStay,
duration: stayDuration,
isAbnormal: true
});
}
currentStay = null;
}
}
}
return {
hasAbnormalStay: stays.length > 0,
stays,
shouldAlert: stays.some(s => s.duration > maxStayTime * 2)
};
}数据模型
GPS 轨迹点(GPSPoint)
typescript
interface GPSPoint {
lat: number; // 纬度
lng: number; // 经度
time: Date; // 时间戳
accuracy?: number; // 精度(米)
speed?: number; // 速度(km/h)
}轨迹验证结果(TrajectoryValidationResult)
typescript
interface TrajectoryValidationResult {
isValid: boolean;
routeDeviation: DeviationResult;
speedCheck: SpeedCheckResult;
jumpCheck: JumpCheckResult;
timeWindowCheck: TimeWindowResult;
stayCheck: StayCheckResult;
violations: Violation[];
}开发注意事项
- GPS 精度处理:GPS 精度有限,需要设置合理的容差范围
- 轨迹采样:轨迹点可能过于密集,需要适当采样
- 离线处理:网络不好时,轨迹数据需要本地缓存
- 电池优化:GPS 定位耗电,需要优化定位频率
- 异常处理:GPS 信号丢失、定位失败等情况需要处理
相似场景复用
这个规则可以复用到:
- 巡检轨迹验证:安保巡检、设备巡检
- 配送路线验证:外卖配送、物流配送
- 运输路线监控:医废转运、危险品运输
- 人员定位追踪:矿山人员定位、施工现场人员定位
### 如何使用这个 Skill
**步骤 1:保存为文件**
将上述内容保存为 `.cursorrules` 文件或在项目中创建 `docs/business-rules/gps-trajectory-validation.md`
**步骤 2:在 Cursor 中引用**在开发轨迹验证功能时,告诉 AI: "参考 gps-trajectory-validation.md 中的业务规则, 实现 GPS 轨迹验证逻辑"
**步骤 3:AI 会理解并生成代码**
AI 会基于这个规则生成准确的轨迹验证逻辑、路线偏离检测等。
---
## 2. PROMPT 模板:蓝牙设备集成逻辑生成
### 使用场景
当需要快速生成类似的"蓝牙设备集成"代码时,使用这个 PROMPT 模板。
### PROMPT 模板
```text
你是一个硬件集成开发专家。请根据以下需求,生成完整的蓝牙设备集成代码。
## 业务场景
[描述你的具体场景,例如:蓝牙电子秤自动称重]
## 设备信息
- 设备类型:[例如:蓝牙电子秤]
- 设备型号:[例如:XXX-500]
- 通信协议:[例如:蓝牙 4.0 BLE]
- 数据格式:[例如:JSON / 二进制]
## 功能需求
1. 设备扫描和连接
2. 数据读取和解析
3. 数据验证和处理
4. 异常处理和重连
## 输出要求
1. TypeScript/JavaScript 代码实现
2. 包含完整的设备连接逻辑
3. 包含数据解析逻辑
4. 包含异常处理
5. 包含单元测试用例
6. 包含注释说明
请生成代码。3. 实施指南
快速复现步骤
如果你需要在新项目中实现类似的场景,按照以下步骤:
步骤 1:需求确认(1 小时)
- [ ] 确认轨迹验证规则(偏离距离、时间窗口)
- [ ] 确认硬件设备(PDA、蓝牙秤、GPS)
- [ ] 确认数据采集频率和精度要求
- [ ] 确认异常处理规则
步骤 2:数据库设计(30 分钟)
sql
-- 轨迹记录表
CREATE TABLE trajectory_records (
id VARCHAR(50) PRIMARY KEY,
record_id VARCHAR(50), -- 关联记录ID(转运记录、巡检记录等)
record_type VARCHAR(50), -- 记录类型
user_id VARCHAR(50),
start_time TIMESTAMP,
end_time TIMESTAMP,
planned_route JSON, -- 规定路线
actual_trajectory JSON, -- 实际轨迹
deviation_result JSON, -- 偏离检测结果
speed_check_result JSON, -- 速度检测结果
violations JSON, -- 违规记录
status VARCHAR(20),
created_at TIMESTAMP
);
-- GPS 轨迹点表
CREATE TABLE gps_points (
id VARCHAR(50) PRIMARY KEY,
trajectory_id VARCHAR(50),
lat DECIMAL(10,6),
lng DECIMAL(10,6),
time TIMESTAMP,
accuracy DECIMAL(5,2),
speed DECIMAL(5,2),
created_at TIMESTAMP,
INDEX idx_trajectory_time (trajectory_id, time)
);步骤 3:开发轨迹验证(3 小时)
使用上述 Cursor Skill,快速生成轨迹验证逻辑代码。
步骤 4:开发硬件集成(3 小时)
使用 PROMPT 模板生成蓝牙设备集成代码。
步骤 5:集成通知(1 小时)
- 微信公众号模板消息
- 企业微信机器人
- 短信通知(备用)
步骤 6:测试(2 小时)
- 轨迹验证测试
- 硬件集成测试
- 异常处理测试
- 边界值测试
总开发时间:约 10-12 小时
关键代码片段
后端 API 示例:
typescript
// POST /api/trajectories/validate
router.post('/validate', async (req, res) => {
const { trajectoryId, plannedRoute } = req.body;
// 1. 获取轨迹数据
const trajectory = await getTrajectory(trajectoryId);
// 2. 验证路线偏离
const deviationResult = await checkRouteDeviation(
trajectory.points,
plannedRoute,
50 // 最大允许偏离 50 米
);
// 3. 验证速度合理性
const speedCheck = checkSpeedReasonableness(trajectory.points);
// 4. 验证轨迹跳跃
const jumpCheck = checkTrajectoryJump(trajectory.points);
// 5. 验证时间窗口
const timeWindowCheck = await checkTimeWindow(
trajectory.startTime,
trajectory.endTime,
plannedRoute.startTime,
plannedRoute.endTime
);
// 6. 验证异常停留
const stayCheck = checkAbnormalStay(trajectory.points, 10);
// 7. 汇总验证结果
const validationResult = {
isValid: !deviationResult.shouldAlert &&
!speedCheck.hasAbnormalSpeed &&
!jumpCheck.isSuspicious &&
timeWindowCheck.isInTimeWindow &&
!stayCheck.shouldAlert,
deviationResult,
speedCheck,
jumpCheck,
timeWindowCheck,
stayCheck,
violations: []
};
// 8. 如果有违规,记录并通知
if (!validationResult.isValid) {
await recordViolations(trajectoryId, validationResult);
await notifyAdmin({
type: 'TRAJECTORY_VIOLATION',
trajectoryId,
violations: validationResult.violations
});
}
res.json({ success: true, result: validationResult });
});下一步
查看 系统落地 → 了解这个场景在完整系统中的实现。

