Files
erp_sb/electron-vue-template/src/renderer/api/http.ts
zhangzijienbplus 1be22664c4 feat(subscription): 添加订阅功能并优化过期处理逻辑
- 扩展 trialExpiredType 类型,新增 'subscribe' 状态以支持主动订阅场景
- 新增 openSubscriptionDialog 方法,用于处理 VIP 状态点击事件
- 优化 VIP 状态卡片 UI,添加悬停与点击效果,提升交互体验
- 调整过期状态样式,保持水平布局并移除冗余按钮样式
- 在 Rakuten 组件中引入请求中断机制,提升任务控制灵活性- 更新 TrialExpiredDialog 组件,支持订阅类型提示与微信复制反馈- 修复部分 API 调用未传递 signal 参数的问题,增强请求管理能力
- 切换 Ruoyi 服务地址至生产环境配置,确保接口通信正常
- 移除部分无用代码与样式,精简组件结构
2025-10-21 11:33:41 +08:00

110 lines
3.1 KiB
TypeScript

export type HttpMethod = 'GET' | 'POST' | 'DELETE';
export const CONFIG = {
CLIENT_BASE: 'http://localhost:8081',
RUOYI_BASE: 'http://8.138.23.49:8085',
//RUOYI_BASE: 'http://192.168.1.89:8085',
SSE_URL: 'http://8.138.23.49:8085/monitor/account/events'
} as const;
function resolveBase(path: string): string {
if (path.startsWith('/monitor/') || path.startsWith('/system/') || path.startsWith('/tool/banma')) {
return CONFIG.RUOYI_BASE;
}
return CONFIG.CLIENT_BASE;
}
function buildQuery(params?: Record<string, unknown>): string {
if (!params) return '';
const query = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (value != null) query.append(key, String(value));
});
return query.toString() ? `?${query}` : '';
}
async function getToken(): Promise<string> {
try {
const tokenModule = await import('../utils/token');
return tokenModule.getToken() || '';
} catch {
return '';
}
}
async function request<T>(path: string, options: RequestInit & { signal?: AbortSignal }): Promise<T> {
const token = await getToken();
const res = await fetch(`${resolveBase(path)}${path}`, {
credentials: 'omit',
cache: 'no-store',
...options,
headers: {
'Content-Type': 'application/json',
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
...options.headers
}
});
if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(text || `HTTP ${res.status}`);
}
const contentType = res.headers.get('content-type') || '';
if (contentType.includes('application/json')) {
const json: any = await res.json();
if (json.code !== undefined && json.code !== 0 && json.code !== 200) {
throw new Error(json.msg || '请求失败');
}
return json as T;
}
return (await res.text()) as unknown as T;
}
export const http = {
get<T>(path: string, params?: Record<string, unknown>, signal?: AbortSignal) {
return request<T>(`${path}${buildQuery(params)}`, { method: 'GET', signal });
},
post<T>(path: string, body?: unknown, signal?: AbortSignal) {
return request<T>(path, {
method: 'POST',
body: body ? JSON.stringify(body) : undefined,
signal
});
},
delete<T>(path: string) {
return request<T>(path, { method: 'DELETE' });
},
async upload<T>(path: string, form: FormData, signal?: AbortSignal) {
const token = await getToken();
const res = await fetch(`${resolveBase(path)}${path}`, {
method: 'POST',
body: form,
credentials: 'omit',
cache: 'no-store',
headers: token ? { 'Authorization': `Bearer ${token}` } : {},
signal
});
if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(text || `HTTP ${res.status}`);
}
const contentType = res.headers.get('content-type') || '';
if (contentType.includes('application/json')) {
const json: any = await res.json();
if (json.code !== undefined && json.code !== 0 && json.code !== 200) {
throw new Error(json.msg || '请求失败');
}
return json as T;
}
return (await res.text()) as unknown as T;
}
};