| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- import type {
- Annotation,
- AnnotationConfigResponse,
- AnnotationLabel,
- AnnotationListResponse,
- DevicePoint,
- FaultsResponse,
- PeriodDetail,
- QueryOptionsResponse,
- SitePoint,
- SitePointsResponse,
- TimePoint,
- TimePointsResponse,
- TspluseRulerResponse,
- WaveWindowResponse,
- } from './types'
- const apiBase = import.meta.env.VITE_API_BASE ?? ''
- const TOKEN_KEY = 'auth_token'
- export function getToken(): string | null {
- return localStorage.getItem(TOKEN_KEY)
- }
- export function setToken(token: string | null) {
- if (token) localStorage.setItem(TOKEN_KEY, token)
- else localStorage.removeItem(TOKEN_KEY)
- }
- async function request<T>(path: string, init?: RequestInit): Promise<T> {
- const token = getToken()
- const response = await fetch(`${apiBase}${path}`, {
- ...init,
- headers: {
- 'Content-Type': 'application/json',
- ...(token ? { Authorization: `Bearer ${token}` } : {}),
- ...(init?.headers ?? {}),
- },
- })
- if (response.status === 401 && path !== '/api/login') {
- setToken(null)
- window.dispatchEvent(new CustomEvent('auth-expired'))
- }
- if (!response.ok) {
- const body = await response.json().catch(() => null)
- throw new Error(body?.detail ?? `请求失败(${response.status})`)
- }
- return response.json() as Promise<T>
- }
- export async function login(username: string, password: string) {
- const result = await request<{ token: string; username: string }>('/api/login', {
- method: 'POST',
- body: JSON.stringify({ username, password }),
- })
- setToken(result.token)
- return result
- }
- export async function logout() {
- try {
- await request<{ ok: boolean }>('/api/logout', { method: 'POST' })
- } finally {
- setToken(null)
- }
- }
- export function fetchQueryOptions() {
- return request<QueryOptionsResponse>('/api/query-options')
- }
- export function fetchSitePoints(devicePart: string) {
- return request<SitePointsResponse>(`/api/site-points?device_part=${encodeURIComponent(devicePart)}`)
- }
- export function fetchTimePoints(params: {
- devicePart: string
- devicePoints: DevicePoint[]
- minTime?: string
- maxTime?: string
- includeStopped?: boolean
- minStatus?: number | null
- statusFilter?: string[]
- sitePoints?: string[]
- }) {
- const search = new URLSearchParams({ device_part: params.devicePart })
- params.devicePoints.forEach((value) => search.append('device_points', value))
- if (params.minTime) search.set('min_time', params.minTime)
- if (params.maxTime) search.set('max_time', params.maxTime)
- if (params.includeStopped) search.set('include_stopped', 'true')
- if (params.minStatus) search.set('min_status', String(params.minStatus))
- ;(params.statusFilter ?? []).forEach((value) => search.append('status_filter', value))
- ;(params.sitePoints ?? []).forEach((value) => search.append('site_points', value))
- return request<TimePointsResponse>(`/api/time-points?${search.toString()}`)
- }
- export function fetchTspluseRuler() {
- return request<TspluseRulerResponse>('/api/tspluse-ruler')
- }
- export function fetchFaults(params: { devicePart: string; minTime?: string; maxTime?: string }) {
- const search = new URLSearchParams({ device_part: params.devicePart })
- if (params.minTime) search.set('min_time', params.minTime)
- if (params.maxTime) search.set('max_time', params.maxTime)
- return request<FaultsResponse>(`/api/faults?${search.toString()}`)
- }
- export function fetchWaveWindow(params: {
- devicePart: string
- devicePoints: DevicePoint[]
- points: TimePoint[]
- maxPoints: number
- noSampling: boolean
- firstCycleOnly?: boolean
- sitePoints?: string[]
- }) {
- return request<WaveWindowResponse>('/api/wave-window', {
- method: 'POST',
- body: JSON.stringify(params),
- })
- }
- export function fetchPeriodDetail(waveFileId: number, periodNo: number) {
- return request<PeriodDetail>(`/api/wave-files/${waveFileId}/periods/${periodNo}`)
- }
- export function fetchAnnotationConfig() {
- return request<AnnotationConfigResponse>('/api/annotation-config')
- }
- export function fetchAnnotations(waveFileIds: number[]) {
- if (!waveFileIds.length) return Promise.resolve({ source: 'demo' as const, annotations: [] as Annotation[], notice: null })
- const search = new URLSearchParams()
- waveFileIds.forEach((id) => search.append('wave_file_ids', String(id)))
- return request<AnnotationListResponse>(`/api/annotations?${search.toString()}`)
- }
- export function fetchAnnotationsByIds(waveFileIds: number[]) {
- if (!waveFileIds.length) return Promise.resolve({ source: 'demo' as const, annotations: [] as Annotation[], notice: null })
- return request<AnnotationListResponse>('/api/annotations/query', {
- method: 'POST',
- body: JSON.stringify({ wave_file_ids: waveFileIds }),
- })
- }
- export function createAnnotation(payload: {
- wave_file_id: number
- label: AnnotationLabel
- period_start: number
- period_end: number
- sample_index_start: number
- sample_index_end: number
- }) {
- return request<Annotation & { source: string; notice: string | null }>('/api/annotations', {
- method: 'POST',
- body: JSON.stringify(payload),
- })
- }
- export function deleteAnnotation(id: number) {
- return request<{ deleted: number; source: string; notice: string | null }>(`/api/annotations/${id}`, {
- method: 'DELETE',
- })
- }
- export type PretrainRecordInput = {
- id: number
- point_name: string
- measurement_type: string
- rpm: number
- sample_time: string
- file_name: string
- }
- export function fetchPretrainStatus(ids: number[]) {
- if (!ids.length) return Promise.resolve({ recorded: [] as number[] })
- const search = new URLSearchParams()
- ids.forEach((id) => search.append('ids', String(id)))
- return request<{ recorded: number[] }>(`/api/pretrain-records?${search.toString()}`)
- }
- export function recordPretrain(row: PretrainRecordInput) {
- return request<{ recorded: boolean; already: boolean }>('/api/pretrain-records', {
- method: 'POST',
- body: JSON.stringify(row),
- })
- }
- export function deletePretrain(id: number) {
- return request<{ deleted: boolean }>(`/api/pretrain-records/${id}`, {
- method: 'DELETE',
- })
- }
|