useBaseInfoApi.ts
3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import type { DeviceType, DeviceTypeCategory, DeviceTypePayload } from '~/types/device-type'
import { DEVICE_TYPE_CATEGORY_VALUES } from '~/types/device-type'
import { createSharedComposable } from '@vueuse/core'
interface MutationResponse {
success: boolean
errorCode: string | null
message: string
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null
}
function isDeviceTypeCategory(value: unknown): value is DeviceTypeCategory {
return typeof value === 'string' && DEVICE_TYPE_CATEGORY_VALUES.includes(value as DeviceTypeCategory)
}
function normalizeDeviceTypes(payload: unknown): DeviceType[] {
if (!Array.isArray(payload)) {
return []
}
return payload
.filter(isRecord)
.map((item) => {
const rawCategory = item.category
return {
id: Number(item.id ?? 0),
name: typeof item.name === 'string' ? item.name : '',
model: typeof item.model === 'string' ? item.model : '',
category: isDeviceTypeCategory(rawCategory) ? rawCategory : 'other',
lengthMm: Number(item.lengthMm ?? 0),
widthMm: Number(item.widthMm ?? 0),
heightMm: Number(item.heightMm ?? 0),
weightKg: Number(item.weightKg ?? 0),
hasBattery: Boolean(item.hasBattery),
batterySpec: typeof item.batterySpec === 'string' ? item.batterySpec : undefined,
description: typeof item.description === 'string' ? item.description : undefined,
updatedAt: typeof item.updatedAt === 'string' ? item.updatedAt : ''
} satisfies DeviceType
})
.filter(item => item.id > 0 && item.name.length > 0)
}
function normalizeMutation(payload: unknown, fallbackMessage: string): MutationResponse {
if (!isRecord(payload)) {
return {
success: false,
errorCode: 'REQUEST_FAILED',
message: fallbackMessage
}
}
const message = typeof payload.message === 'string' && payload.message.length > 0
? payload.message
: fallbackMessage
return {
success: typeof payload.success === 'boolean' ? payload.success : false,
errorCode: typeof payload.errorCode === 'string' ? payload.errorCode : null,
message
}
}
const _useBaseInfoApi = () => {
const api = useApiGateway()
const getDeviceTypes = () => {
return api.useApiFetch<DeviceType[]>('/api/base-info/device-types', {
transform: normalizeDeviceTypes,
default: () => []
})
}
const createDeviceType = async (payload: DeviceTypePayload) => {
try {
const result = await api.request<unknown>('/api/base-info/device-types', {
method: 'POST',
body: payload
})
return normalizeMutation(result, '创建设备类型失败。')
} catch {
return {
success: false,
errorCode: 'REQUEST_FAILED',
message: '创建设备类型失败。'
} satisfies MutationResponse
}
}
const updateDeviceType = async (id: number, payload: DeviceTypePayload) => {
try {
const result = await api.request<unknown>(`/api/base-info/device-types/${id}`, {
method: 'PUT',
body: payload
})
return normalizeMutation(result, '更新设备类型失败。')
} catch {
return {
success: false,
errorCode: 'REQUEST_FAILED',
message: '更新设备类型失败。'
} satisfies MutationResponse
}
}
const deleteDeviceType = async (id: number) => {
try {
const result = await api.request<unknown>(`/api/base-info/device-types/${id}`, {
method: 'DELETE'
})
return normalizeMutation(result, '删除设备类型失败。')
} catch {
return {
success: false,
errorCode: 'REQUEST_FAILED',
message: '删除设备类型失败。'
} satisfies MutationResponse
}
}
return {
getDeviceTypes,
createDeviceType,
updateDeviceType,
deleteDeviceType
}
}
export const useBaseInfoApi = createSharedComposable(_useBaseInfoApi)