first commit

This commit is contained in:
douboer
2026-03-21 18:57:10 +08:00
commit c49aa1a5e9
570 changed files with 107167 additions and 0 deletions

View File

@@ -0,0 +1,174 @@
/* global wx, console, require, module */
const { getOpsConfig } = require("./opsConfig");
const SYNC_AUTH_STORAGE_KEY = "remoteconn.sync.auth.v1";
function logSyncAuth(level, message, extra) {
if (level === "info") return;
const payload = extra && typeof extra === "object" ? extra : {};
const writer = level === "warn" ? console.warn : level === "error" ? console.error : console.info;
writer("[sync.auth]", message, payload);
}
function readAuthCache() {
try {
const raw = wx.getStorageSync(SYNC_AUTH_STORAGE_KEY);
return raw && typeof raw === "object" ? raw : {};
} catch {
return {};
}
}
function writeAuthCache(value) {
try {
wx.setStorageSync(SYNC_AUTH_STORAGE_KEY, value && typeof value === "object" ? value : {});
} catch {
// ignore
}
}
function resolveSyncBaseUrl() {
const ops = getOpsConfig();
const raw = String(ops.gatewayUrl || "").trim();
if (!raw) {
logSyncAuth("warn", "未配置 gatewayUrl无法发起同步请求");
return "";
}
let normalized = raw;
if (normalized.startsWith("ws://")) normalized = `http://${normalized.slice(5)}`;
if (normalized.startsWith("wss://")) normalized = `https://${normalized.slice(6)}`;
if (!normalized.startsWith("http://") && !normalized.startsWith("https://")) {
normalized = `https://${normalized}`;
}
normalized = normalized.replace(/[?#].*$/, "").replace(/\/+$/, "");
const matched = normalized.match(/^(https?):\/\/([^/]+)(?:\/.*)?$/i);
if (!matched) {
logSyncAuth("warn", "gatewayUrl 非法,无法推导同步基地址", { raw });
return "";
}
const baseUrl = `${matched[1].toLowerCase()}://${matched[2]}`;
logSyncAuth("info", "同步基地址推导成功", { baseUrl });
return baseUrl;
}
function requestJson(url, options) {
logSyncAuth("info", "发起同步请求", {
method: (options && options.method) || "GET",
url
});
return new Promise((resolve, reject) => {
wx.request({
url,
method: (options && options.method) || "GET",
data: options && options.data,
header: (options && options.header) || {},
...(Number.isFinite(Number(options && options.timeoutMs)) && Number(options && options.timeoutMs) >= 1000
? { timeout: Math.round(Number(options && options.timeoutMs)) }
: {}),
success(res) {
const ok = res && res.statusCode >= 200 && res.statusCode < 300;
if (!ok) {
const message =
res && res.data && typeof res.data === "object" && res.data.message
? String(res.data.message)
: `sync request failed: ${res.statusCode}`;
logSyncAuth("warn", "同步请求返回非 2xx", {
method: (options && options.method) || "GET",
url,
statusCode: res && res.statusCode,
message
});
reject(new Error(message));
return;
}
logSyncAuth("info", "同步请求成功", {
method: (options && options.method) || "GET",
url,
statusCode: res.statusCode
});
resolve(res.data || {});
},
fail(error) {
logSyncAuth("error", "同步请求失败", {
method: (options && options.method) || "GET",
url,
error: error && error.errMsg ? error.errMsg : String(error || "")
});
reject(error);
}
});
});
}
async function loginAndFetchToken() {
const baseUrl = resolveSyncBaseUrl();
const ops = getOpsConfig();
if (!baseUrl || !ops.gatewayToken) {
logSyncAuth("warn", "同步鉴权配置不完整", {
hasBaseUrl: Boolean(baseUrl),
hasGatewayToken: Boolean(ops.gatewayToken)
});
throw new Error("sync config incomplete");
}
logSyncAuth("info", "准备执行 wx.login 获取同步令牌", { baseUrl });
const loginResult = await new Promise((resolve, reject) => {
wx.login({
success(res) {
if (!res.code) {
logSyncAuth("warn", "wx.login 成功但未返回 code");
reject(new Error("wx.login missing code"));
return;
}
logSyncAuth("info", "wx.login 成功,已拿到 code");
resolve(res);
},
fail(error) {
logSyncAuth("error", "wx.login 失败", {
error: error && error.errMsg ? error.errMsg : String(error || "")
});
reject(error);
}
});
});
const payload = await requestJson(`${baseUrl}/api/miniprogram/auth/login`, {
method: "POST",
data: { code: loginResult.code },
header: {
"content-type": "application/json",
"x-gateway-token": ops.gatewayToken
}
});
if (!payload || payload.ok !== true || !payload.token) {
throw new Error((payload && payload.message) || "sync login failed");
}
const session = {
token: String(payload.token || ""),
expiresAt: String(payload.expiresAt || "")
};
writeAuthCache(session);
logSyncAuth("info", "同步令牌获取成功", {
expiresAt: session.expiresAt
});
return session;
}
async function ensureSyncAuthToken() {
const cached = readAuthCache();
const expiresAt = +new Date(cached.expiresAt || 0);
if (cached.token && Number.isFinite(expiresAt) && expiresAt - Date.now() > 60 * 1000) {
logSyncAuth("info", "复用本地缓存的同步令牌", {
expiresAt: cached.expiresAt
});
return String(cached.token);
}
logSyncAuth("info", "本地无可用同步令牌,准备重新登录");
const session = await loginAndFetchToken();
return session.token;
}
module.exports = {
ensureSyncAuthToken,
resolveSyncBaseUrl,
requestJson
};