公网 /account/ 下绝对路径 /api/admin 会被 OpenIM 接走,无条件 res.json() 把非 JSON 响应打成英文异常。按页面路径拼接前缀,并先看状态再解析。 Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
80 lines
2.8 KiB
JavaScript
80 lines
2.8 KiB
JavaScript
/**
|
|
* 员工管理页前端请求辅助(与 admin.html 内联函数保持一致,供自动化检查引用)。
|
|
* 零 npm 依赖。
|
|
*/
|
|
'use strict';
|
|
|
|
function adminApiUrl(apiPath, pagePath) {
|
|
const pathname = pagePath != null
|
|
? pagePath
|
|
: (typeof location !== 'undefined' ? location.pathname : '/');
|
|
let prefix = String(pathname || '/');
|
|
if (prefix.length > 1 && prefix.endsWith('/')) prefix = prefix.slice(0, -1);
|
|
if (prefix === '/admin' || prefix.endsWith('/admin')) {
|
|
prefix = prefix.slice(0, -6);
|
|
}
|
|
if (prefix === '/') prefix = '';
|
|
const route = apiPath.charAt(0) === '/' ? apiPath : '/' + apiPath;
|
|
return prefix + route;
|
|
}
|
|
|
|
function httpStatusHint(status) {
|
|
const n = Number(status);
|
|
if (n === 401) return '管理口令错误或未提供';
|
|
if (n === 403) return '没有权限执行此操作';
|
|
if (n === 404) return '接口地址不正确,请从管理页重新打开';
|
|
if (n === 502 || n === 503 || n === 504) return '服务暂时不可用,请稍后重试';
|
|
if (n >= 500) return '服务暂时出错,请稍后重试';
|
|
if (n >= 400) return '请求失败,请稍后重试';
|
|
return '';
|
|
}
|
|
|
|
function toUserMessage(err) {
|
|
const raw = err && typeof err === 'object' && err.message != null
|
|
? String(err.message)
|
|
: String(err || '');
|
|
const s = raw.trim();
|
|
if (!s) return '请求失败,请稍后重试';
|
|
if (/unexpected end of json|failed to execute ['"]json['"]|json parse|not valid json|unexpected token/i.test(s)) {
|
|
return '服务器返回了无法识别的内容';
|
|
}
|
|
if (/failed to fetch|networkerror|load failed|network request failed/i.test(s)) {
|
|
return '网络异常,请检查连接后重试';
|
|
}
|
|
return s;
|
|
}
|
|
|
|
async function readAdminJson(res) {
|
|
const status = res.status;
|
|
const ctype = String((res.headers && res.headers.get && res.headers.get('content-type')) || '').toLowerCase();
|
|
let text = '';
|
|
try {
|
|
text = await res.text();
|
|
} catch {
|
|
throw new Error(httpStatusHint(status) || '无法读取服务器响应');
|
|
}
|
|
const trimmed = (text || '').trim();
|
|
if (!trimmed) {
|
|
throw new Error(httpStatusHint(status) || '服务器没有返回内容');
|
|
}
|
|
const looksJson = ctype.indexOf('json') !== -1 || trimmed.charAt(0) === '{' || trimmed.charAt(0) === '[';
|
|
if (!looksJson) {
|
|
throw new Error(httpStatusHint(status) || '服务器返回了无法识别的内容');
|
|
}
|
|
let j;
|
|
try {
|
|
j = JSON.parse(trimmed);
|
|
} catch {
|
|
throw new Error(httpStatusHint(status) || '服务器返回了无法识别的内容');
|
|
}
|
|
if (!j || typeof j !== 'object') {
|
|
throw new Error(httpStatusHint(status) || '服务器返回了无法识别的内容');
|
|
}
|
|
if (j.code !== 0) {
|
|
throw new Error(j.msg || httpStatusHint(status) || '请求失败');
|
|
}
|
|
return j.data;
|
|
}
|
|
|
|
module.exports = { adminApiUrl, httpStatusHint, toUserMessage, readAdminJson };
|