feat(地理围栏): 添加地理围栏功能并优化打卡记录处理
- 添加@turf/turf依赖用于地理围栏计算 - 实现地理围栏检查,拒绝围栏外的打卡并记录失败事件 - 过滤掉失败事件在工人历史记录中显示 - 修复地图链接中的错误语法 - 移除开发提示和HTTPS相关代码 - 优化视图按钮样式和事件类型颜色标识
This commit is contained in:
+45
-4
@@ -1,5 +1,3 @@
|
||||
import https from 'https'
|
||||
import fs from 'fs'
|
||||
import express from 'express'
|
||||
import cors from 'cors'
|
||||
import { Parser } from 'json2csv'
|
||||
@@ -8,6 +6,11 @@ import mysql from 'mysql2/promise'
|
||||
import dotenv from 'dotenv'
|
||||
import bcrypt from 'bcrypt'
|
||||
import jwt from 'jsonwebtoken'
|
||||
// --- FIX START ---
|
||||
// Import only the required functions from turf
|
||||
import { point, polygon, booleanPointInPolygon, pointToLineDistance } from '@turf/turf'
|
||||
// --- FIX END ---
|
||||
|
||||
|
||||
// Main function to start the server
|
||||
async function startServer() {
|
||||
@@ -38,6 +41,22 @@ async function startServer() {
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// --- FIX START ---
|
||||
// Define the geofence polygon by calling the 'polygon' function directly
|
||||
const geofence = polygon([
|
||||
[
|
||||
[101.80827335908509, 2.8350045747358337],
|
||||
[101.80822799653066, 2.8340134829130363],
|
||||
[101.80827902940462, 2.8335264317641418],
|
||||
[101.80941309326164, 2.8332772427247335],
|
||||
[101.81144873788423, 2.834596811345506],
|
||||
[101.81166988033686, 2.8345911479647157],
|
||||
[101.81199875885511, 2.83593336858695],
|
||||
[101.80827335908509, 2.8350045747358337],
|
||||
],
|
||||
])
|
||||
// --- FIX END ---
|
||||
|
||||
app.use(cors())
|
||||
app.use(express.json())
|
||||
|
||||
@@ -96,6 +115,28 @@ async function startServer() {
|
||||
try {
|
||||
const { userId, eventType, qrCodeValue, latitude, longitude } = req.body
|
||||
|
||||
// Geofencing check using the directly imported functions
|
||||
const userLocation = point([longitude, latitude]);
|
||||
const isWithinGeofence = booleanPointInPolygon(userLocation, geofence);
|
||||
|
||||
if (!isWithinGeofence) {
|
||||
// User is outside the geofence, log a 'failed' attempt
|
||||
// Calculate the distance from the geofence
|
||||
const distance = pointToLineDistance(userLocation, geofence.geometry.coordinates[0], { units: 'meters' });
|
||||
// Create a descriptive note
|
||||
const notes = `Clock-in outside of the zone: ${distance.toFixed(2)} meters.`;
|
||||
|
||||
// Insert the failed attempt into the database
|
||||
await db.execute(
|
||||
'INSERT INTO clock_records (worker_id, event_type, timestamp, qr_code_id, latitude, longitude, notes, distance_meters) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[userId, 'failed', new Date(), qrCodeValue, latitude, longitude, notes, distance]
|
||||
);
|
||||
|
||||
// Return an error to the user
|
||||
return res.status(403).json({ message: `You are not within the allowed work area.` });
|
||||
// --- MODIFICATION END ---
|
||||
}
|
||||
|
||||
const [qrRows] = await db.execute('SELECT name, is_active FROM qr_codes WHERE id = ?', [
|
||||
qrCodeValue,
|
||||
])
|
||||
@@ -536,7 +577,7 @@ async function startServer() {
|
||||
const placeholders = idsArray.map(() => '?').join(',')
|
||||
|
||||
// MODIFIED: Use LEFT JOIN and COALESCE to handle manual entries, and select `notes`
|
||||
let query = `SELECT cr.id, w.full_name, cr.event_type, cr.timestamp, COALESCE(qc.name, 'Manual Entry') as qrCodeUsedName, cr.latitude, cr.longitude, cr.notes FROM clock_records cr LEFT JOIN qr_codes qc ON cr.qr_code_id = qc.id JOIN workers w ON cr.worker_id = w.id WHERE cr.worker_id IN (${placeholders})`
|
||||
let query = `SELECT cr.id, w.full_name, cr.event_type, cr.timestamp, COALESCE(qc.name, 'Manual Entry') as qrCodeUsedName, cr.latitude, cr.longitude, cr.notes, cr.distance_meters FROM clock_records cr LEFT JOIN qr_codes qc ON cr.qr_code_id = qc.id JOIN workers w ON cr.worker_id = w.id WHERE cr.worker_id IN (${placeholders})`;
|
||||
|
||||
const params = [...idsArray]
|
||||
if (startDate && endDate) {
|
||||
@@ -657,7 +698,7 @@ async function startServer() {
|
||||
// }
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server is running on https://localhost:${port}`)
|
||||
console.log(`Server is running on http://localhost:${port}`)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user