/** * 手环位置服务 - 处理基站ID、位置信息、围栏功能 */ import type { AkReqResponse } from '@/uni_modules/ak-req/index.uts' // 基础坐标类型 export type LocationCoordinate = { longitude: number latitude: number } // 估算位置类型 export type EstimatedLocation = { longitude: number latitude: number accuracy: number } // 围栏中心点类型 export type FenceCenter = { longitude: number latitude: number } // 基站信息类型 export type BaseStationInfo = { /** 基站ID */ id: string /** 基站名称 */ name: string /** 基站位置描述 */ location: string /** 经度 */ longitude: number /** 纬度 */ latitude: number /** 信号强度 */ signalStrength: number /** 是否在线 */ isOnline: boolean /** 覆盖范围(米) */ range: number } // 位置信息类型 export type LocationInfo = { /** 设备ID */ deviceId: string /** 当前连接的基站 */ baseStation: BaseStationInfo | null /** 估算位置 */ estimatedLocation: EstimatedLocation | null /** 最后更新时间 */ lastUpdate: string /** 位置状态 */ status: 'online' | 'offline' | 'unknown' } // 围栏信息类型 export type FenceInfo = { /** 围栏ID */ id: string /** 围栏名称 */ name: string /** 围栏类型 */ type: 'circle' | 'polygon' /** 围栏中心点(圆形围栏) */ center?: FenceCenter /** 围栏半径(米,圆形围栏) */ radius?: number /** 围栏顶点(多边形围栏) */ points?: Array /** 是否激活 */ isActive: boolean /** 围栏事件类型 */ eventType: 'enter' | 'exit' | 'both' /** 创建时间 */ createdAt: string } // 位置历史记录类型 export type LocationHistoryItem = { /** 记录ID */ id: string /** 设备ID */ deviceId: string /** 基站信息 */ baseStation: BaseStationInfo /** 记录时间 */ timestamp: string /** 持续时间(秒) */ duration: number /** 位置类型 */ locationType: 'basestation' | 'estimated' } // 围栏事件类型 export type FenceEvent = { /** 事件ID */ id: string /** 设备ID */ deviceId: string /** 围栏信息 */ fence: FenceInfo /** 事件类型 */ eventType: 'enter' | 'exit' /** 事件时间 */ timestamp: string /** 触发位置 */ location: LocationCoordinate /** 是否已读 */ isRead: boolean } // FenceInfo 的手动 Partial 类型 export type PartialFenceInfo = { id?: string name?: string type?: 'circle' | 'polygon' center?: FenceCenter radius?: number points?: Array isActive?: boolean eventType?: 'enter' | 'exit' | 'both' createdAt?: string } // mock generic AkReqResponse for array data export function mockAkArrayResponse(data: T[], status: number = 200): AkReqResponse> { return { status, data, headers: {} as UTSJSONObject, error: null, total: data.length, page: 1, limit: data.length, hasmore: false, origin: null, }; } /** * 位置服务工厂函数 */ export function createLocationResponse(status: number, message: string, data: T[]): AkReqResponse> { return mockAkArrayResponse(data, status); } /** * 位置服务错误响应工厂函数 */ export function createLocationErrorResponse(message: string): AkReqResponse> { return createLocationResponse(500, message, []) } /** * 手环位置服务类 */ export class LocationService { /** * 获取设备当前位置信息 */ static async getCurrentLocation(deviceId: string): Promise> { try { // 模拟API调用延迟 await new Promise((resolve) => { setTimeout(() => { resolve() }, 1000) }) // 模拟数据 const mockBaseStation: BaseStationInfo = { id: 'BS001', name: '教学楼A栋基站', location: '教学楼A栋1层', longitude: 116.397428, latitude: 39.90923, signalStrength: -45, isOnline: true, range: 50 } const mockLocation: LocationInfo[] = [{ deviceId: deviceId, baseStation: mockBaseStation, estimatedLocation: { longitude: 116.397428, latitude: 39.90923, accuracy: 15 }, lastUpdate: new Date().toISOString(), status: 'online' }] return createLocationResponse(200, '获取位置成功', mockLocation) } catch (error) { console.error('获取设备位置失败:', error) return createLocationErrorResponse('获取位置信息失败') } } /** * 获取可用基站列表 */ static async getBaseStations(): Promise> { try { await new Promise((resolve) => { setTimeout(() => { resolve() }, 800) }) const mockBaseStations: BaseStationInfo[] = [ { id: 'BS001', name: '教学楼A栋基站', location: '教学楼A栋1层', longitude: 116.397428, latitude: 39.90923, signalStrength: -45, isOnline: true, range: 50 }, { id: 'BS002', name: '教学楼B栋基站', location: '教学楼B栋2层', longitude: 116.398428, latitude: 39.91023, signalStrength: -52, isOnline: true, range: 45 }, { id: 'BS003', name: '操场基站', location: '学校操场', longitude: 116.399428, latitude: 39.91123, signalStrength: -38, isOnline: true, range: 100 }, { id: 'BS004', name: '宿舍楼基站', location: '学生宿舍1号楼', longitude: 116.396428, latitude: 39.90823, signalStrength: -60, isOnline: false, range: 40 } ] return createLocationResponse(200, '获取基站列表成功', mockBaseStations) } catch (error) { console.error('获取基站列表失败:', error) return createLocationErrorResponse('获取基站列表失败') } } /** * 获取围栏列表 */ static async getFences(deviceId: string): Promise> { try { await new Promise((resolve) => { setTimeout(() => { resolve() }, 600) }) const mockFences: FenceInfo[] = [ { id: 'FENCE001', name: '校园安全区域', type: 'circle', center: { longitude: 116.397928, latitude: 39.90973 }, radius: 200, isActive: true, eventType: 'exit', createdAt: '2024-01-15T10:00:00Z' }, { id: 'FENCE002', name: '教学区域', type: 'polygon', points: [ { longitude: 116.397000, latitude: 39.909000 }, { longitude: 116.398000, latitude: 39.909000 }, { longitude: 116.398000, latitude: 39.910000 }, { longitude: 116.397000, latitude: 39.910000 } ], isActive: true, eventType: 'both', createdAt: '2024-01-16T14:30:00Z' }, { id: 'FENCE003', name: '危险区域', type: 'circle', center: { longitude: 116.395428, latitude: 39.90723 }, radius: 30, isActive: true, eventType: 'enter', createdAt: '2024-01-17T09:15:00Z' } ] console.log(mockFences) return createLocationResponse(200, '获取围栏列表成功', mockFences) } catch (error) { console.error('获取围栏列表失败:', error) return createLocationErrorResponse('获取围栏列表失败') } } /** * 获取位置历史记录 */ static async getLocationHistory(deviceId: string, startDate: string, endDate: string): Promise> { try { await new Promise((resolve) => { setTimeout(() => { resolve() }, 1200) }) const mockHistory: LocationHistoryItem[] = [ { id: 'HIST001', deviceId: deviceId, baseStation: { id: 'BS001', name: '教学楼A栋基站', location: '教学楼A栋1层', longitude: 116.397428, latitude: 39.90923, signalStrength: -45, isOnline: true, range: 50 }, timestamp: '2024-01-20T08:30:00Z', duration: 3600, locationType: 'basestation' }, { id: 'HIST002', deviceId: deviceId, baseStation: { id: 'BS003', name: '操场基站', location: '学校操场', longitude: 116.399428, latitude: 39.91123, signalStrength: -38, isOnline: true, range: 100 }, timestamp: '2024-01-20T10:00:00Z', duration: 2400, locationType: 'basestation' }, { id: 'HIST003', deviceId: deviceId, baseStation: { id: 'BS002', name: '教学楼B栋基站', location: '教学楼B栋2层', longitude: 116.398428, latitude: 39.91023, signalStrength: -52, isOnline: true, range: 45 }, timestamp: '2024-01-20T14:20:00Z', duration: 5400, locationType: 'basestation' } ] return createLocationResponse(200, '获取位置历史成功', mockHistory) } catch (error) { console.error('获取位置历史失败:', error) return createLocationErrorResponse('获取位置历史失败') } } /** * 获取围栏事件记录 */ static async getFenceEvents(deviceId: string, limit: number = 10): Promise> { try { await new Promise((resolve) => { setTimeout(() => { resolve() }, 900) }) const mockEvents: FenceEvent[] = [ { id: 'EVENT001', deviceId: deviceId, fence: { id: 'FENCE001', name: '校园安全区域', type: 'circle', center: { longitude: 116.397928, latitude: 39.90973 }, radius: 200, isActive: true, eventType: 'exit', createdAt: '2024-01-15T10:00:00Z' }, eventType: 'enter', timestamp: '2024-01-20T07:45:00Z', location: { longitude: 116.397528, latitude: 39.90943 }, isRead: false }, { id: 'EVENT002', deviceId: deviceId, fence: { id: 'FENCE002', name: '教学区域', type: 'polygon', points: [ { longitude: 116.397000, latitude: 39.909000 }, { longitude: 116.398000, latitude: 39.909000 }, { longitude: 116.398000, latitude: 39.910000 }, { longitude: 116.397000, latitude: 39.910000 } ], isActive: true, eventType: 'both', createdAt: '2024-01-16T14:30:00Z' }, eventType: 'enter', timestamp: '2024-01-20T08:30:00Z', location: { longitude: 116.397500, latitude: 39.909500 }, isRead: true } ] return createLocationResponse(200, '获取围栏事件成功', mockEvents) } catch (error) { console.error('获取围栏事件失败:', error) return createLocationErrorResponse('获取围栏事件失败') } } /** * 创建围栏 */ static async createFence(fence: PartialFenceInfo): Promise> { try { await new Promise((resolve) => { setTimeout(() => { resolve() }, 1500) }) const newFence: FenceInfo[] = [{ id: `FENCE${Date.now()}`, name: fence.name ?? '新围栏', type: fence.type ?? 'circle', center: fence.center, radius: fence.radius, points: fence.points, isActive: fence.isActive ?? true, eventType: fence.eventType ?? 'both', createdAt: new Date().toISOString() }] return createLocationResponse(200, '创建围栏成功', newFence) } catch (error) { console.error('创建围栏失败:', error) return createLocationErrorResponse('创建围栏失败') } } /** * 更新围栏 */ static async updateFence(fenceId: string, updates: PartialFenceInfo): Promise> { try { await new Promise((resolve) => { setTimeout(() => { resolve() }, 1200) }) // 模拟更新成功 const updatedFence: FenceInfo[] = [{ id: fenceId, name: updates.name ?? '更新的围栏', type: updates.type ?? 'circle', center: updates.center, radius: updates.radius, points: updates.points, isActive: updates.isActive ?? true, eventType: updates.eventType ?? 'both', createdAt: '2024-01-15T10:00:00Z' }] return createLocationResponse(200, '更新围栏成功', updatedFence) } catch (error) { console.error('更新围栏失败:', error) return createLocationErrorResponse('更新围栏失败') } } /** * 删除围栏 */ static async deleteFence(fenceId: string): Promise>> { try { await new Promise((resolve) => { setTimeout(() => { resolve() }, 800) }) return createLocationResponse(200, '删除围栏成功', [true]) } catch (error) { console.error('删除围栏失败:', error) return createLocationErrorResponse('删除围栏失败') } } /** * 标记围栏事件为已读 */ static async markEventAsRead(eventId: string): Promise>> { try { await new Promise((resolve) => { setTimeout(() => { resolve() }, 500) }) return createLocationResponse(200, '标记事件成功', [true]) } catch (error) { console.error('标记事件失败:', error) return createLocationErrorResponse('标记事件失败') } } }