BodyBalanceEvaluation/frontend/src/renderer/src/services/api.js

667 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import axios from 'axios'
import { ElMessage } from 'element-plus'
// 创建axios实例
const api = axios.create({
timeout: 10000
})
// 请求拦截器
api.interceptors.request.use(
config => {
// 动态设置baseURL
if (window.electronAPI) {
config.baseURL = window.electronAPI.getBackendUrl()
} else {
config.baseURL = 'http://192.168.1.58:5000'
}
// 为需要发送数据的请求设置Content-Type避免覆盖FormData
if (['post', 'put', 'patch'].includes((config.method || '').toLowerCase())) {
const isFormData = typeof FormData !== 'undefined' && config.data instanceof FormData
if (!isFormData && !config.headers['Content-Type']) {
config.headers['Content-Type'] = 'application/json'
}
}
// 添加认证token
const token = localStorage.getItem('authToken')
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
}
// 添加时间戳防止缓存
if (config.method === 'get') {
config.params = {
...config.params,
_t: Date.now()
}
}
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器
api.interceptors.response.use(
response => {
return response.data
},
error => {
let message = '请求失败'
if (error.response) {
// 服务器响应错误
const { status, data } = error.response
switch (status) {
case 400:
message = data.message || '请求参数错误'
break
case 401:
message = '未授权访问'
break
case 403:
message = '禁止访问'
break
case 404:
message = '请求的资源不存在'
break
case 500:
message = '服务器内部错误'
break
default:
message = data.message || `请求失败 (${status})`
}
} else if (error.request) {
// 网络错误
message = '网络连接失败,请检查后端服务是否启动'
} else {
// 其他错误
message = error.message || '未知错误'
}
// ElMessage.error(message)
return Promise.reject(error)
}
)
// 系统API
export const systemAPI = {
// 健康检查
health() {
return api.get('/health')
},
// 获取系统信息
getSystemInfo() {
return api.get('/api/system/info')
},
// 获取系统状态
getSystemStatus() {
return api.get('/api/system/status')
}
}
// 设备API
export const deviceAPI = {
// 获取设备状态
getDeviceStatus() {
return api.get('/api/devices/status')
},
// 刷新设备
refreshDevices() {
return api.post('/api/devices/refresh')
},
// 校准设备
calibrateDevice() {
return api.post('/api/devices/calibrate')
},
// 校准IMU头部姿态传感器
calibrateIMU() {
return api.post('/api/devices/calibrate/imu')
},
// 测试设备
testDevice() {
return api.post('/api/devices/test')
}
}
// 用户认证API
export const authAPI = {
// 用户登录
login(credentials) {
return api.post('/api/auth/login', credentials)
},
// 用户注册
register(userData) {
return api.post('/api/auth/register', userData)
},
// 忘记密码
forgotPassword(email) {
return api.post('/api/auth/forgot-password', { email })
},
// 重置密码
resetPassword(token, newPassword) {
return api.post('/api/auth/reset-password', { token, password: newPassword })
},
// 退出登录
logout() {
return api.post('/api/auth/logout')
},
// 验证token
verifyToken() {
return api.get('/api/auth/verify')
}
}
// 患者API
export const patientAPI = {
// 获取患者列表
getPatients(params = {}) {
return api.get('/api/patients', { params })
},
// 获取患者详情
getPatient(id) {
return api.get(`/api/patients/${id}`)
},
// 根据ID获取患者别名方法
getById(id) {
return this.getPatient(id)
},
// 创建患者
createPatient(data) {
return api.post('/api/patients', data)
},
// 创建患者(别名方法)
create(data) {
return this.createPatient(data)
},
// 更新患者
updatePatient(id, data) {
return api.put(`/api/patients/${id}`, data)
},
// 更新患者(别名方法)
update(id, data) {
return this.updatePatient(id, data)
},
// 删除患者
deletePatient(id) {
return api.delete(`/api/patients/${id}`)
},
// 搜索患者
searchPatients(query) {
return api.get('/api/patients/search', { params: { q: query } })
},
// 获取患者统计信息
getStatistics() {
return api.get('/api/patients/statistics')
}
}
// 检测API
export const detectionAPI = {
// 开始检测
startDetection(config) {
return api.post('/api/detection/start', config)
},
// 停止检测
stopDetection(sessionId) {
return api.post(`/api/detection/${sessionId}/stop`)
},
// 获取检测状态
getDetectionStatus(sessionId) {
return api.get(`/api/detection/${sessionId}/status`)
},
// 获取实时数据
getRealTimeData(sessionId) {
return api.get(`/api/detection/${sessionId}/realtime`)
},
// 获取检测结果
getDetectionResults(sessionId) {
return api.get(`/api/detection/${sessionId}/results`)
},
// 保存检测结果
saveDetectionResults(sessionId, data) {
return api.post(`/api/detection/${sessionId}/save`, data)
},
// 创建检测记录
create(data) {
return api.post('/api/detection', data)
},
// 获取检测记录列表
getList(params = {}) {
return api.get('/api/detection', { params })
},
// 根据患者ID获取检测记录
getByPatient(patientId) {
return api.get(`/api/patients/${patientId}/detections`)
}
}
// 授权API
export const licenseAPI = {
info() {
return api.get('/api/license/info')
},
generateActivationRequest(company_name, contact_info) {
return api.post('/api/license/activation-request', { company_name, contact_info })
},
verifyLicense(licenseFile) {
const formData = new FormData()
formData.append('license_file', licenseFile)
return api.post('/api/license/verify', formData)
},
activatePackage(zipFile) {
const formData = new FormData()
formData.append('package_zip', zipFile)
return api.post('/api/license/activate-package', formData)
}
}
// 录制API
export const recordingAPI = {
// 创建录制
create(data) {
return api.post('/api/recordings', data)
},
// 获取录制列表
getList(params = {}) {
return api.get('/api/recordings', { params })
},
// 根据患者ID获取录制
getByPatient(patientId) {
return api.get(`/api/patients/${patientId}/recordings`)
},
// 获取录制详情
getById(id) {
return api.get(`/api/recordings/${id}`)
},
// 更新录制
update(id, data) {
return api.put(`/api/recordings/${id}`, data)
},
// 删除录制
delete(id) {
return api.delete(`/api/recordings/${id}`)
},
// 上传录制文件
upload(file, onProgress) {
const formData = new FormData()
formData.append('file', file)
return api.post('/api/recordings/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: (progressEvent) => {
if (onProgress) {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
onProgress(percentCompleted)
}
}
})
}
}
// 会话API
export const sessionAPI = {
// 获取会话列表
getSessions(params = {}) {
return api.get('/api/sessions', { params })
},
// 获取会话详情
getSession(id) {
return api.get(`/api/sessions/${id}`)
},
// 删除会话
deleteSession(id) {
return api.delete(`/api/sessions/${id}`)
},
// 获取患者的会话历史
getPatientSessions(patientId, params = {}) {
return api.get(`/api/patients/${patientId}/sessions`, { params })
}
}
// 数据分析API
export const analysisAPI = {
// 分析会话数据
analyzeSession(sessionId) {
return api.post(`/api/analysis/session/${sessionId}`)
},
// 获取分析结果
getAnalysisResult(sessionId) {
return api.get(`/api/analysis/session/${sessionId}/result`)
},
// 比较多个会话
compareSessions(sessionIds) {
return api.post('/api/analysis/compare', { session_ids: sessionIds })
},
// 获取统计数据
getStatistics(params = {}) {
return api.get('/api/analysis/statistics', { params })
},
// 生成趋势报告
generateTrendReport(patientId, params = {}) {
return api.post(`/api/analysis/trend/${patientId}`, params)
}
}
// 报告API
export const reportAPI = {
// 生成PDF报告
generatePDFReport(sessionId) {
return api.post(`/api/reports/pdf/${sessionId}`, {}, {
responseType: 'blob'
})
},
// 导出数据
exportData(sessionId, format = 'csv') {
return api.get(`/api/reports/export/${sessionId}`, {
params: { format },
responseType: 'blob'
})
},
// 批量导出
batchExport(sessionIds, format = 'csv') {
return api.post('/api/reports/batch-export', {
session_ids: sessionIds,
format
}, {
responseType: 'blob'
})
},
// 获取报告列表
getReports(params = {}) {
return api.get('/api/reports', { params })
},
// 删除报告
deleteReport(reportId) {
return api.delete(`/api/reports/${reportId}`)
}
}
// 设置API
export const settingsAPI = {
// 获取系统设置
getSettings() {
return api.get('/api/settings')
},
// 更新系统设置
updateSettings(settings) {
return api.put('/api/settings', settings)
},
// 重置设置
resetSettings() {
return api.post('/api/settings/reset')
},
// 备份设置
backupSettings() {
return api.post('/api/settings/backup', {}, {
responseType: 'blob'
})
},
// 恢复设置
restoreSettings(file) {
const formData = new FormData()
formData.append('file', file)
return api.post('/api/settings/restore', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
}
// WebSocket连接管理
export class WebSocketManager {
constructor() {
this.socket = null
this.reconnectAttempts = 0
this.maxReconnectAttempts = 5
this.reconnectInterval = 3000
this.listeners = new Map()
}
connect(url) {
try {
this.socket = new WebSocket(url)
this.socket.onopen = () => {
console.log('WebSocket连接已建立')
this.reconnectAttempts = 0
this.emit('connected')
}
this.socket.onmessage = (event) => {
try {
const data = JSON.parse(event.data)
this.emit('message', data)
// 根据消息类型分发
if (data.type) {
this.emit(data.type, data.payload)
}
} catch (error) {
console.error('WebSocket消息解析失败:', error)
}
}
this.socket.onclose = () => {
console.log('WebSocket连接已关闭')
this.emit('disconnected')
this.attemptReconnect()
}
this.socket.onerror = (error) => {
console.error('WebSocket错误:', error)
this.emit('error', error)
}
} catch (error) {
console.error('WebSocket连接失败:', error)
this.emit('error', error)
}
}
disconnect() {
if (this.socket) {
this.socket.close()
this.socket = null
}
}
send(data) {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify(data))
} else {
console.warn('WebSocket未连接无法发送消息')
}
}
on(event, callback) {
if (!this.listeners.has(event)) {
this.listeners.set(event, [])
}
this.listeners.get(event).push(callback)
}
off(event, callback) {
if (this.listeners.has(event)) {
const callbacks = this.listeners.get(event)
const index = callbacks.indexOf(callback)
if (index > -1) {
callbacks.splice(index, 1)
}
}
}
emit(event, data) {
if (this.listeners.has(event)) {
this.listeners.get(event).forEach(callback => {
try {
callback(data)
} catch (error) {
console.error(`WebSocket事件处理错误 [${event}]:`, error)
}
})
}
}
attemptReconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++
console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`)
setTimeout(() => {
if (window.electronAPI) {
const backendUrl = window.electronAPI.getBackendUrl()
const wsUrl = backendUrl.replace('http', 'ws') + '/ws'
this.connect(wsUrl)
}
}, this.reconnectInterval)
} else {
console.error('WebSocket重连失败已达到最大重试次数')
this.emit('reconnect_failed')
}
}
}
// 创建WebSocket管理器实例
export const wsManager = new WebSocketManager()
// 文件上传工具
export const uploadFile = (file, onProgress) => {
return new Promise((resolve, reject) => {
const formData = new FormData()
formData.append('file', file)
const config = {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: (progressEvent) => {
if (onProgress) {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
onProgress(percentCompleted)
}
}
}
api.post('/api/upload', formData, config)
.then(resolve)
.catch(reject)
})
}
// 文件下载工具
export const downloadFile = (url, filename) => {
return api.get(url, { responseType: 'blob' })
.then(response => {
const blob = new Blob([response])
const downloadUrl = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = downloadUrl
link.download = filename
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(downloadUrl)
})
}
//
export const historyAPI = {
// 获取检测会话历史
sessionsPage(params) {
return api.get('/api/history/sessions', { params })
},
// 删除检测数据记录
detectionDelById(id) {
return api.delete(`/api/detection/data/${id}`, {})
},
// 删除检测会话及其相关的检测数据
sessionsDelById(id) {
return api.delete(`api/detection/sessions/${id}`, {})
},
// 获取检测会话历史
sessionById(id) {
return api.get(`/api/history/sessions/${id}`)
},
//获取最新的检测数据
detectionLatestList(id) {
return api.get(`/api/detection/data/detail/${id}/latest`)
},
//根据主键ID查询检测数据详情
detectionById(id) {
return api.get(`/api/detection/data/detail/${id}`)
},
}
// 获取后端URL的函数
export const getBackendUrl = () => {
if (window.electronAPI) {
return window.electronAPI.getBackendUrl()
} else {
return 'http://localhost:5000'
}
}
export default api