Files
lol-skin/.data/www/网页/js/bridge.js
T

207 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* =============================================
bridge.js — WebView2 消息通信桥
统一封装所有与易语言后端的 postMessage 通信
消息格式:JSON { "命令": "...", ...参数 }
后端回调格式:JSON { "命令": "...", ...结果 }
============================================= */
window.Bridge = (function () {
// ── 待回调队列(命令 → 回调列表)─────────────
const _listeners = {};
/**
* 向后端发送 WebView2 消息
* @param {object} payload 纯 JS 对象,会被 JSON.stringify 后发送
*/
function send(payload) {
try {
const msg = JSON.stringify(payload);
if (window.chrome && window.chrome.webview) {
window.chrome.webview.postMessage(msg);
} else {
console.warn('[Bridge] WebView2 不可用,消息未发送:', msg);
}
} catch (e) {
console.error('[Bridge] send 异常:', e);
}
}
/**
* 订阅来自后端的命令消息(可注册多个)
* @param {string} cmd 命令名称,如 "登录结果"
* @param {function} callback 回调函数,参数为完整消息对象
* @returns {function} 调用后可取消订阅
*/
function on(cmd, callback) {
if (!_listeners[cmd]) _listeners[cmd] = [];
_listeners[cmd].push(callback);
return function off() {
_listeners[cmd] = (_listeners[cmd] || []).filter(fn => fn !== callback);
};
}
/**
* 一次性订阅(触发一次后自动移除)
* @param {string} cmd
* @param {function} callback
*/
function once(cmd, callback) {
const off = on(cmd, function wrapper(data) {
off();
callback(data);
});
}
/**
* 发送消息并等待指定命令回调(Promise 形式,超时 10s)
* @param {object} payload 发送内容
* @param {string} replyCmd 期待后端回复的命令名
* @param {number} timeout 超时毫秒,默认 10000
*/
function call(payload, replyCmd, timeout) {
timeout = timeout || 10000;
return new Promise(function (resolve, reject) {
const timer = setTimeout(function () {
_listeners[replyCmd] = (_listeners[replyCmd] || []).filter(fn => fn !== handler);
reject(new Error('请求超时,请检查网络连接'));
}, timeout);
function handler(data) {
clearTimeout(timer);
resolve(data);
}
once(replyCmd, handler);
send(payload);
});
}
// ── 监听后端推送的 WebView2 消息 ─────────────
if (window.chrome && window.chrome.webview) {
window.chrome.webview.addEventListener('message', function (e) {
try {
const data = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;
const cmd = data['命令'] || data.cmd || '';
const cbs = _listeners[cmd];
if (cbs && cbs.length) {
// 复制一份,避免回调中修改 _listeners 影响遍历
cbs.slice().forEach(function (fn) { fn(data); });
}
} catch (err) {
console.warn('[Bridge] 解析后端消息失败:', e.data, err);
}
});
} else {
// 非 WebView2 环境(普通浏览器调试):提供模拟接口,避免报错
console.warn('[Bridge] 未检测到 WebView2,通信桥降级为模拟模式');
window._bridgeSimReceive = function (jsonStr) {
try {
const data = JSON.parse(jsonStr);
const cmd = data['命令'] || '';
const cbs = _listeners[cmd];
if (cbs && cbs.length) cbs.slice().forEach(fn => fn(data));
} catch (e) {}
};
}
// ── 窗口控制快捷方法 ─────────────────────────
const WinCtrl = {
/**
* 最小化窗口
*/
minimize: function () {
send({ '命令': '窗口控制', '动作': '最小化', '手柄': 0 });
},
/**
* 最大化 / 还原切换
*/
toggleMaximize: function () {
send({ '命令': '窗口控制', '动作': '最大化切换', '手柄': 0 });
},
/**
* 关闭窗口
*/
close: function () {
send({ '命令': '窗口控制', '动作': '关闭', '手柄': 0 });
},
/**
* 置顶 / 取消置顶切换
*/
toggleTopmost: function () {
send({ '命令': '窗口控制', '动作': '置顶切换', '手柄': 0 });
},
/**
* 拖拽移动窗口(在 mousedown 事件中调用)
*/
startMove: function () {
send({ '命令': '窗口控制', '动作': '移动窗口', '手柄': 0 });
},
/**
* 拖拽调整窗口尺寸
* @param {number} dir 方位:1上 2下 3右 4左 5左上 6右上 7右下 8左下
*/
resize: function (dir) {
send({ '命令': '窗口控制', '动作': '调整尺寸', '手柄': dir });
},
};
// ── 登录相关快捷方法 ─────────────────────────
const Auth = {
/**
* 请求自动填卡(后端回复 "自动填卡" 命令)
*/
requestAutoFill: function () {
send({ '命令': '请求自动填卡' });
},
/**
* 账号登录
* @param {string} user
* @param {string} pass
* @returns {Promise} 解析为 { 成功: bool, 消息: string, ... }
*/
login: function (user, pass) {
return call(
{ '命令': '账号登录', '账号': user, '密码': pass },
'登录结果'
);
},
/**
* 注册账号
*/
register: function (user, pass, sec, card) {
return call(
{ '命令': '注册账号', '账号': user, '密码': pass, '密保': sec, '卡密': card },
'注册结果'
);
},
/**
* 续费账号
*/
renew: function (user, card) {
return call(
{ '命令': '续费账号', '账号': user, '卡密': card },
'续费结果'
);
},
/**
* 修改密码
*/
changePwd: function (user, sec, newPass) {
return call(
{ '命令': '修改密码', '账号': user, '密保': sec, '新密码': newPass },
'改密结果'
);
},
};
return {
send: send,
on: on,
once: once,
call: call,
WinCtrl: WinCtrl,
Auth: Auth,
};
})();