Files
WXProgram/miniprogram/services/apiService.ts

999 lines
28 KiB
TypeScript
Raw Permalink Normal View History

2025-10-16 21:32:16 +08:00
import { WarehouseInfo, UserInfo, DeliveryPerson, Order, EmployeeInfo } from '../types';
2025-10-19 23:38:54 +08:00
import locationTrackingService from './locationTrackingService';
2025-10-16 21:32:16 +08:00
/**
* API服务基类
* API交互的核心功能
*/
// API基础URL配置
2025-10-19 23:38:54 +08:00
const IS_LOCAL_DEV = false; // true: 本地开发环境, false: 生产环境
2025-10-16 21:32:16 +08:00
const API_BASE_URL = IS_LOCAL_DEV ? 'http://localhost:8080' : 'https://www.doubleyin.cn';
console.log(`当前API地址: ${API_BASE_URL} (${IS_LOCAL_DEV ? '本地开发环境' : '生产环境'})`);
/**
*
* 使
*/
2025-10-16 21:32:16 +08:00
/**
* API服务类
* API交互的方法
*/
class ApiService {
2025-10-19 23:38:54 +08:00
2025-10-16 21:32:16 +08:00
/**
* WebSocket连接
*/
private locationWebSocket: any | null;
/**
*
*/
constructor() {
this.locationWebSocket = null;
}
/**
*
* @param endpoint API端点路径
* @param options
* @returns Promise<T>
*/
private async request<T>(endpoint: string, options: {
method?: string;
data?: any;
headers?: Record<string, string>
} = {}): Promise<T> {
const requestUrl = `${API_BASE_URL}${endpoint}`;
// 获取全局token
const app = getApp<any>();
const token = app.globalData.token;
// 构建请求头自动添加Authorization头如果存在token
const headers: Record<string, string> = {
'Content-Type': 'application/json',
...options.headers,
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const requestOptions = {
method: options.method || 'GET',
data: options.data,
header: headers,
};
// 打印请求信息
console.log('\n========== API Request ==========');
console.log(`Method: ${requestOptions.method}`);
console.log(`URL: ${requestUrl}`);
console.log(`Headers:`, requestOptions.header);
console.log(`Data:`, requestOptions.data);
console.log('================================');
return new Promise((resolve, reject) => {
wx.request({
url: requestUrl,
method: requestOptions.method as any,
data: requestOptions.data,
header: requestOptions.header,
success: (res: any) => {
// 打印响应信息
console.log('\n========== API Response ==========');
console.log(`URL: ${requestUrl}`);
console.log(`Status: ${res.statusCode}`);
console.log(`Response Data:`, res.data);
console.log('==================================');
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve(res.data);
} else {
2025-10-21 21:51:51 +08:00
// 优先使用服务器返回的具体错误信息,如果没有则使用默认错误信息
const errorMessage = res.data || res.errMsg || '请求失败';
console.error(`API Error: HTTP ${res.statusCode}: ${errorMessage}`);
reject(new Error(`HTTP ${res.statusCode}: ${errorMessage}`));
2025-10-16 21:32:16 +08:00
}
},
fail: (err: any) => {
console.error('\n========== API Request Failed ==========');
console.error(`URL: ${requestUrl}`);
console.error(`Error: ${err.errMsg}`);
console.error('=======================================');
reject(new Error(`Request failed: ${err.errMsg}`));
}
});
});
}
// ==================== 用户模块 ====================
// ====== 认证相关 ======
/**
*
* @param code
* @returns
*/
async ServerLogin(code: string) {
console.log('API wxLogin调用参数code:', code);
return await this.request<{ user: UserInfo; token: string; openid: string; session_key: string }>('/user/wxlogin', {
method: 'POST',
data: { code: code },
});
}
/**
*
* @param userId ID
2025-10-19 13:40:20 +08:00
* @param initialLocation
2025-10-16 21:32:16 +08:00
* @returns
*/
2025-10-19 13:40:20 +08:00
async userSignIn(userId: number, initialLocation: { latitude: number; longitude: number; timestamp: number }): Promise<{ success: boolean; employeeInfo: EmployeeInfo; message?: string }> {
console.log('API userSignIn调用参数userId:', userId, 'initialLocation:', initialLocation);
// 构建请求数据,必须包含位置数据
const requestData: any = {
latitude: initialLocation.latitude,
longitude: initialLocation.longitude,
timestamp: initialLocation.timestamp
};
2025-10-16 21:32:16 +08:00
2025-10-19 23:38:54 +08:00
// 服务器现在返回统一的DTO格式直接使用
2025-10-16 21:32:16 +08:00
const response = await this.request<any>('/user/signin', {
method: 'POST',
2025-10-19 13:40:20 +08:00
data: requestData,
2025-10-16 21:32:16 +08:00
});
2025-10-19 23:38:54 +08:00
// 服务器返回格式:{ success: boolean, userInfo: UserInfoResponse }
2025-10-16 21:32:16 +08:00
return {
2025-10-19 23:38:54 +08:00
success: response.success,
2025-10-16 21:32:16 +08:00
employeeInfo: {
2025-10-19 23:38:54 +08:00
id: response.userInfo.id,
name: response.userInfo.name,
phone: response.userInfo.phone,
role: response.userInfo.role || 'DELIVERY_PERSON'
2025-10-16 21:32:16 +08:00
},
2025-10-19 23:38:54 +08:00
message: response.message
2025-10-16 21:32:16 +08:00
};
}
/**
2025-10-21 21:51:51 +08:00
*
* @param userInfo
* @returns
2025-10-16 21:32:16 +08:00
*/
async userRegister(userInfo: { name: string; phone: string }): Promise<{ success: boolean; employeeInfo: EmployeeInfo; message?: string }> {
console.log('API userRegister调用参数userInfo:', userInfo);
2025-10-21 21:51:51 +08:00
// 服务器返回直接的用户信息格式:{id, name, phone, role, openid}
2025-10-16 21:32:16 +08:00
const response = await this.request<any>('/user/register', {
method: 'POST',
data: userInfo,
});
2025-10-21 21:51:51 +08:00
// 检查响应格式,兼容不同的返回格式
if (response.id) {
// 直接返回用户信息格式
return {
success: true,
employeeInfo: {
id: response.id,
name: response.name || userInfo.name,
phone: response.phone || userInfo.phone,
role: response.role || 'DELIVERY_PERSON'
},
message: '绑定成功'
};
} else if (response.userInfo && response.userInfo.id) {
// 包装格式:{success, userInfo, message}
return {
success: response.success !== false,
employeeInfo: {
id: response.userInfo.id,
name: response.userInfo.name || userInfo.name,
phone: response.userInfo.phone || userInfo.phone,
role: response.userInfo.role || 'DELIVERY_PERSON'
},
message: response.message
};
} else {
// 未知格式,返回错误
console.error('未知的绑定响应格式:', response);
return {
success: false,
employeeInfo: {
id: 0,
name: userInfo.name,
phone: userInfo.phone,
role: 'DELIVERY_PERSON'
},
message: '绑定响应格式错误'
};
}
2025-10-16 21:32:16 +08:00
}
/**
*
*/
async logout(): Promise<void> {
return await this.request('/user/logout', { method: 'POST' });
}
2025-10-21 21:51:51 +08:00
/**
*
* openid绑定
* @returns
*/
async unbindWechat(): Promise<{ success: boolean; message?: string }> {
console.log('API unbindWechat调用');
const response = await this.request<any>('/user/unbind', {
method: 'POST',
data: {}
});
return {
success: response.success,
message: response.message
};
}
/**
* 退
* @param userId ID
* @returns 退
*/
async userSignOut(userId: number): Promise<{ success: boolean; message?: string }> {
console.log('API userSignOut调用参数userId:', userId);
2025-10-19 23:38:54 +08:00
// 服务器现在返回统一的DTO格式{ success: boolean, message: string }
const response = await this.request<any>('/user/signout', {
method: 'POST',
data: { userId },
});
2025-10-19 23:38:54 +08:00
return {
success: response.success,
message: response.message
};
}
2025-10-16 21:32:16 +08:00
/**
*
* @returns
*/
async getUserStatus(): Promise<{ status: 'signed_in' | 'signed_out' | 'registered' | 'unregistered'; lastSignInTime?: string; lastSignOutTime?: string }> {
return await this.request('/user/status', { method: 'GET' });
}
// ====== 信息相关 ======
/**
*
* @returns
*/
async getUserInfo() {
return await this.request<UserInfo>('/user/info');
}
/**
*
* @param userInfo
* @returns
*/
async updateUserInfo(userInfo: Partial<UserInfo>): Promise<UserInfo> {
return await this.request<UserInfo>('/user/update', {
method: 'PUT',
data: userInfo,
});
}
/**
*
* @returns
*/
async getUserPermissions(): Promise<string[]> {
return await this.request<string[]>('/user/permissions');
}
/**
* 线
* @returns 线
*/
async checkUserOnline(): Promise<boolean> {
return await this.request<boolean>('/user/online');
}
/**
*
* @returns
*/
async getSessionInfo(): Promise<{
userId: number;
sessionId: string;
expiresAt: number;
permissions: string[];
}> {
return await this.request<{
userId: number;
sessionId: string;
expiresAt: number;
permissions: string[];
}>('/user/session');
}
/**
*
* @param oldToken
* @returns
*/
async refreshToken(oldToken: string): Promise<{ token: string; expiresAt: number }> {
return await this.request<{ token: string; expiresAt: number }>('/user/refresh-token', {
method: 'POST',
data: { token: oldToken },
});
}
/**
*
* @param permission
* @returns
*/
async verifyPermission(permission: string): Promise<boolean> {
return await this.request<boolean>(`/user/verify-permission?permission=${permission}`);
}
// ====== 管理相关 ======
/**
*
* @param query
* @param page
* @param pageSize
* @returns
*/
async searchUsers(query: string, page: number = 1, pageSize: number = 20): Promise<{
users: UserInfo[];
total: number;
page: number;
pageSize: number;
}> {
return await this.request<{ users: UserInfo[]; total: number; page: number; pageSize: number }>(
`/user/search?query=${query}&page=${page}&pageSize=${pageSize}`
);
}
/**
*
* @param userIds ID列表
* @param status
*/
async batchUpdateUserStatus(userIds: number[], status: 'active' | 'inactive' | 'suspended'): Promise<void> {
return await this.request('/user/batch-update-status', {
method: 'POST',
data: { userIds, status },
});
}
// ====== 员工管理接口 ======
/**
*
* @returns
*/
async getEmployees(): Promise<EmployeeInfo[]> {
return await this.request<EmployeeInfo[]>('/employees');
}
/**
*
* @param employeeInfo
* @returns
*/
async addEmployee(employeeInfo: { name: string; phone: string; role: string }): Promise<EmployeeInfo> {
return await this.request<EmployeeInfo>('/employees', {
method: 'POST',
data: employeeInfo,
});
}
/**
*
* @param employeeId ID
* @returns
*/
async deleteEmployee(employeeId: number): Promise<{ success: boolean; message?: string }> {
return await this.request<{ success: boolean; message?: string }>(`/employees/${employeeId}`, {
method: 'DELETE',
});
}
/**
*
* @param employeeId ID
* @param employeeInfo
* @returns
*/
async updateEmployee(employeeId: number, employeeInfo: { name?: string; phone?: string; role?: string }): Promise<EmployeeInfo> {
return await this.request<EmployeeInfo>(`/employees/${employeeId}`, {
method: 'PUT',
data: employeeInfo,
});
}
2025-10-16 21:32:16 +08:00
// ==================== 仓库相关接口 ====================
/**
*
* @returns
*/
async getWarehouses(): Promise<WarehouseInfo[]> {
return await this.request<WarehouseInfo[]>('/warehouses');
}
/**
*
* @param id ID
* @returns
*/
async getWarehouseById(id: number): Promise<WarehouseInfo> {
return await this.request<WarehouseInfo>(`/warehouses/${id}`);
}
/**
*
* @param warehouseId ID
* @returns
*/
async getWarehouseOrders(warehouseId: number): Promise<Order[]> {
return await this.request<Order[]>(`/warehouses/${warehouseId}/orders`);
}
// ==================== 货运人员接口 ====================
/**
*
* @returns
*/
async getDeliveryPersons(): Promise<DeliveryPerson[]> {
return await this.request<DeliveryPerson[]>('/delivery-persons');
}
/**
*
* @returns
*/
async getAllDeliveryPersonLocations(): Promise<Array<{
deliveryPersonId: number;
name: string;
latitude: number;
longitude: number;
status: string;
}>> {
return await this.request<Array<{
deliveryPersonId: number;
name: string;
latitude: number;
longitude: number;
status: string;
}>>('/location-sync/delivery-persons/locations');
}
/**
*
* @param id ID
* @returns
*/
async getDeliveryPersonById(id: number): Promise<DeliveryPerson> {
return await this.request<DeliveryPerson>(`/delivery-persons/${id}`);
}
/**
*
* @param id ID
* @param location
*/
async updateDeliveryPersonLocation(id: number, location: { longitude: number; latitude: number }): Promise<void> {
return await this.request(`/delivery-persons/${id}/location`, {
method: 'PUT',
data: location,
});
}
// 地图相关接口支持
/**
* mapService参数
* @param locations
*/
async batchUpdateDeliveryPersonLocations(locations: Array<{
userId: number;
latitude: number;
longitude: number;
timestamp: number;
}>): Promise<void> {
// 转换参数格式以匹配原有API
const formattedLocations = locations.map(loc => ({
deliveryPersonId: loc.userId,
longitude: loc.longitude,
latitude: loc.latitude,
timestamp: loc.timestamp
}));
await this.request('/delivery-persons/locations/batch', {
method: 'POST',
data: { locations: formattedLocations }
});
}
/**
*
* @returns
*/
async getIdleDeliveryPersons(): Promise<DeliveryPerson[]> {
return await this.request<DeliveryPerson[]>('/delivery-persons/idle');
}
/**
*
* @returns
*/
async getBusyDeliveryPersons(): Promise<DeliveryPerson[]> {
return await this.request<DeliveryPerson[]>('/delivery-persons/busy');
}
/**
*
* @param deliveryPersonId ID
* @param limit
* @returns
*/
async getLocationHistory(deliveryPersonId: number, limit: number = 50): Promise<Array<{
timestamp: number;
longitude: number;
latitude: number;
speed?: number;
accuracy?: number;
}>> {
return await this.request<Array<{
timestamp: number;
longitude: number;
latitude: number;
speed?: number;
accuracy?: number;
}>>(`/delivery-persons/${deliveryPersonId}/location-history?limit=${limit}`);
}
/**
* ID列表
* @param deliveryPersonIds ID列表
* @returns
*/
async subscribeToRealTimeLocations(deliveryPersonIds: number[]): Promise<{
subscriptionId: string;
expiresAt: number;
}> {
// 真实环境中调用API
try {
return await this.request<{
subscriptionId: string;
expiresAt: number;
}>('/locations/subscribe', {
method: 'POST',
data: { deliveryPersonIds }
});
} catch (error) {
console.error('订阅实时位置更新失败:', error);
throw error;
}
}
/**
*
* @param subscriptionId ID
*/
async unsubscribeFromRealTimeLocations(subscriptionId: string): Promise<void> {
// 真实环境中调用API
try {
await this.request<void>('/locations/unsubscribe', {
method: 'POST',
data: { subscriptionId }
});
} catch (error) {
console.error('取消订阅实时位置更新失败:', error);
throw error;
}
}
// ===== 私有属性和方法 =====
/**
* WebSocket连接
*/
public async initLocationWebSocket(): Promise<void> {
if (this.locationWebSocket) {
console.log('WebSocket连接已存在');
return;
}
try {
if (typeof wx !== 'undefined' && typeof wx.connectSocket === 'function') {
console.log('初始化位置更新WebSocket连接小程序环境');
// 连接到服务端的WebSocket地址使用配置的服务器地址
const serverUrl = API_BASE_URL.replace('http', 'ws');
const wsUrl = `${serverUrl}/ws/location`;
2025-10-19 13:40:20 +08:00
// 获取当前用户ID从全局应用数据中获取
const app = getApp<any>();
const userInfo = app.globalData.userInfo;
const userId = userInfo?.id;
// 构建带用户ID参数的WebSocket URL
const finalWsUrl = userId ? `${wsUrl}?userId=${userId}` : wsUrl;
console.log(`WebSocket连接URL: ${finalWsUrl}`);
2025-10-16 21:32:16 +08:00
this.locationWebSocket = wx.connectSocket({
2025-10-19 13:40:20 +08:00
url: finalWsUrl,
2025-10-16 21:32:16 +08:00
header: {
'content-type': 'application/json'
}
});
// WebSocket连接打开事件
wx.onSocketOpen(() => {
console.log('WebSocket连接已打开');
});
// WebSocket消息接收事件
wx.onSocketMessage((res) => {
try {
const message = JSON.parse(typeof res.data === 'string' ? res.data : String(res.data));
this.handleWebSocketMessage(message);
} catch (error) {
console.error('解析WebSocket消息失败:', error);
}
});
// WebSocket连接关闭事件
wx.onSocketClose((res) => {
console.log('WebSocket连接已关闭', res);
2025-10-16 21:32:16 +08:00
this.locationWebSocket = null;
// 如果是非主动关闭,尝试重连
if (res.code !== 1000) { // 1000表示正常关闭
console.log('WebSocket连接异常关闭将在3秒后尝试重连');
setTimeout(() => {
if (!this.locationWebSocket) {
this.initLocationWebSocket().catch(err => {
console.error('WebSocket重连失败:', err);
});
}
}, 3000);
}
2025-10-16 21:32:16 +08:00
});
// WebSocket错误事件
wx.onSocketError((error) => {
console.error('WebSocket连接错误:', error);
this.locationWebSocket = null;
});
} else {
console.warn('当前环境不支持WebSocket连接');
}
} catch (error) {
console.error('初始化位置更新WebSocket连接失败:', error);
this.locationWebSocket = null;
}
}
/**
* WebSocket连接是否已建立
*/
public isWebSocketConnected(): boolean {
return this.locationWebSocket !== null && this.locationWebSocket !== undefined;
}
2025-10-16 21:32:16 +08:00
/**
* WebSocket连接
*/
public async closeLocationWebSocket(): Promise<void> {
if (this.locationWebSocket && typeof wx !== 'undefined' && typeof wx.closeSocket === 'function') {
try {
// 先检查WebSocket状态避免在连接过程中关闭
wx.closeSocket();
this.locationWebSocket = null;
console.log('WebSocket连接已关闭');
} catch (error) {
console.warn('关闭WebSocket连接时出现异常:', error);
// 即使关闭失败,也重置连接状态
this.locationWebSocket = null;
}
2025-10-16 21:32:16 +08:00
}
}
/**
* WebSocket消息
* @param message
*/
private handleWebSocketMessage(message: any): void {
if (!message || typeof message.type !== 'string') {
console.warn('收到无效的WebSocket消息:', message);
return;
}
2025-10-19 23:38:54 +08:00
locationTrackingService.handleWebSocketMessage(message);
2025-10-16 21:32:16 +08:00
}
2025-10-16 21:32:16 +08:00
/**
* WebSocket消息
2025-10-19 13:40:20 +08:00
* @param message
2025-10-16 21:32:16 +08:00
*/
private sendWebSocketMessage(message: any): void {
if (!this.locationWebSocket) {
console.warn('WebSocket连接未建立无法发送消息');
return;
}
try {
const messageStr = JSON.stringify(message);
if (typeof wx !== 'undefined' && typeof wx.sendSocketMessage === 'function') {
wx.sendSocketMessage({
data: messageStr
});
}
} catch (error) {
console.error('发送WebSocket消息失败:', error);
}
}
/**
*
* @param userId ID
2025-10-16 21:32:16 +08:00
*/
async subscribeToLocationUpdates(): Promise<void> {
2025-10-16 21:32:16 +08:00
// 确保WebSocket连接已建立
if (!this.locationWebSocket) {
this.initLocationWebSocket();
}
// 服务器会自动处理订阅逻辑,无需发送订阅消息
console.log('位置订阅已初始化,服务器将自动处理订阅逻辑');
2025-10-16 21:32:16 +08:00
}
/**
*
* @param userId ID
2025-10-16 21:32:16 +08:00
*/
2025-10-19 23:38:54 +08:00
async unsubscribeFromLocationUpdates(_userId: number): Promise<void> {
// 服务器会自动处理取消订阅逻辑,无需发送取消订阅消息
console.log('位置取消订阅已初始化,服务器将自动处理取消订阅逻辑');
2025-10-16 21:32:16 +08:00
}
/**
*
* @param userId ID
2025-10-16 21:32:16 +08:00
* @param latitude
* @param longitude
*/
async sendLocationUpdate(userId: number, latitude: number, longitude: number): Promise<void> {
2025-10-16 21:32:16 +08:00
// 确保WebSocket连接已建立
if (!this.locationWebSocket) {
this.initLocationWebSocket();
}
// 发送位置更新消息
const locationMessage = {
type: 'updateLocation',
userId: userId,
2025-10-16 21:32:16 +08:00
latitude: latitude,
longitude: longitude,
timestamp: Date.now()
};
this.sendWebSocketMessage(locationMessage);
}
2025-10-16 21:32:16 +08:00
// ==================== 订单接口 ====================
/**
*
* @returns
*/
async getPendingOrders(): Promise<Order[]> {
return await this.request<Order[]>('/orders/pending');
}
/**
*
* @param orderId ID
* @param deliveryPersonId ID
*/
async assignOrder(orderId: number, deliveryPersonId: number): Promise<{ success: boolean; message?: string }> {
return await this.request<{ success: boolean; message?: string }>(`/orders/${orderId}/assign`, {
method: 'POST',
data: { deliveryPersonId },
});
}
/**
*
* @param deliveryPersonId ID
* @returns
*/
async getDeliveryPersonOrders(deliveryPersonId: number): Promise<Order[]> {
return await this.request<Order[]>(`/delivery-persons/${deliveryPersonId}/orders`);
}
/**
* ID获取订单
* @param id ID
* @returns
*/
async getOrderById(id: number): Promise<Order> {
return await this.request<Order>(`/orders/${id}`);
}
/**
*
* @param orderId ID
* @param status
*/
async updateOrderStatus(orderId: number, status: Order['status']): Promise<{ success: boolean; message?: string }> {
return await this.request<{ success: boolean; message?: string }>(`/orders/${orderId}/status`, {
method: 'PUT',
data: { status },
});
}
/**
*
* @param orderData
* @returns
*/
async createOrder(orderData: Omit<Order, 'id' | 'createTime'>): Promise<Order> {
return await this.request<Order>('/orders', {
method: 'POST',
data: orderData,
});
}
/**
*
* @param orderId ID
*/
async deleteOrder(orderId: number): Promise<void> {
return await this.request(`/orders/${orderId}`, {
method: 'DELETE',
});
}
// ==================== 统计和日志接口 ====================
/**
*
* @returns
*/
async getSystemStats(): Promise<{
totalWarehouses: number;
totalDeliveryPersons: number;
pendingOrders: number;
activeOrders: number;
}> {
return await this.request<{
totalWarehouses: number;
totalDeliveryPersons: number;
pendingOrders: number;
activeOrders: number;
}>('/stats/system');
}
/**
*
* @param timeRange
* @returns
*/
async getOrderStats(timeRange: 'today' | 'week' | 'month'): Promise<{
totalOrders: number;
completedOrders: number;
inProgressOrders: number;
averageDeliveryTime: number;
}> {
return await this.request<{
totalOrders: number;
completedOrders: number;
inProgressOrders: number;
averageDeliveryTime: number;
}>(`/stats/orders?timeRange=${timeRange}`);
}
/**
*
* @returns
*/
async getUserStats(): Promise<{
totalUsers: number;
activeUsers: number;
onlineUsers: number;
newUsersToday: number;
}> {
return await this.request<{
totalUsers: number;
activeUsers: number;
onlineUsers: number;
newUsersToday: number;
}>('/user/stats');
}
/**
*
* @param userId ID
* @param limit
* @returns
*/
async getUserActivityLogs(userId: number, limit: number = 20): Promise<Array<{
id: number;
action: string;
timestamp: number;
details?: any;
}>> {
return await this.request<Array<{ id: number; action: string; timestamp: number; details?: any }>>(
`/user/${userId}/activity-logs?limit=${limit}`
);
}
/**
*
* @param error
*/
async uploadErrorLog(error: any): Promise<void> {
await this.request('/logs/error', {
method: 'POST',
data: {
error: error instanceof Error ? error.message : String(error),
stack: error instanceof Error ? error.stack : undefined,
timestamp: Date.now(),
userAgent: 'miniprogram/' + (typeof wx !== 'undefined' ? wx.getSystemInfoSync().platform : 'unknown')
}
});
}
// ==================== 系统接口 ====================
/**
*
* @returns
*/
async healthCheck(): Promise<{
status: 'ok' | 'degraded' | 'down';
message: string;
timestamp: number;
}> {
return await this.request<{
status: 'ok' | 'degraded' | 'down';
message: string;
timestamp: number;
}>('/health');
}
}
/**
* API服务单例实例
* 使
*/
export default new ApiService();