feat(移动端优化): 实现安卓原生应用的全屏布局和安全区域处理
添加安全区域插件和样式处理,优化移动端视图布局 重构路由和导航结构,改进底部导航栏 增强原生功能集成,包括状态栏和导航栏控制 优化位置服务和后台任务处理 更新语言包和样式以适应移动端体验
This commit is contained in:
+57
-33
@@ -189,18 +189,28 @@ async function startServer() {
|
||||
}
|
||||
|
||||
// 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],
|
||||
],
|
||||
])
|
||||
// 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],
|
||||
// ],
|
||||
// ])
|
||||
|
||||
const geofence = polygon([
|
||||
[
|
||||
[113.310, 23.120],
|
||||
[113.330, 23.120],
|
||||
[113.310, 23.140],
|
||||
[113.330, 23.140],
|
||||
[113.310, 23.120]
|
||||
]
|
||||
])
|
||||
|
||||
|
||||
// Enhanced CORS configuration for HTTPS and mobile development
|
||||
@@ -897,38 +907,52 @@ async function startServer() {
|
||||
|
||||
// --- NEW NATIVE FEATURES API ENDPOINTS ---
|
||||
|
||||
// Location Update Endpoint
|
||||
// Location Update Endpoint - OPTIMIZED: Removed continuous geofence checking
|
||||
app.post('/api/location/update', authenticateJWT, async (req, res) => {
|
||||
try {
|
||||
const { userId, latitude, longitude, accuracy, timestamp, speed, heading, altitude } = req.body
|
||||
const { userId, latitude, longitude, checkGeofence } = req.body
|
||||
|
||||
if (!userId || !latitude || !longitude) {
|
||||
return res.status(400).json({ message: 'User ID, latitude, and longitude are required.' })
|
||||
}
|
||||
|
||||
// Convert timestamp to MySQL-compatible format
|
||||
let mysqlTimestamp
|
||||
if (timestamp) {
|
||||
if (typeof timestamp === 'string' && timestamp.includes('T')) {
|
||||
// Handle ISO 8601 format (e.g., '2025-07-04T09:00:49.192Z')
|
||||
// Convert to MySQL DATETIME format by replacing 'T' with ' ' and removing 'Z'
|
||||
mysqlTimestamp = timestamp.replace('T', ' ').replace('Z', '')
|
||||
} else if (timestamp instanceof Date) {
|
||||
// Handle Date object
|
||||
mysqlTimestamp = timestamp.toISOString().replace('T', ' ').replace('Z', '')
|
||||
} else {
|
||||
// Fallback to current time for invalid formats
|
||||
mysqlTimestamp = new Date().toISOString().replace('T', ' ').replace('Z', '')
|
||||
// OPTIMIZATION: Only check geofence when explicitly requested
|
||||
// This reduces unnecessary processing on every location update
|
||||
if (checkGeofence === true) {
|
||||
try {
|
||||
const userLocation = point([longitude, latitude]);
|
||||
const isWithinGeofence = booleanPointInPolygon(userLocation, geofence);
|
||||
|
||||
if (!isWithinGeofence) {
|
||||
// User is outside the geofence - log security alert silently
|
||||
const distance = pointToLineDistance(userLocation, geofence.geometry.coordinates[0], { units: 'meters' });
|
||||
|
||||
const alertData = {
|
||||
latitude: latitude,
|
||||
longitude: longitude,
|
||||
timestamp: new Date().toISOString(),
|
||||
distance_from_geofence: distance.toFixed(2),
|
||||
check_type: 'scheduled_update' // Indicate this was a scheduled check
|
||||
};
|
||||
|
||||
// Log geofence violation to security_alerts table
|
||||
await logSecurityAlert(userId, 'geofence_violation', alertData, db);
|
||||
|
||||
console.log(`OPTIMIZED: Geofence violation detected for user ${userId}: ${distance.toFixed(2)} meters outside boundary`);
|
||||
} else {
|
||||
console.log(`OPTIMIZED: User ${userId} within geofence during scheduled check`);
|
||||
}
|
||||
} catch (geofenceError) {
|
||||
console.error('OPTIMIZED: Error checking geofence:', geofenceError);
|
||||
// Continue with location update even if geofence check fails
|
||||
}
|
||||
} else {
|
||||
// Use current time if no timestamp provided
|
||||
mysqlTimestamp = new Date().toISOString().replace('T', ' ').replace('Z', '')
|
||||
}
|
||||
|
||||
// Insert location update
|
||||
// OPTIMIZED: Simplified location update - only essential fields
|
||||
// No need for timestamp conversion as we use created_at with NOW()
|
||||
await db.execute(
|
||||
'INSERT INTO location_updates (user_id, latitude, longitude, accuracy, timestamp, speed, heading, altitude, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())',
|
||||
[userId, latitude, longitude, accuracy || null, mysqlTimestamp, speed || null, heading || null, altitude || null]
|
||||
'INSERT INTO location_updates (user_id, longitude, latitude, created_at) VALUES (?, ?, ?, NOW())',
|
||||
[userId, longitude, latitude]
|
||||
)
|
||||
|
||||
res.json({ message: 'Location updated successfully' })
|
||||
|
||||
Reference in New Issue
Block a user