feat(electron-vue-template):重构认证与设备管理模块
- 统一token存取逻辑,封装getToken/setToken/removeToken方法 -优化设备ID获取逻辑,调整API路径 - 完善设备管理接口类型定义,增强类型安全 - 调整SSE连接逻辑,使用统一配置管理- 重构HTTP客户端,集中管理后端服务配置 - 更新认证相关API接口,完善请求/响应类型 - 优化设备列表展示逻辑,移除冗余字段 - 调整图片代理路径,统一API前缀 - 完善用户反馈列表展示功能,增强交互体验 - 移除冗余的错误处理逻辑,简化代码结构
This commit is contained in:
@@ -1,32 +1,31 @@
|
||||
// 极简 HTTP 工具:封装 GET/POST,按路径选择后端服务
|
||||
export type HttpMethod = 'GET' | 'POST';
|
||||
// HTTP 工具:统一管理后端服务配置和请求
|
||||
export type HttpMethod = 'GET' | 'POST' | 'DELETE';
|
||||
|
||||
const BASE_CLIENT = 'http://localhost:8081'; // erp_client_sb
|
||||
const BASE_RUOYI = 'http://192.168.1.89:8085';
|
||||
// 集中管理所有后端服务配置
|
||||
export const CONFIG = {
|
||||
CLIENT_BASE: 'http://localhost:8081',
|
||||
RUOYI_BASE: 'http://192.168.1.89:8085',
|
||||
SSE_URL: 'http://192.168.1.89:8085/monitor/account/events'
|
||||
} as const;
|
||||
|
||||
function resolveBase(path: string): string {
|
||||
// 走 ruoyi-admin 的路径:鉴权、设备管理、版本、平台工具路由
|
||||
if (path.startsWith('/monitor/account')) return BASE_RUOYI; // 账号认证相关
|
||||
if (path.startsWith('/monitor/device')) return BASE_RUOYI; // 设备管理
|
||||
if (path.startsWith('/system/')) return BASE_RUOYI; // 版本控制器 VersionController
|
||||
if (path.startsWith('/tool/banma')) return BASE_RUOYI; // 既有规则保留
|
||||
// 其他默认走客户端服务
|
||||
return BASE_CLIENT;
|
||||
// RuoYi 后端路径:鉴权、设备、反馈、版本、工具
|
||||
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 usp = new URLSearchParams();
|
||||
const query = new URLSearchParams();
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value === undefined || value === null) return;
|
||||
usp.append(key, String(value));
|
||||
if (value != null) query.append(key, String(value));
|
||||
});
|
||||
const queryString = usp.toString();
|
||||
return queryString ? `?${queryString}` : '';
|
||||
return query.toString() ? `?${query}` : '';
|
||||
}
|
||||
|
||||
// 统一请求入口:自动加上 BASE_URL、JSON 头与错误处理
|
||||
async function request<T>(path: string, options: RequestInit): Promise<T> {
|
||||
const res = await fetch(`${resolveBase(path)}${path}`, {
|
||||
credentials: 'omit',
|
||||
@@ -34,22 +33,27 @@ async function request<T>(path: string, options: RequestInit): Promise<T> {
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...(options.headers || {}),
|
||||
},
|
||||
...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();
|
||||
// 检查业务状态码
|
||||
// 业务状态码判断:支持两种格式
|
||||
// - erp_client_sb (本地服务): code=0 表示成功
|
||||
// - RuoYi 后端: code=200 表示成功
|
||||
if (json.code !== undefined && json.code !== 0 && json.code !== 200) {
|
||||
throw new Error(json.msg || json.message || '请求失败');
|
||||
throw new Error(json.msg || '请求失败');
|
||||
}
|
||||
return json as T;
|
||||
}
|
||||
|
||||
return (await res.text()) as unknown as T;
|
||||
}
|
||||
|
||||
@@ -58,40 +62,38 @@ export const http = {
|
||||
return request<T>(`${path}${buildQuery(params)}`, { method: 'GET' });
|
||||
},
|
||||
post<T>(path: string, body?: unknown) {
|
||||
return request<T>(path, { method: 'POST', body: body ? JSON.stringify(body) : undefined });
|
||||
return request<T>(path, {
|
||||
method: 'POST',
|
||||
body: body ? JSON.stringify(body) : undefined
|
||||
});
|
||||
},
|
||||
|
||||
delete<T>(path: string) {
|
||||
return request<T>(path, { method: 'DELETE' });
|
||||
},
|
||||
// 用于无需读取响应体的 POST(如删除/心跳等),从根源避免读取中断
|
||||
postVoid(path: string, body?: unknown) {
|
||||
return fetch(`${resolveBase(path)}${path}`, {
|
||||
method: 'POST',
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
credentials: 'omit',
|
||||
cache: 'no-store',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}).then(res => {
|
||||
if (!res.ok) return res.text().then(t => Promise.reject(new Error(t || `HTTP ${res.status}`)));
|
||||
return undefined as unknown as void;
|
||||
});
|
||||
},
|
||||
// 文件上传:透传 FormData,不设置 Content-Type 让浏览器自动处理
|
||||
|
||||
upload<T>(path: string, form: FormData) {
|
||||
const res = fetch(`${resolveBase(path)}${path}`, {
|
||||
return fetch(`${resolveBase(path)}${path}`, {
|
||||
method: 'POST',
|
||||
body: form,
|
||||
credentials: 'omit',
|
||||
cache: 'no-store',
|
||||
});
|
||||
return res.then(async response => {
|
||||
if (!response.ok) {
|
||||
const text = await response.text().catch(() => '');
|
||||
throw new Error(text || `HTTP ${response.status}`);
|
||||
cache: 'no-store'
|
||||
}).then(async res => {
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => '');
|
||||
throw new Error(text || `HTTP ${res.status}`);
|
||||
}
|
||||
return response.json() as Promise<T>;
|
||||
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;
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user