3213 lines
142 KiB
JavaScript
3213 lines
142 KiB
JavaScript
/******/ (function() { // webpackBootstrap
|
||
/******/ "use strict";
|
||
/******/ var __webpack_modules__ = ({
|
||
|
||
/***/ 4677:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(144);
|
||
/* harmony import */ var _components_LoginView_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3727);
|
||
/* harmony import */ var _components_DocumentedShell_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8409);
|
||
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(926);
|
||
|
||
|
||
|
||
|
||
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'App',
|
||
setup(__props) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_4__/* .useSessionStore */ .B)();
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .onMounted */ .sV)(() => {
|
||
session.restore();
|
||
});
|
||
return (_ctx, _cache) => {
|
||
return !(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(session).isAuthenticated ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_components_LoginView_vue__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A, {
|
||
key: 0
|
||
})) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_components_DocumentedShell_vue__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A, {
|
||
key: 1
|
||
}));
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 865:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5130);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5187);
|
||
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(926);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2169);
|
||
|
||
const _hoisted_1 = {
|
||
class: "documented-shell"
|
||
};
|
||
const _hoisted_2 = {
|
||
class: "documented-rail"
|
||
};
|
||
const _hoisted_3 = {
|
||
class: "documented-avatar"
|
||
};
|
||
const _hoisted_4 = ["src"];
|
||
const _hoisted_5 = {
|
||
key: 1
|
||
};
|
||
const _hoisted_6 = {
|
||
class: "documented-rail-copy"
|
||
};
|
||
const _hoisted_7 = {
|
||
class: "documented-main"
|
||
};
|
||
const _hoisted_8 = {
|
||
class: "documented-header"
|
||
};
|
||
const _hoisted_9 = {
|
||
class: "documented-status"
|
||
};
|
||
const _hoisted_10 = {
|
||
class: "documented-card"
|
||
};
|
||
const _hoisted_11 = {
|
||
class: "documented-meta"
|
||
};
|
||
const _hoisted_12 = {
|
||
key: 0,
|
||
class: "form-error"
|
||
};
|
||
const _hoisted_13 = {
|
||
key: 1,
|
||
class: "form-info"
|
||
};
|
||
const _hoisted_14 = {
|
||
class: "modal-actions"
|
||
};
|
||
const _hoisted_15 = ["disabled"];
|
||
const _hoisted_16 = ["disabled"];
|
||
|
||
|
||
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'DocumentedShell',
|
||
setup(__props) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_4__/* .useSessionStore */ .B)();
|
||
const passwordDialogOpen = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)(false);
|
||
const passwordSaving = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)(false);
|
||
const passwordError = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)('');
|
||
const passwordNotice = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)('');
|
||
const passwordDraft = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .reactive */ .Kh)({
|
||
oldPassword: '',
|
||
newPassword: '',
|
||
confirmPassword: ''
|
||
});
|
||
const initials = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => String(session.displayName || session.userId || 'U').slice(0, 1).toUpperCase());
|
||
function resetPasswordDraft() {
|
||
passwordDraft.oldPassword = '';
|
||
passwordDraft.newPassword = '';
|
||
passwordDraft.confirmPassword = '';
|
||
}
|
||
function openPasswordDialog() {
|
||
passwordError.value = '';
|
||
passwordNotice.value = '';
|
||
resetPasswordDraft();
|
||
passwordDialogOpen.value = true;
|
||
}
|
||
function closePasswordDialog() {
|
||
if (passwordSaving.value) {
|
||
return;
|
||
}
|
||
passwordDialogOpen.value = false;
|
||
passwordError.value = '';
|
||
passwordNotice.value = '';
|
||
resetPasswordDraft();
|
||
}
|
||
async function savePassword() {
|
||
passwordError.value = '';
|
||
passwordNotice.value = '';
|
||
if (!passwordDraft.oldPassword || !passwordDraft.newPassword || !passwordDraft.confirmPassword) {
|
||
passwordError.value = '请填写完整密码';
|
||
return;
|
||
}
|
||
if (passwordDraft.newPassword !== passwordDraft.confirmPassword) {
|
||
passwordError.value = '两次输入的新密码不一致';
|
||
return;
|
||
}
|
||
if (passwordDraft.oldPassword === passwordDraft.newPassword) {
|
||
passwordError.value = '新密码不能与当前密码相同';
|
||
return;
|
||
}
|
||
passwordSaving.value = true;
|
||
try {
|
||
await session.changePassword({
|
||
oldPassword: passwordDraft.oldPassword,
|
||
newPassword: passwordDraft.newPassword
|
||
});
|
||
passwordNotice.value = '密码已修改,当前登录态会按文档要求失效。';
|
||
} catch (error) {
|
||
passwordError.value = error.message || '密码修改失败';
|
||
} finally {
|
||
passwordSaving.value = false;
|
||
}
|
||
}
|
||
async function logout() {
|
||
await session.logout();
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("main", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("aside", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).portrait,
|
||
alt: ""
|
||
}, null, 8, _hoisted_4)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("span", _hoisted_5, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(initials.value), 1))]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_6, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).displayName || (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).userId), 1), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).userId), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
|
||
class: "documented-rail-button",
|
||
type: "button",
|
||
onClick: openPasswordDialog
|
||
}, "修改密码"), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
|
||
class: "documented-rail-button ghost",
|
||
type: "button",
|
||
onClick: logout
|
||
}, "退出登录")]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("section", _hoisted_7, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("header", _hoisted_8, [_cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("h1", null, "文档对接模式"), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("p", null, "当前界面只保留这两份文档已经明确提供的能力。")], -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_9, [_cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "连接状态", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).connectionStatusText || '已登录'), 1)])]), _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createStaticVNode */ .Fv)("<section class=\"documented-card\"><h2>已按文档接入</h2><ul class=\"documented-list\"><li>`/auth/login_pwd` 密码登录</li><li>`/auth/register` 注册并返回 `imToken`、`accessToken`、`refreshToken`</li><li>`/auth/sendEmailCode` 邮箱验证码</li><li>`/auth/refreshToken` 过期自动刷新</li><li>`/auth/changePassword` 修改密码</li><li>`/auth/logout` 退出登录</li><li>扫码登录兼容接口:`/pc_session` 与 `/session_login/{token}`</li><li>AES-128-CBC 请求加密、响应解密、`X-Timestamp`、排除路径规则</li></ul></section><section class=\"documented-card\"><h2>当前按 1 比 1 已停用</h2><p class=\"documented-text\">下面这些旧页面功能已经不再走本地 PHP 或旧接口,因为你给的文档里没有对应定义。</p><ul class=\"documented-list muted\"><li>会话列表与消息列表</li><li>发送文字、图片、文件消息</li><li>联系人列表、添加联系人、备注</li><li>群详情、群成员、群管理</li><li>个人资料编辑与头像上传</li></ul></section>", 2)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("section", _hoisted_10, [_cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("h2", null, "当前登录态", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dl", _hoisted_11, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "用户 ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).userId || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "显示名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).displayName || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "IM Token", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).token ? '已保存' : '未保存'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "App Server", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(_config__WEBPACK_IMPORTED_MODULE_5__/* .appConfig */ .U).appServer), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[9] || (_cache[9] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "扫码服务", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(_config__WEBPACK_IMPORTED_MODULE_5__/* .appConfig */ .U).qrAppServer), 1)])])])]), passwordDialogOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "modal-backdrop",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .withModifiers */ .D$)(closePasswordDialog, ["self"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("form", {
|
||
class: "modal-panel documented-password-panel",
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .withModifiers */ .D$)(savePassword, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("header", null, [_cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("strong", null, "修改密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closePasswordDialog
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("label", null, [_cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "当前密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[0] || (_cache[0] = $event => passwordDraft.oldPassword = $event),
|
||
type: "password",
|
||
autocomplete: "current-password"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_0__/* .vModelText */ .Jo, passwordDraft.oldPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("label", null, [_cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "新密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[1] || (_cache[1] = $event => passwordDraft.newPassword = $event),
|
||
type: "password",
|
||
autocomplete: "new-password"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_0__/* .vModelText */ .Jo, passwordDraft.newPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("label", null, [_cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "确认新密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[2] || (_cache[2] = $event => passwordDraft.confirmPassword = $event),
|
||
type: "password",
|
||
autocomplete: "new-password"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_0__/* .vModelText */ .Jo, passwordDraft.confirmPassword]])]), passwordError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("p", _hoisted_12, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(passwordError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createCommentVNode */ .Q3)("", true), passwordNotice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("p", _hoisted_13, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(passwordNotice.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_14, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
disabled: passwordSaving.value,
|
||
onClick: closePasswordDialog
|
||
}, "取消", 8, _hoisted_15), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
|
||
class: "primary-inline-action",
|
||
disabled: passwordSaving.value
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(passwordSaving.value ? '保存中...' : '保存'), 9, _hoisted_16)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createCommentVNode */ .Q3)("", true)]);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 8607:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5130);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5187);
|
||
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2387);
|
||
/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2789);
|
||
/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(jr_qrcode__WEBPACK_IMPORTED_MODULE_6__);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2169);
|
||
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(926);
|
||
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(5051);
|
||
|
||
|
||
const _hoisted_1 = {
|
||
class: "login-page"
|
||
};
|
||
const _hoisted_2 = {
|
||
class: "login-panel"
|
||
};
|
||
const _hoisted_3 = {
|
||
class: "brand-lockup"
|
||
};
|
||
const _hoisted_4 = ["src", "alt"];
|
||
const _hoisted_5 = {
|
||
class: "login-tabs register-tabs",
|
||
style: {
|
||
gridTemplateColumns: 'repeat(3, minmax(0, 1fr))'
|
||
}
|
||
};
|
||
const _hoisted_6 = ["disabled"];
|
||
const _hoisted_7 = ["src"];
|
||
const _hoisted_8 = {
|
||
key: 1
|
||
};
|
||
const _hoisted_9 = {
|
||
key: 0,
|
||
class: "qr-scan-user"
|
||
};
|
||
const _hoisted_10 = ["src"];
|
||
const _hoisted_11 = {
|
||
key: 1
|
||
};
|
||
const _hoisted_12 = {
|
||
class: "qr-login-status"
|
||
};
|
||
const _hoisted_13 = ["disabled"];
|
||
const _hoisted_14 = ["autocomplete", "inputmode", "placeholder"];
|
||
const _hoisted_15 = ["disabled"];
|
||
const _hoisted_16 = {
|
||
key: 2,
|
||
class: "form-error"
|
||
};
|
||
const _hoisted_17 = {
|
||
key: 3,
|
||
class: "form-info"
|
||
};
|
||
const _hoisted_18 = {
|
||
class: "login-tabs register-tabs",
|
||
style: {
|
||
gridTemplateColumns: 'repeat(2, minmax(0, 1fr))'
|
||
}
|
||
};
|
||
const _hoisted_19 = ["autocomplete", "inputmode", "placeholder"];
|
||
const _hoisted_20 = {
|
||
key: 0
|
||
};
|
||
const _hoisted_21 = {
|
||
class: "code-row"
|
||
};
|
||
const _hoisted_22 = ["disabled"];
|
||
const _hoisted_23 = ["disabled"];
|
||
const _hoisted_24 = {
|
||
key: 1,
|
||
class: "form-error"
|
||
};
|
||
const _hoisted_25 = {
|
||
key: 2,
|
||
class: "form-info"
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const QR_CODE_PREFIX_PC_SESSION = 'wildfirechat://pcsession/';
|
||
const defaultPlatformLogo = '/favicon.ico';
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'LoginView',
|
||
setup(__props) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_8__/* .useSessionStore */ .B)();
|
||
const view = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('login');
|
||
const loginMode = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('phone');
|
||
const loginAccount = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const loginPassword = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const registerType = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(1);
|
||
const registerForm = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .reactive */ .Kh)({
|
||
number: '',
|
||
code: '',
|
||
password: '',
|
||
confirmPassword: '',
|
||
invitationCode: ''
|
||
});
|
||
const sendingCode = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(false);
|
||
const info = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const qrStatus = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('idle');
|
||
const qrCodeImage = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const qrSessionToken = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const qrUserName = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const qrUserPortrait = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
let qrGeneration = 0;
|
||
let qrExpireTimer = null;
|
||
const defaultPlatformName = _config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.appName;
|
||
const platformName = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(defaultPlatformName);
|
||
const platformLogo = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(defaultPlatformLogo);
|
||
const canSubmitLogin = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => loginAccount.value.length >= 3 && loginPassword.value.length >= 1);
|
||
const canRequestEmailCode = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => registerType.value === 2 && /\S+@\S+\.\S+/.test(registerForm.number));
|
||
const canSubmitRegister = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
|
||
if (registerForm.password.length < 1 || registerForm.password !== registerForm.confirmPassword) {
|
||
return false;
|
||
}
|
||
if (registerType.value === 2) {
|
||
return canRequestEmailCode.value && registerForm.code.length >= 1;
|
||
}
|
||
return registerForm.number.length >= 5;
|
||
});
|
||
const qrUserInitial = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => String(qrUserName.value || 'U').slice(0, 1).toUpperCase());
|
||
const qrStatusTitle = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
|
||
if (session.connecting || qrStatus.value === 'confirmed') {
|
||
return '正在进入';
|
||
}
|
||
if (qrStatus.value === 'loading') {
|
||
return '正在生成二维码';
|
||
}
|
||
if (qrStatus.value === 'scanned') {
|
||
return qrUserName.value ? `${qrUserName.value} 已扫码` : '已扫码,待确认';
|
||
}
|
||
if (qrStatus.value === 'expired') {
|
||
return '二维码已过期';
|
||
}
|
||
if (qrStatus.value === 'error') {
|
||
return '二维码加载失败';
|
||
}
|
||
return '扫码登录';
|
||
});
|
||
const qrStatusText = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
|
||
if (session.connecting || qrStatus.value === 'confirmed') {
|
||
return '登录信息已确认,正在建立连接';
|
||
}
|
||
if (qrStatus.value === 'loading') {
|
||
return '正在创建扫码登录会话';
|
||
}
|
||
if (qrStatus.value === 'scanned') {
|
||
return '请在手机 App 上确认登录';
|
||
}
|
||
if (qrStatus.value === 'expired') {
|
||
return '请刷新二维码后重新扫码';
|
||
}
|
||
if (qrStatus.value === 'error') {
|
||
return '请稍后重试';
|
||
}
|
||
return '使用已登录的手机 App 扫描二维码';
|
||
});
|
||
const qrRefreshText = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
|
||
if (qrStatus.value === 'loading') {
|
||
return '生成中...';
|
||
}
|
||
if (qrStatus.value === 'expired' || qrStatus.value === 'error') {
|
||
return '重新生成二维码';
|
||
}
|
||
return '刷新二维码';
|
||
});
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .onMounted */ .sV)(() => {
|
||
loadPlatformConfig();
|
||
});
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .onBeforeUnmount */ .xo)(() => {
|
||
stopQrLogin();
|
||
});
|
||
function clearFormMessage() {
|
||
session.error = '';
|
||
info.value = '';
|
||
}
|
||
function setLoginMode(mode) {
|
||
loginMode.value = mode;
|
||
loginAccount.value = '';
|
||
loginPassword.value = '';
|
||
clearFormMessage();
|
||
if (mode === 'qr') {
|
||
startQrLogin();
|
||
return;
|
||
}
|
||
stopQrLogin();
|
||
}
|
||
async function submitLogin() {
|
||
clearFormMessage();
|
||
const type = loginMode.value === 'email' ? 2 : 1;
|
||
await session.loginWithPassword(loginAccount.value, loginPassword.value, type);
|
||
}
|
||
function switchRegisterType(type) {
|
||
registerType.value = type;
|
||
registerForm.number = '';
|
||
registerForm.code = '';
|
||
registerForm.password = '';
|
||
registerForm.confirmPassword = '';
|
||
registerForm.invitationCode = '';
|
||
clearFormMessage();
|
||
}
|
||
async function requestEmailCode() {
|
||
clearFormMessage();
|
||
sendingCode.value = true;
|
||
try {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.requestAuthCode(registerForm.number);
|
||
info.value = '邮箱验证码已发送,请在当前注册表单中填写后继续。';
|
||
} catch (error) {
|
||
session.error = error.message || '验证码发送失败';
|
||
} finally {
|
||
sendingCode.value = false;
|
||
}
|
||
}
|
||
async function submitRegister() {
|
||
clearFormMessage();
|
||
if (registerForm.password !== registerForm.confirmPassword) {
|
||
session.error = '两次输入的密码不一致';
|
||
return;
|
||
}
|
||
const result = await session.register({
|
||
type: registerType.value,
|
||
number: registerForm.number,
|
||
code: registerType.value === 2 ? registerForm.code : '',
|
||
password: registerForm.password,
|
||
invitationCode: registerForm.invitationCode
|
||
});
|
||
if (result) {
|
||
info.value = '注册成功,正在进入系统。';
|
||
}
|
||
}
|
||
function openRegister() {
|
||
clearFormMessage();
|
||
stopQrLogin();
|
||
view.value = 'register';
|
||
}
|
||
function backToLogin() {
|
||
clearFormMessage();
|
||
loginMode.value = 'phone';
|
||
stopQrLogin();
|
||
view.value = 'login';
|
||
}
|
||
function resetQrState() {
|
||
qrStatus.value = 'idle';
|
||
qrCodeImage.value = '';
|
||
qrSessionToken.value = '';
|
||
qrUserName.value = '';
|
||
qrUserPortrait.value = '';
|
||
}
|
||
function clearQrExpireTimer() {
|
||
if (qrExpireTimer) {
|
||
window.clearTimeout(qrExpireTimer);
|
||
qrExpireTimer = null;
|
||
}
|
||
}
|
||
function stopQrLogin() {
|
||
qrGeneration += 1;
|
||
clearQrExpireTimer();
|
||
resetQrState();
|
||
}
|
||
function refreshQrLogin() {
|
||
startQrLogin(true);
|
||
}
|
||
async function startQrLogin(force = false) {
|
||
if (loginMode.value !== 'qr') {
|
||
return;
|
||
}
|
||
if (!force && qrSessionToken.value && qrCodeImage.value && !['expired', 'error'].includes(qrStatus.value)) {
|
||
return;
|
||
}
|
||
qrGeneration += 1;
|
||
const generation = qrGeneration;
|
||
clearQrExpireTimer();
|
||
clearFormMessage();
|
||
qrStatus.value = 'loading';
|
||
qrCodeImage.value = '';
|
||
qrSessionToken.value = '';
|
||
qrUserName.value = '';
|
||
qrUserPortrait.value = '';
|
||
try {
|
||
const pcSession = await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.createPcSession();
|
||
if (generation !== qrGeneration || loginMode.value !== 'qr') {
|
||
return;
|
||
}
|
||
const token = String(pcSession.token || '');
|
||
if (!token) {
|
||
throw new Error('服务端没有返回扫码 token');
|
||
}
|
||
qrSessionToken.value = token;
|
||
qrCodeImage.value = jr_qrcode__WEBPACK_IMPORTED_MODULE_6___default().getQrBase64(QR_CODE_PREFIX_PC_SESSION + token);
|
||
qrStatus.value = 'waiting';
|
||
const expireMs = Math.max(30000, Math.min(Number(pcSession.expired || 300000), 300000));
|
||
qrExpireTimer = window.setTimeout(() => {
|
||
if (generation === qrGeneration && qrStatus.value !== 'confirmed' && !session.isAuthenticated) {
|
||
qrStatus.value = 'expired';
|
||
}
|
||
}, expireMs);
|
||
pollQrLogin(generation, token);
|
||
} catch (error) {
|
||
if (generation !== qrGeneration) {
|
||
return;
|
||
}
|
||
qrStatus.value = 'error';
|
||
session.error = error.message || '二维码加载失败';
|
||
}
|
||
}
|
||
async function pollQrLogin(generation, token) {
|
||
try {
|
||
while (generation === qrGeneration && loginMode.value === 'qr' && !session.isAuthenticated) {
|
||
const payload = await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.loginWithPcSession(token);
|
||
if (generation !== qrGeneration || loginMode.value !== 'qr') {
|
||
return;
|
||
}
|
||
const code = Number(payload.code);
|
||
const data = payload.data || payload.result || {};
|
||
const status = Number(data.status);
|
||
if (code === 0 && data.imToken) {
|
||
qrStatus.value = 'confirmed';
|
||
clearQrExpireTimer();
|
||
await session.completePcSessionLogin(data);
|
||
return;
|
||
}
|
||
if (code === 20042 || status === 1 || status === 3) {
|
||
qrStatus.value = 'scanned';
|
||
qrUserName.value = data.userName || data.displayName || qrUserName.value;
|
||
qrUserPortrait.value = data.portrait || qrUserPortrait.value;
|
||
await delay(1000);
|
||
continue;
|
||
}
|
||
if (status === 0 || code === 13) {
|
||
qrStatus.value = 'waiting';
|
||
await delay(1000);
|
||
continue;
|
||
}
|
||
if (status === 4) {
|
||
qrStatus.value = 'expired';
|
||
session.error = payload.message || '扫码登录已取消';
|
||
return;
|
||
}
|
||
if (payload.message) {
|
||
throw new Error(payload.message);
|
||
}
|
||
await delay(1000);
|
||
}
|
||
} catch (error) {
|
||
if (generation === qrGeneration && loginMode.value === 'qr' && !session.isAuthenticated) {
|
||
qrStatus.value = 'error';
|
||
session.error = error.message || '扫码登录失败';
|
||
}
|
||
}
|
||
}
|
||
function delay(ms) {
|
||
return new Promise(resolve => window.setTimeout(resolve, ms));
|
||
}
|
||
async function loadPlatformConfig() {
|
||
try {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A.get(_config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.platformConfigApi, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '平台配置加载失败');
|
||
}
|
||
const config = response.data?.result || {};
|
||
const name = String(config.platformName || '').trim();
|
||
const logo = String(config.logoUrl || config.logo || '').trim();
|
||
const version = String(config.version || '').trim();
|
||
platformName.value = name || defaultPlatformName;
|
||
platformLogo.value = resolveBrandLogo(logo, version);
|
||
} catch (error) {
|
||
platformName.value = defaultPlatformName;
|
||
platformLogo.value = defaultPlatformLogo;
|
||
}
|
||
applyDocumentBrand();
|
||
}
|
||
function resolveBrandLogo(value, version = '') {
|
||
const logo = String(value || '').trim();
|
||
if (!logo) {
|
||
return defaultPlatformLogo;
|
||
}
|
||
if (/^(https?:|data:|blob:)/i.test(logo)) {
|
||
return appendBrandVersion(logo, version);
|
||
}
|
||
if (logo.startsWith('//')) {
|
||
return appendBrandVersion(`${window.location.protocol}${logo}`, version);
|
||
}
|
||
const base = logo.startsWith('/') ? _config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.adminServer : `${_config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.adminServer}/`;
|
||
return appendBrandVersion(new URL(logo, base).toString(), version);
|
||
}
|
||
function appendBrandVersion(url, version) {
|
||
if (!version || /^(data:|blob:)/i.test(url)) {
|
||
return url;
|
||
}
|
||
const parsed = new URL(url, window.location.href);
|
||
parsed.searchParams.set('v', version);
|
||
return parsed.toString();
|
||
}
|
||
function applyDocumentBrand() {
|
||
if (typeof document === 'undefined') {
|
||
return;
|
||
}
|
||
document.title = platformName.value || defaultPlatformName;
|
||
let icon = document.querySelector('link[rel="icon"]');
|
||
if (!icon) {
|
||
icon = document.createElement('link');
|
||
icon.setAttribute('rel', 'icon');
|
||
document.head.appendChild(icon);
|
||
}
|
||
icon.setAttribute('href', platformLogo.value || defaultPlatformLogo);
|
||
}
|
||
function handleBrandLogoError() {
|
||
if (platformLogo.value !== defaultPlatformLogo) {
|
||
platformLogo.value = defaultPlatformLogo;
|
||
applyDocumentBrand();
|
||
}
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("main", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("section", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("img", {
|
||
class: "brand-mark",
|
||
src: platformLogo.value,
|
||
alt: `${platformName.value} logo`,
|
||
onError: handleBrandLogoError
|
||
}, null, 40, _hoisted_4), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("h1", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(platformName.value), 1)])]), view.value === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("form", {
|
||
key: 0,
|
||
class: "login-form",
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withModifiers */ .D$)(submitLogin, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
|
||
active: loginMode.value === 'qr'
|
||
}),
|
||
onClick: _cache[0] || (_cache[0] = $event => setLoginMode('qr'))
|
||
}, "扫码登录", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
|
||
active: loginMode.value === 'phone'
|
||
}),
|
||
onClick: _cache[1] || (_cache[1] = $event => setLoginMode('phone'))
|
||
}, "手机号", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
|
||
active: loginMode.value === 'email'
|
||
}),
|
||
onClick: _cache[2] || (_cache[2] = $event => setLoginMode('email'))
|
||
}, "邮箱", 2)]), loginMode.value === 'qr' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, {
|
||
key: 0
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)(["qr-login-card", {
|
||
scanned: qrStatus.value === 'scanned',
|
||
expired: qrStatus.value === 'expired',
|
||
error: qrStatus.value === 'error'
|
||
}])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "qr-code-button",
|
||
disabled: qrStatus.value === 'loading' || (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting,
|
||
onClick: refreshQrLogin
|
||
}, [qrCodeImage.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
src: qrCodeImage.value,
|
||
alt: "扫码登录二维码"
|
||
}, null, 8, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatus.value === 'loading' ? '生成中' : '点击刷新'), 1))], 8, _hoisted_6), qrStatus.value === 'scanned' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("div", _hoisted_9, [qrUserPortrait.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
src: qrUserPortrait.value,
|
||
alt: ""
|
||
}, null, 8, _hoisted_10)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_11, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrUserInitial.value), 1))])) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatusTitle.value), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatusText.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-action",
|
||
disabled: qrStatus.value === 'loading' || (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting,
|
||
onClick: refreshQrLogin
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrRefreshText.value), 9, _hoisted_13)], 64)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, {
|
||
key: 1
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(loginMode.value === 'phone' ? '手机号' : '邮箱'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[3] || (_cache[3] = $event => loginAccount.value = $event),
|
||
autocomplete: loginMode.value === 'phone' ? 'username' : 'email',
|
||
inputmode: loginMode.value === 'phone' ? 'tel' : 'email',
|
||
placeholder: loginMode.value === 'phone' ? '请输入手机号' : '请输入邮箱'
|
||
}, null, 8, _hoisted_14), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, loginAccount.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[4] || (_cache[4] = $event => loginPassword.value = $event),
|
||
autocomplete: "current-password",
|
||
type: "password",
|
||
placeholder: "请输入密码"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, loginPassword.value]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
class: "primary-action",
|
||
disabled: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting || !canSubmitLogin.value
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting ? '登录中...' : '登录'), 9, _hoisted_15)], 64)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), info.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_17, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(info.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 32)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("form", {
|
||
key: 1,
|
||
class: "login-form",
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withModifiers */ .D$)(submitRegister, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_18, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
|
||
active: registerType.value === 1
|
||
}),
|
||
onClick: _cache[5] || (_cache[5] = $event => switchRegisterType(1))
|
||
}, "手机号注册", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
|
||
active: registerType.value === 2
|
||
}),
|
||
onClick: _cache[6] || (_cache[6] = $event => switchRegisterType(2))
|
||
}, "邮箱注册", 2)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(registerType.value === 1 ? '手机号' : '邮箱'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[7] || (_cache[7] = $event => registerForm.number = $event),
|
||
autocomplete: registerType.value === 1 ? 'tel' : 'email',
|
||
inputmode: registerType.value === 1 ? 'tel' : 'email',
|
||
placeholder: registerType.value === 1 ? '请输入手机号' : '请输入邮箱'
|
||
}, null, 8, _hoisted_19), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.number, void 0, {
|
||
trim: true
|
||
}]])]), registerType.value === 2 ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("label", _hoisted_20, [_cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "邮箱验证码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_21, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[8] || (_cache[8] = $event => registerForm.code = $event),
|
||
autocomplete: "one-time-code",
|
||
inputmode: "numeric",
|
||
placeholder: "请输入邮箱验证码"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.code, void 0, {
|
||
trim: true
|
||
}]]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "code-action",
|
||
disabled: sendingCode.value || !canRequestEmailCode.value,
|
||
onClick: requestEmailCode
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(sendingCode.value ? '发送中' : '发送验证码'), 9, _hoisted_22)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[9] || (_cache[9] = $event => registerForm.password = $event),
|
||
autocomplete: "new-password",
|
||
type: "password",
|
||
placeholder: "请输入密码"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.password]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "确认密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[10] || (_cache[10] = $event => registerForm.confirmPassword = $event),
|
||
autocomplete: "new-password",
|
||
type: "password",
|
||
placeholder: "请再次输入密码"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.confirmPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "邀请码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[11] || (_cache[11] = $event => registerForm.invitationCode = $event),
|
||
autocomplete: "off",
|
||
placeholder: "没有可留空"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.invitationCode, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
class: "primary-action",
|
||
disabled: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting || !canSubmitRegister.value
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting ? '注册中...' : '注册并登录'), 9, _hoisted_23), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_24, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), info.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_25, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(info.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 32)), view.value === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("button", {
|
||
key: 2,
|
||
class: "ghost-action",
|
||
type: "button",
|
||
onClick: openRegister
|
||
}, " 新用户注册 ")) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("button", {
|
||
key: 3,
|
||
class: "ghost-action",
|
||
type: "button",
|
||
onClick: backToLogin
|
||
}, " 返回登录 "))])]);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 2169:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
const currentHost = window.location.hostname || '127.0.0.1';
|
||
const runtimeConfig = window.JC_WEB_IM_CONFIG || {};
|
||
const appServerOrigin = `${window.location.protocol}//${currentHost}:8888`;
|
||
const qrAppServerOrigin = `${window.location.protocol}//${currentHost}:18888`;
|
||
const adminServerOrigin = `${window.location.protocol}//${currentHost}:8024`;
|
||
const appConfig = {
|
||
appName: 'Web IM',
|
||
adminServer: runtimeConfig.adminServer || undefined || adminServerOrigin,
|
||
appServer: runtimeConfig.appServer || undefined || appServerOrigin,
|
||
qrAppServer: runtimeConfig.qrAppServer || undefined || qrAppServerOrigin,
|
||
platformConfigApi: runtimeConfig.platformConfigApi || undefined || ( false ? 0 : '/api/platform_config.php'),
|
||
registerConfigApi: runtimeConfig.registerConfigApi || undefined || `${adminServerOrigin}/api/register-config`,
|
||
registerPhoneExistsApi: runtimeConfig.registerPhoneExistsApi || undefined || `${adminServerOrigin}/api/register-phone-exists`,
|
||
contactsApi: runtimeConfig.contactsApi || undefined || ( false ? 0 : '/api/contacts.php'),
|
||
updateAliasApi: runtimeConfig.updateAliasApi || undefined || ( false ? 0 : '/api/update_alias.php'),
|
||
addContactApi: runtimeConfig.addContactApi || undefined || ( false ? 0 : '/api/add_contact.php'),
|
||
conversationActionsApi: runtimeConfig.conversationActionsApi || undefined || ( false ? 0 : '/api/conversation_actions.php'),
|
||
sendMessageApi: runtimeConfig.sendMessageApi || undefined || ( false ? 0 : '/api/send_message.php'),
|
||
messageActionApi: runtimeConfig.messageActionApi || undefined || ( false ? 0 : '/api/message_action.php'),
|
||
messageDetailApi: runtimeConfig.messageDetailApi || undefined || ( false ? 0 : '/api/message_detail.php'),
|
||
messagesApi: runtimeConfig.messagesApi || undefined || ( false ? 0 : '/api/messages.php'),
|
||
profileApi: runtimeConfig.profileApi || undefined || ( false ? 0 : '/api/profile.php'),
|
||
changePasswordApi: runtimeConfig.changePasswordApi || undefined || `${appServerOrigin}/auth/changePassword`,
|
||
logoutApi: runtimeConfig.logoutApi || undefined || `${appServerOrigin}/auth/logout`,
|
||
imServerHost: runtimeConfig.imServerHost || undefined || currentHost,
|
||
imRoutePort: Number(runtimeConfig.imRoutePort || undefined || 18000),
|
||
useWss: runtimeConfig.useWss ?? undefined === 'true',
|
||
wsPath: runtimeConfig.wsPath || undefined || '/ws',
|
||
wsUrl: runtimeConfig.wsUrl || undefined || '',
|
||
sdkMode: runtimeConfig.sdkMode || undefined || 'http',
|
||
syncIntervalMs: Number(runtimeConfig.syncIntervalMs || undefined || 300),
|
||
platform: 5,
|
||
clientIdStorageKey: 'qmt-web-im-client-id',
|
||
authTokenStoragePrefix: 'qmt-web-im-auth-token-'
|
||
};
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
|
||
/* harmony export */ "U", 0, /* binding */ appConfig
|
||
/* harmony export */ ]);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 1406:
|
||
/***/ (function(__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5130);
|
||
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2261);
|
||
/* harmony import */ var _App_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7067);
|
||
|
||
|
||
|
||
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createApp */ .Ef)(_App_vue__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A).use((0,pinia__WEBPACK_IMPORTED_MODULE_1__/* .createPinia */ .Ey)()).mount('#app');
|
||
|
||
/***/ }),
|
||
|
||
/***/ 9311:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ Ln: function() { return /* binding */ appServerPost; },
|
||
/* harmony export */ Pd: function() { return /* binding */ getStoredAppAuth; },
|
||
/* harmony export */ eG: function() { return /* binding */ persistAppAuth; },
|
||
/* harmony export */ u$: function() { return /* binding */ clearStoredAppAuth; }
|
||
/* harmony export */ });
|
||
/* unused harmony exports appServerRequest, appServerGet */
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7588);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9577);
|
||
/* harmony import */ var core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6632);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4226);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4__);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9486);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5__);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(456);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6__);
|
||
/* harmony import */ var core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(4979);
|
||
/* harmony import */ var core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7__);
|
||
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(2387);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2169);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const AES_KEY = 'xczx2026!@#secKe';
|
||
const ENCRYPTION_EXCLUDE_PATHS = ['/avatar/', '/f/', '/amr2mp3', '/appVersion/check'];
|
||
const AUTH_STORAGE_KEY = 'qmt-web-im-app-auth-v1';
|
||
const AUTH_ERROR_CODE = 13;
|
||
const REFRESH_ERROR_CODE = 20045;
|
||
let importedCryptoKeyPromise = null;
|
||
let refreshPromise = null;
|
||
function storageScope() {
|
||
return _config__WEBPACK_IMPORTED_MODULE_9__/* .appConfig */ .U.appServer || '';
|
||
}
|
||
function readAuthStore() {
|
||
try {
|
||
return JSON.parse(localStorage.getItem(AUTH_STORAGE_KEY) || '{}');
|
||
} catch (error) {
|
||
return {};
|
||
}
|
||
}
|
||
function writeAuthStore(store) {
|
||
localStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify(store));
|
||
}
|
||
function normalizeAuthBundle(bundle = {}) {
|
||
const accessToken = String(bundle.accessToken || '').trim();
|
||
const refreshToken = String(bundle.refreshToken || '').trim();
|
||
if (!accessToken || !refreshToken) {
|
||
return null;
|
||
}
|
||
return {
|
||
accessToken,
|
||
refreshToken,
|
||
tokenType: String(bundle.tokenType || 'Bearer').trim() || 'Bearer',
|
||
accessTokenExpireIn: Number(bundle.accessTokenExpireIn || 0) || 0,
|
||
accessTokenExpireAt: Number(bundle.accessTokenExpireAt || 0) || 0,
|
||
refreshTokenExpireIn: Number(bundle.refreshTokenExpireIn || 0) || 0,
|
||
refreshTokenExpireAt: Number(bundle.refreshTokenExpireAt || 0) || 0
|
||
};
|
||
}
|
||
function getStoredAppAuth() {
|
||
const store = readAuthStore();
|
||
return normalizeAuthBundle(store[storageScope()]);
|
||
}
|
||
function persistAppAuth(bundle) {
|
||
const normalized = normalizeAuthBundle(bundle);
|
||
const store = readAuthStore();
|
||
if (!normalized) {
|
||
delete store[storageScope()];
|
||
writeAuthStore(store);
|
||
return null;
|
||
}
|
||
store[storageScope()] = normalized;
|
||
writeAuthStore(store);
|
||
return normalized;
|
||
}
|
||
function clearStoredAppAuth() {
|
||
persistAppAuth(null);
|
||
}
|
||
function hasFormData(value) {
|
||
return typeof FormData !== 'undefined' && value instanceof FormData;
|
||
}
|
||
function absoluteUrl(url) {
|
||
return new URL(url, window.location.origin);
|
||
}
|
||
function shouldEncrypt(url) {
|
||
const pathname = absoluteUrl(url).pathname;
|
||
return !ENCRYPTION_EXCLUDE_PATHS.some(path => pathname === path || pathname.startsWith(path));
|
||
}
|
||
function shouldAttachAuth(config) {
|
||
return !config.skipAuth;
|
||
}
|
||
function textEncoder() {
|
||
return new TextEncoder();
|
||
}
|
||
function textDecoder() {
|
||
return new TextDecoder();
|
||
}
|
||
function bytesToBase64(bytes) {
|
||
let binary = '';
|
||
bytes.forEach(byte => {
|
||
binary += String.fromCharCode(byte);
|
||
});
|
||
return btoa(binary);
|
||
}
|
||
function base64ToBytes(base64) {
|
||
const binary = atob(base64);
|
||
const bytes = new Uint8Array(binary.length);
|
||
for (let index = 0; index < binary.length; index += 1) {
|
||
bytes[index] = binary.charCodeAt(index);
|
||
}
|
||
return bytes;
|
||
}
|
||
async function getCryptoKey() {
|
||
if (!importedCryptoKeyPromise) {
|
||
importedCryptoKeyPromise = window.crypto.subtle.importKey('raw', textEncoder().encode(AES_KEY), {
|
||
name: 'AES-CBC'
|
||
}, false, ['encrypt', 'decrypt']);
|
||
}
|
||
return importedCryptoKeyPromise;
|
||
}
|
||
async function encryptPayload(plainText) {
|
||
const iv = window.crypto.getRandomValues(new Uint8Array(16));
|
||
const key = await getCryptoKey();
|
||
const encrypted = await window.crypto.subtle.encrypt({
|
||
name: 'AES-CBC',
|
||
iv
|
||
}, key, textEncoder().encode(plainText));
|
||
return `${bytesToBase64(iv)}:${bytesToBase64(new Uint8Array(encrypted))}`;
|
||
}
|
||
async function decryptPayload(cipherText) {
|
||
const [ivBase64, encryptedBase64] = String(cipherText || '').split(':', 2);
|
||
if (!ivBase64 || !encryptedBase64) {
|
||
throw new Error('Encrypted payload format is invalid');
|
||
}
|
||
const key = await getCryptoKey();
|
||
const decrypted = await window.crypto.subtle.decrypt({
|
||
name: 'AES-CBC',
|
||
iv: base64ToBytes(ivBase64)
|
||
}, key, base64ToBytes(encryptedBase64));
|
||
return textDecoder().decode(decrypted);
|
||
}
|
||
function normalizeBusinessResponse(payload) {
|
||
if (payload && typeof payload === 'object' && !Array.isArray(payload)) {
|
||
return payload;
|
||
}
|
||
return {
|
||
code: 0,
|
||
message: 'success',
|
||
data: payload
|
||
};
|
||
}
|
||
async function decodeResponsePayload(response) {
|
||
const encrypted = String(response.headers?.['x-encrypted'] || '').toLowerCase() === 'true';
|
||
if (encrypted && typeof response.data === 'string') {
|
||
const plainText = await decryptPayload(response.data);
|
||
response.data = normalizeBusinessResponse(JSON.parse(plainText));
|
||
return response;
|
||
}
|
||
response.data = normalizeBusinessResponse(response.data);
|
||
return response;
|
||
}
|
||
const client = axios__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.create({
|
||
withCredentials: false
|
||
});
|
||
client.interceptors.request.use(async config => {
|
||
const nextConfig = {
|
||
...config
|
||
};
|
||
const url = absoluteUrl(nextConfig.url || '').toString();
|
||
if (shouldAttachAuth(nextConfig)) {
|
||
const auth = getStoredAppAuth();
|
||
if (auth?.accessToken) {
|
||
nextConfig.headers = {
|
||
...(nextConfig.headers || {}),
|
||
Authorization: `${auth.tokenType || 'Bearer'} ${auth.accessToken}`
|
||
};
|
||
}
|
||
}
|
||
if (!hasFormData(nextConfig.data) && nextConfig.method?.toLowerCase() !== 'get' && shouldEncrypt(url)) {
|
||
const plainBody = JSON.stringify(nextConfig.data ?? {});
|
||
nextConfig.data = await encryptPayload(plainBody);
|
||
nextConfig.headers = {
|
||
...(nextConfig.headers || {}),
|
||
'Content-Type': 'text/plain;charset=UTF-8',
|
||
'X-Timestamp': `${Math.floor(Date.now() / 1000)}`
|
||
};
|
||
}
|
||
return nextConfig;
|
||
});
|
||
client.interceptors.response.use(async response => decodeResponsePayload(response));
|
||
async function refreshAccessToken() {
|
||
if (refreshPromise) {
|
||
return refreshPromise;
|
||
}
|
||
const auth = getStoredAppAuth();
|
||
if (!auth?.refreshToken) {
|
||
clearStoredAppAuth();
|
||
throw new Error('登录状态已失效,请重新登录');
|
||
}
|
||
refreshPromise = client.post(`${_config__WEBPACK_IMPORTED_MODULE_9__/* .appConfig */ .U.appServer}/auth/refreshToken`, {
|
||
refreshToken: auth.refreshToken
|
||
}, {
|
||
skipAuth: true
|
||
}).then(response => {
|
||
const payload = response.data || {};
|
||
if (Number(payload.code) !== 0 || !payload.data) {
|
||
if (Number(payload.code) === REFRESH_ERROR_CODE) {
|
||
clearStoredAppAuth();
|
||
}
|
||
throw new Error(payload.message || '刷新登录状态失败');
|
||
}
|
||
persistAppAuth(payload.data);
|
||
return payload.data;
|
||
}).finally(() => {
|
||
refreshPromise = null;
|
||
});
|
||
return refreshPromise;
|
||
}
|
||
async function request(config) {
|
||
const response = await client.request(config);
|
||
const payload = response.data || {};
|
||
if (Number(payload.code) === AUTH_ERROR_CODE && shouldAttachAuth(config) && !config._retriedAfterRefresh) {
|
||
await refreshAccessToken();
|
||
return request({
|
||
...config,
|
||
_retriedAfterRefresh: true
|
||
});
|
||
}
|
||
return response;
|
||
}
|
||
async function appServerRequest(config) {
|
||
return request(config);
|
||
}
|
||
async function appServerGet(url, config = {}) {
|
||
return request({
|
||
...config,
|
||
method: 'get',
|
||
url
|
||
});
|
||
}
|
||
async function appServerPost(url, data = {}, config = {}) {
|
||
return request({
|
||
...config,
|
||
method: 'post',
|
||
url,
|
||
data
|
||
});
|
||
}
|
||
|
||
/***/ }),
|
||
|
||
/***/ 4355:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ u: function() { return /* binding */ DocumentedHttpImClient; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2169);
|
||
/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5099);
|
||
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2387);
|
||
/* harmony import */ var _appServerClient__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9311);
|
||
|
||
|
||
|
||
|
||
|
||
function inferAccountType(account) {
|
||
return String(account || '').includes('@') ? 2 : 1;
|
||
}
|
||
function unwrapData(response) {
|
||
return response.data?.data ?? response.data?.result ?? null;
|
||
}
|
||
function unwrapMessage(response, fallback) {
|
||
return response.data?.message || response.data?.msg || fallback;
|
||
}
|
||
class DocumentedHttpImClient extends _httpImClient__WEBPACK_IMPORTED_MODULE_2__/* .HttpImClient */ .Y {
|
||
unsupported(feature) {
|
||
throw new Error(`当前对接文档未提供“${feature}”接口,已禁用旧本地代理链路`);
|
||
}
|
||
async loginWithPassword(account, password, type = inferAccountType(account)) {
|
||
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/login_pwd`, {
|
||
type,
|
||
number: account,
|
||
password,
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform,
|
||
clientId: this.getClientId()
|
||
}, {
|
||
skipAuth: true
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '登录失败'));
|
||
}
|
||
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(unwrapData(response));
|
||
return unwrapData(response);
|
||
}
|
||
async requestAuthCode(email) {
|
||
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/sendEmailCode`, {
|
||
email
|
||
}, {
|
||
skipAuth: true
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '验证码发送失败'));
|
||
}
|
||
return unwrapData(response);
|
||
}
|
||
async loginWithCode(account, code) {
|
||
void account;
|
||
void code;
|
||
throw new Error('接口文档未提供验证码登录接口,请使用密码登录');
|
||
}
|
||
async register({
|
||
type,
|
||
number,
|
||
code = '',
|
||
password,
|
||
invitationCode = ''
|
||
}) {
|
||
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/register`, {
|
||
type,
|
||
number,
|
||
code,
|
||
password,
|
||
clientId: this.getClientId(),
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform,
|
||
invitationCode
|
||
}, {
|
||
skipAuth: true
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '注册失败'));
|
||
}
|
||
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(unwrapData(response));
|
||
return unwrapData(response);
|
||
}
|
||
async createPcSession(userId = '') {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.qrAppServer}/pc_session`, {
|
||
flag: 1,
|
||
device_name: 'Web IM',
|
||
userId,
|
||
clientId: this.getClientId(),
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '二维码登录会话创建失败'));
|
||
}
|
||
return unwrapData(response) || {};
|
||
}
|
||
async loginWithPcSession(token) {
|
||
const url = `${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.qrAppServer}/session_login/${encodeURIComponent(token)}`;
|
||
let response;
|
||
try {
|
||
response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.post(url, null, {
|
||
withCredentials: false
|
||
});
|
||
} catch (postError) {
|
||
response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.get(url, {
|
||
withCredentials: false
|
||
});
|
||
}
|
||
this.persistAppToken(url, response);
|
||
const payload = response.data || {};
|
||
const result = payload.result ?? payload.data ?? null;
|
||
if (Number(payload.code) === 0 && result) {
|
||
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(result);
|
||
}
|
||
if ([0, 8, 9, 10, 13, 18, 20042].includes(Number(payload.code))) {
|
||
return {
|
||
...payload,
|
||
data: result
|
||
};
|
||
}
|
||
throw new Error(payload.message || '扫码登录失败');
|
||
}
|
||
async changePassword({
|
||
oldPassword,
|
||
newPassword
|
||
}) {
|
||
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.changePasswordApi, {
|
||
oldPassword,
|
||
newPassword
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '密码修改失败'));
|
||
}
|
||
return true;
|
||
}
|
||
async resetPasswordWithCode({
|
||
mobile,
|
||
resetCode,
|
||
newPassword
|
||
}) {
|
||
void mobile;
|
||
void resetCode;
|
||
void newPassword;
|
||
throw new Error('接口文档未提供重置密码接口,请联系服务端确认流程');
|
||
}
|
||
async logout() {
|
||
const auth = (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .getStoredAppAuth */ .Pd)();
|
||
if (!auth?.refreshToken) {
|
||
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .clearStoredAppAuth */ .u$)();
|
||
return true;
|
||
}
|
||
try {
|
||
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.logoutApi, {
|
||
refreshToken: auth.refreshToken
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '退出登录失败'));
|
||
}
|
||
} finally {
|
||
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .clearStoredAppAuth */ .u$)();
|
||
}
|
||
return true;
|
||
}
|
||
async fetchRemoteConversations() {
|
||
return [];
|
||
}
|
||
async fetchRemoteMessages() {
|
||
return [];
|
||
}
|
||
async getServerContactList() {
|
||
return [];
|
||
}
|
||
async getProfile() {
|
||
return null;
|
||
}
|
||
async sendTextMessage() {
|
||
this.unsupported('发送消息');
|
||
}
|
||
async sendAttachmentMessage() {
|
||
this.unsupported('发送附件消息');
|
||
}
|
||
async addContact() {
|
||
this.unsupported('添加联系人');
|
||
}
|
||
async updateContactAlias() {
|
||
this.unsupported('联系人备注');
|
||
}
|
||
async createGroup() {
|
||
this.unsupported('创建群组');
|
||
}
|
||
async joinGroup() {
|
||
this.unsupported('加入群组');
|
||
}
|
||
async broadcastMessage() {
|
||
this.unsupported('群发消息');
|
||
}
|
||
async getGroupDetail() {
|
||
this.unsupported('群详情');
|
||
}
|
||
async getGroupMembers() {
|
||
this.unsupported('群成员');
|
||
}
|
||
async updateGroupAlias() {
|
||
this.unsupported('群备注');
|
||
}
|
||
async leaveGroup() {
|
||
this.unsupported('退出群组');
|
||
}
|
||
async dismissGroup() {
|
||
this.unsupported('解散群组');
|
||
}
|
||
async transferGroup() {
|
||
this.unsupported('转让群组');
|
||
}
|
||
async setGroupAdmins() {
|
||
this.unsupported('设置群管理员');
|
||
}
|
||
async updateGroupProfile() {
|
||
this.unsupported('更新群资料');
|
||
}
|
||
async kickGroupMembers() {
|
||
this.unsupported('移除群成员');
|
||
}
|
||
async updateGroupMuteSetting() {
|
||
this.unsupported('群禁言设置');
|
||
}
|
||
async updateProfile() {
|
||
this.unsupported('更新个人资料');
|
||
}
|
||
async recallMessage() {
|
||
this.unsupported('撤回消息');
|
||
}
|
||
async editMessage() {
|
||
this.unsupported('编辑消息');
|
||
}
|
||
async getMessageDetail() {
|
||
this.unsupported('消息详情');
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
|
||
/***/ 5099:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ Y: function() { return /* binding */ HttpImClient; }
|
||
/* harmony export */ });
|
||
/* unused harmony export imClient */
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4114);
|
||
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2489);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(116);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7588);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5__);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1701);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6__);
|
||
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(3579);
|
||
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7__);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(5367);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8__);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2731);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9__);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(7642);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(8004);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11__);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(3853);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12__);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(5876);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(2475);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14__);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(5024);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15__);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(1698);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16__);
|
||
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(2387);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(2169);
|
||
/* harmony import */ var _services_appServerClient__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(9311);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const LOCAL_MESSAGE_STORAGE_KEY = 'qmt-web-im-local-messages-v2';
|
||
const LOCAL_HIDDEN_MESSAGE_STORAGE_KEY = 'qmt-web-im-hidden-messages-v1';
|
||
const LOCAL_RECALLED_MESSAGE_STORAGE_KEY = 'qmt-web-im-recalled-messages-v1';
|
||
function scopedStorageKey(baseKey, userId = '') {
|
||
const scope = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer || ''}:${userId || 'anonymous'}`;
|
||
return `${baseKey}:${encodeURIComponent(scope)}`;
|
||
}
|
||
function randomId() {
|
||
if (window.crypto && window.crypto.randomUUID) {
|
||
return window.crypto.randomUUID().replaceAll('-', '');
|
||
}
|
||
return `${Date.now()}${Math.random().toString(16).slice(2)}`;
|
||
}
|
||
function readLocalMessages(userId) {
|
||
try {
|
||
return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId)) || '{}');
|
||
} catch (error) {
|
||
return {};
|
||
}
|
||
}
|
||
function readMessageSet(storageKey, userId) {
|
||
try {
|
||
return JSON.parse(localStorage.getItem(scopedStorageKey(storageKey, userId)) || '{}');
|
||
} catch (error) {
|
||
return {};
|
||
}
|
||
}
|
||
function writeMessageSet(storageKey, messagesByConversation, userId) {
|
||
localStorage.setItem(scopedStorageKey(storageKey, userId), JSON.stringify(messagesByConversation));
|
||
}
|
||
function messageKeys(message) {
|
||
return [message?.id, message?.messageUid].filter(Boolean).map(value => String(value));
|
||
}
|
||
function hasStoredMessage(storageKey, conversationId, message, userId) {
|
||
const stored = readMessageSet(storageKey, userId);
|
||
const ids = new Set(stored[conversationId] || []);
|
||
return messageKeys(message).some(id => ids.has(id));
|
||
}
|
||
function storeMessageKeys(storageKey, conversationId, messages, userId) {
|
||
const stored = readMessageSet(storageKey, userId);
|
||
const ids = new Set(stored[conversationId] || []);
|
||
messages.forEach(message => {
|
||
messageKeys(message).forEach(id => ids.add(id));
|
||
});
|
||
stored[conversationId] = Array.from(ids);
|
||
writeMessageSet(storageKey, stored, userId);
|
||
}
|
||
function withRecalledState(message) {
|
||
return {
|
||
...message,
|
||
status: 'recalled',
|
||
deliveryStatus: '',
|
||
recalled: true,
|
||
recallStatus: '已撤回'
|
||
};
|
||
}
|
||
function applyLocalMessageState(conversationId, messages, userId) {
|
||
return messages.filter(message => !hasStoredMessage(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversationId, message, userId)).map(message => {
|
||
const isRecalled = Boolean(message.recalled) || message.status === 'recalled' || hasStoredMessage(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversationId, message, userId);
|
||
if (!isRecalled) {
|
||
return message;
|
||
}
|
||
return withRecalledState(message);
|
||
});
|
||
}
|
||
function writeLocalMessages(messagesByConversation, userId) {
|
||
localStorage.setItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId), JSON.stringify(messagesByConversation));
|
||
}
|
||
function saveLocalMessage(message, userId) {
|
||
const messagesByConversation = readLocalMessages(userId);
|
||
messagesByConversation[message.conversationId] = messagesByConversation[message.conversationId] || [];
|
||
const index = messagesByConversation[message.conversationId].findIndex(item => item.id === message.id);
|
||
if (index >= 0) {
|
||
messagesByConversation[message.conversationId].splice(index, 1, message);
|
||
} else {
|
||
messagesByConversation[message.conversationId].push(message);
|
||
}
|
||
writeLocalMessages(messagesByConversation, userId);
|
||
}
|
||
function mergeSyncedMessages(localMessages, remoteMessages, conversationId, userId) {
|
||
const visibleLocalMessages = applyLocalMessageState(conversationId, localMessages, userId);
|
||
const localByKey = new Map();
|
||
visibleLocalMessages.forEach(message => {
|
||
messageKeys(message).forEach(key => {
|
||
if (!localByKey.has(key)) {
|
||
localByKey.set(key, message);
|
||
}
|
||
});
|
||
});
|
||
const visibleRemoteMessages = applyLocalMessageState(conversationId, remoteMessages, userId).map(remoteMessage => {
|
||
if (!remoteMessage.recalled || String(remoteMessage.text || '').trim()) {
|
||
return remoteMessage;
|
||
}
|
||
const localMessage = messageKeys(remoteMessage).map(key => localByKey.get(key)).find(message => message?.text && message.text !== '你撤回了一条消息');
|
||
return localMessage ? {
|
||
...remoteMessage,
|
||
text: localMessage.text
|
||
} : remoteMessage;
|
||
});
|
||
const remoteKeys = new Set();
|
||
visibleRemoteMessages.forEach(message => {
|
||
messageKeys(message).forEach(key => remoteKeys.add(key));
|
||
});
|
||
const now = Date.now();
|
||
function hasRemoteMatch(localMessage) {
|
||
if (localMessage.messageUid && remoteKeys.has(localMessage.messageUid)) {
|
||
return true;
|
||
}
|
||
return visibleRemoteMessages.some(remoteMessage => {
|
||
return remoteMessage.direction === localMessage.direction && remoteMessage.text === localMessage.text && Math.abs(Number(remoteMessage.timestamp || 0) - Number(localMessage.timestamp || 0)) < 15000;
|
||
});
|
||
}
|
||
const pendingLocalMessages = visibleLocalMessages.filter(message => {
|
||
if (message.status === 'recalled' || message.recalled) {
|
||
return message.direction === 'out' && !hasRemoteMatch(message);
|
||
}
|
||
if (message.direction !== 'out') {
|
||
return false;
|
||
}
|
||
if (message.status === 'sent' && message.messageUid) {
|
||
return !hasRemoteMatch(message);
|
||
}
|
||
if (message.status === 'sent') {
|
||
return !hasRemoteMatch(message) && now - Number(message.timestamp || 0) < 30000;
|
||
}
|
||
return message.status === 'sending' || message.status === 'failed';
|
||
});
|
||
return [...visibleRemoteMessages, ...pendingLocalMessages].sort((a, b) => {
|
||
return Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0);
|
||
});
|
||
}
|
||
function getTitle(value, fallback) {
|
||
return value || fallback || '';
|
||
}
|
||
function getUniqueEquipment(mobile, fallback) {
|
||
const allowedDevices = {
|
||
'18301902119': '67072d37062c4f31b1165073552933ba',
|
||
'18301902116': '1777479418113eeea8e236edce',
|
||
'18301902118': 'de89fb2f2a61480a8c381f6c16e28bd8',
|
||
'18301902117': 'd117f480faa64145b6162107b1b49617'
|
||
};
|
||
return allowedDevices[mobile] || localStorage.getItem('uniqueEquipment') || fallback;
|
||
}
|
||
function canUseLocalLoginFallback(response) {
|
||
const message = response.data?.message || '';
|
||
return false && 0;
|
||
}
|
||
class HttpImClient {
|
||
constructor() {
|
||
this.listeners = new Map();
|
||
this.connected = false;
|
||
this.currentUser = null;
|
||
}
|
||
getClientId() {
|
||
let clientId = localStorage.getItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey);
|
||
if (!clientId) {
|
||
clientId = randomId();
|
||
localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey, clientId);
|
||
}
|
||
return clientId;
|
||
}
|
||
restoreClientId(clientId) {
|
||
if (clientId) {
|
||
localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey, clientId);
|
||
}
|
||
}
|
||
getSdkVersion() {
|
||
return 'HTTP';
|
||
}
|
||
async ensureSdk() {
|
||
return true;
|
||
}
|
||
async loginWithPassword(mobile, password) {
|
||
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/login_pwd`;
|
||
const deviceId = getUniqueEquipment(mobile, this.getClientId());
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, {
|
||
mobile,
|
||
password,
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform,
|
||
clientId: deviceId,
|
||
uniqueEquipment: deviceId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
this.persistAppToken(url, response);
|
||
if (response.data?.code !== 0) {
|
||
if (canUseLocalLoginFallback(response)) {
|
||
return {
|
||
userId: mobile,
|
||
token: `local-device-pending-${Date.now()}`,
|
||
displayName: mobile,
|
||
localOnly: true
|
||
};
|
||
}
|
||
throw new Error(response.data?.message || '登录失败');
|
||
}
|
||
return response.data.result;
|
||
}
|
||
async requestAuthCode(mobile) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/send_code`, {
|
||
mobile
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '验证码发送失败');
|
||
}
|
||
return response.data.result;
|
||
}
|
||
async loginWithCode(mobile, code) {
|
||
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/login`;
|
||
const deviceId = getUniqueEquipment(mobile, this.getClientId());
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, {
|
||
mobile,
|
||
code,
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform,
|
||
clientId: deviceId,
|
||
uniqueEquipment: deviceId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
this.persistAppToken(url, response);
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '登录失败');
|
||
}
|
||
return response.data.result;
|
||
}
|
||
async createPcSession(userId = '') {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/pc_session`, {
|
||
flag: 1,
|
||
device_name: 'Web IM',
|
||
userId,
|
||
clientId: this.getClientId(),
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '二维码登录会话创建失败');
|
||
}
|
||
return response.data.result || {};
|
||
}
|
||
async loginWithPcSession(token) {
|
||
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/session_login/${encodeURIComponent(token)}`;
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, null, {
|
||
withCredentials: false
|
||
});
|
||
this.persistAppToken(url, response);
|
||
const data = response.data || {};
|
||
if ([0, 8, 9, 10, 18].includes(Number(data.code))) {
|
||
return data;
|
||
}
|
||
throw new Error(data.message || '扫码登录失败');
|
||
}
|
||
async registerWithPhone(mobile, code) {
|
||
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/register`;
|
||
const deviceId = getUniqueEquipment(mobile, this.getClientId());
|
||
try {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, {
|
||
mobile,
|
||
code,
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform,
|
||
clientId: deviceId,
|
||
uniqueEquipment: deviceId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
this.persistAppToken(url, response);
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '注册失败');
|
||
}
|
||
return response.data.result;
|
||
} catch (error) {
|
||
const status = error.response?.status;
|
||
if (status === 404 || status === 405) {
|
||
return this.loginWithCode(mobile, code);
|
||
}
|
||
throw error;
|
||
}
|
||
}
|
||
connect(userId, token) {
|
||
this.currentUser = {
|
||
userId,
|
||
token
|
||
};
|
||
this.connected = true;
|
||
this.emit('connectionStatusChanged', {
|
||
connected: true,
|
||
statusText: '已连接'
|
||
});
|
||
this.refreshConversationList();
|
||
}
|
||
disconnect() {
|
||
this.connected = false;
|
||
this.currentUser = null;
|
||
this.emit('connectionStatusChanged', {
|
||
connected: false,
|
||
statusText: '未连接'
|
||
});
|
||
}
|
||
getConversationList() {
|
||
return [];
|
||
}
|
||
refreshConversationList() {
|
||
const conversations = this.getConversationList();
|
||
if (conversations.length) {
|
||
this.emit('conversationsChanged', conversations);
|
||
}
|
||
if (this.currentUser?.userId) {
|
||
this.fetchRemoteConversations().then(remoteConversations => {
|
||
this.emit('conversationsChanged', remoteConversations);
|
||
}).catch(() => {});
|
||
}
|
||
return conversations;
|
||
}
|
||
async fetchRemoteConversations(limit = 50) {
|
||
if (!this.currentUser?.userId) {
|
||
return [];
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messagesApi, {
|
||
userId: this.currentUser.userId,
|
||
limit
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '会话同步失败');
|
||
}
|
||
return (response.data?.result?.conversations || []).map(conversation => ({
|
||
...conversation,
|
||
updatedAt: Number(conversation.updatedAt || Date.now()),
|
||
avatarText: conversation.avatarText || String(conversation.title || conversation.target || '?').slice(0, 1).toUpperCase(),
|
||
raw: conversation.raw || {
|
||
type: 'single',
|
||
target: conversation.target,
|
||
line: 0
|
||
}
|
||
}));
|
||
}
|
||
getMessages(conversation) {
|
||
if (!conversation?.id) {
|
||
return [];
|
||
}
|
||
const userId = this.currentUser?.userId || '';
|
||
return applyLocalMessageState(conversation.id, readLocalMessages(userId)[conversation.id] || [], userId);
|
||
}
|
||
async fetchRemoteMessages(conversation, limit = 50, options = {}) {
|
||
if (!conversation?.id || !this.currentUser?.userId) {
|
||
return [];
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messagesApi, {
|
||
userId: this.currentUser.userId,
|
||
target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''),
|
||
limit,
|
||
conversationType: conversation.type || conversation.raw?.type || 0,
|
||
markRead: Boolean(options.markRead)
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '消息同步失败');
|
||
}
|
||
const messages = (response.data?.result?.messages || []).map(message => ({
|
||
...message,
|
||
displayTimestamp: message.displayTimestamp || message.timestamp,
|
||
conversationId: conversation.id
|
||
}));
|
||
const userId = this.currentUser?.userId || '';
|
||
const messagesByConversation = readLocalMessages(userId);
|
||
messagesByConversation[conversation.id] = mergeSyncedMessages(messagesByConversation[conversation.id] || [], messages, conversation.id, userId);
|
||
writeLocalMessages(messagesByConversation, userId);
|
||
return messagesByConversation[conversation.id];
|
||
}
|
||
hideMessages(conversation, messages) {
|
||
const items = Array.isArray(messages) ? messages : [messages];
|
||
if (!conversation?.id || !items.length) {
|
||
return;
|
||
}
|
||
const userId = this.currentUser?.userId || '';
|
||
storeMessageKeys(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversation.id, items, userId);
|
||
const messagesByConversation = readLocalMessages(userId);
|
||
messagesByConversation[conversation.id] = applyLocalMessageState(conversation.id, messagesByConversation[conversation.id] || [], userId);
|
||
writeLocalMessages(messagesByConversation, userId);
|
||
}
|
||
markMessagesRecalled(conversation, messages) {
|
||
const items = Array.isArray(messages) ? messages : [messages];
|
||
if (!conversation?.id || !items.length) {
|
||
return;
|
||
}
|
||
const userId = this.currentUser?.userId || '';
|
||
storeMessageKeys(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversation.id, items, userId);
|
||
const messagesByConversation = readLocalMessages(userId);
|
||
messagesByConversation[conversation.id] = applyLocalMessageState(conversation.id, messagesByConversation[conversation.id] || [], userId);
|
||
writeLocalMessages(messagesByConversation, userId);
|
||
}
|
||
async recallMessage(conversation, message) {
|
||
const messageUid = String(message?.messageUid || message?.id || '').trim();
|
||
if (!/^\d+$/.test(messageUid)) {
|
||
throw new Error('缺少可撤回的消息ID');
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageActionApi, {
|
||
action: 'recall',
|
||
userId: this.currentUser?.userId || message.from || '',
|
||
messageUid
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '撤回失败');
|
||
}
|
||
this.markMessagesRecalled(conversation, [message]);
|
||
return response.data.result;
|
||
}
|
||
async editMessage(conversation, message, text) {
|
||
const messageUid = String(message?.messageUid || message?.id || '').trim();
|
||
if (!/^\d+$/.test(messageUid)) {
|
||
throw new Error('缺少可编辑的消息ID');
|
||
}
|
||
const nextText = String(text || '').trim();
|
||
if (!nextText) {
|
||
throw new Error('编辑内容不能为空');
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageActionApi, {
|
||
action: 'edit',
|
||
userId: this.currentUser?.userId || message.from || '',
|
||
messageUid,
|
||
text: nextText
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '编辑失败');
|
||
}
|
||
const result = response.data?.result?.message || {};
|
||
const editedMessage = {
|
||
...message,
|
||
text: result.text || nextText,
|
||
status: 'delivered',
|
||
deliveryStatus: 'delivered',
|
||
editedAt: Number(result.editedAt || Date.now()),
|
||
activityTimestamp: Number(result.editedAt || Date.now())
|
||
};
|
||
saveLocalMessage(editedMessage, this.currentUser?.userId || '');
|
||
this.emit('messageStatusChanged', editedMessage);
|
||
return editedMessage;
|
||
}
|
||
async getMessageDetail(conversation, message) {
|
||
const messageUid = String(message?.messageUid || message?.id || '').trim();
|
||
if (!messageUid) {
|
||
throw new Error('缺少消息ID');
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageDetailApi, {
|
||
userId: this.currentUser?.userId || '',
|
||
target: conversation?.target || conversation?.raw?.target || conversation?.id?.replace(/^single-/, '') || '',
|
||
conversationType: conversation?.type || conversation?.raw?.type || 'single',
|
||
messageUid
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '消息详情加载失败');
|
||
}
|
||
return response.data?.result?.detail || null;
|
||
}
|
||
async sendTextMessage(conversation, text, initialMessage = null) {
|
||
const senderRole = conversation?.role || conversation?.raw?.role || '';
|
||
const message = initialMessage || {
|
||
id: randomId(),
|
||
conversationId: conversation.id,
|
||
from: this.currentUser?.userId || 'me',
|
||
senderRole,
|
||
direction: 'out',
|
||
type: 'text',
|
||
text,
|
||
status: 'sending',
|
||
deliveryStatus: 'sending',
|
||
timestamp: Date.now()
|
||
};
|
||
saveLocalMessage(message, this.currentUser?.userId || '');
|
||
if (!initialMessage) {
|
||
this.emit('messageSent', message);
|
||
}
|
||
try {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.sendMessageApi, {
|
||
sender: this.currentUser?.userId || '',
|
||
target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''),
|
||
conversationType: conversation.type || conversation.raw?.type || 0,
|
||
text
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '发送失败');
|
||
}
|
||
const sentMessage = {
|
||
...message,
|
||
status: 'sent',
|
||
deliveryStatus: 'sent',
|
||
messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '',
|
||
senderRole: response.data?.result?.senderRole || message.senderRole || '',
|
||
serverTimestamp: Number(response.data?.result?.timestamp || 0) || null,
|
||
timestamp: message.timestamp,
|
||
displayTimestamp: message.displayTimestamp || message.timestamp
|
||
};
|
||
saveLocalMessage(sentMessage, this.currentUser?.userId || '');
|
||
this.emit('messageStatusChanged', sentMessage);
|
||
return sentMessage;
|
||
} catch (error) {
|
||
const failedMessage = {
|
||
...message,
|
||
status: 'failed',
|
||
deliveryStatus: '',
|
||
error: error.response?.data?.message || error.message || '发送失败'
|
||
};
|
||
saveLocalMessage(failedMessage, this.currentUser?.userId || '');
|
||
this.emit('messageStatusChanged', failedMessage);
|
||
return failedMessage;
|
||
}
|
||
}
|
||
async sendAttachmentMessage(conversation, {
|
||
type,
|
||
file,
|
||
text = ''
|
||
}, initialMessage = null) {
|
||
const senderRole = conversation?.role || conversation?.raw?.role || '';
|
||
const message = initialMessage || {
|
||
id: randomId(),
|
||
conversationId: conversation.id,
|
||
from: this.currentUser?.userId || 'me',
|
||
senderRole,
|
||
direction: 'out',
|
||
type,
|
||
text,
|
||
attachment: {
|
||
type,
|
||
name: file?.name || (type === 'image' ? '图片' : '文件'),
|
||
mime: file?.type || '',
|
||
size: file?.size || 0,
|
||
url: type === 'image' && file ? URL.createObjectURL(file) : ''
|
||
},
|
||
status: 'sending',
|
||
deliveryStatus: 'sending',
|
||
timestamp: Date.now()
|
||
};
|
||
saveLocalMessage(message, this.currentUser?.userId || '');
|
||
if (!initialMessage) {
|
||
this.emit('messageSent', message);
|
||
}
|
||
try {
|
||
const formData = new FormData();
|
||
formData.append('sender', this.currentUser?.userId || '');
|
||
formData.append('target', conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''));
|
||
formData.append('conversationType', conversation.type || conversation.raw?.type || 0);
|
||
formData.append('messageType', type);
|
||
formData.append('text', text || '');
|
||
formData.append('attachment', file);
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.sendMessageApi, formData, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '发送失败');
|
||
}
|
||
const sentMessage = {
|
||
...message,
|
||
status: 'sent',
|
||
deliveryStatus: 'sent',
|
||
messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '',
|
||
senderRole: response.data?.result?.senderRole || message.senderRole || '',
|
||
attachment: response.data?.result?.attachment || message.attachment,
|
||
serverTimestamp: Number(response.data?.result?.timestamp || 0) || null,
|
||
timestamp: message.timestamp,
|
||
displayTimestamp: message.displayTimestamp || message.timestamp
|
||
};
|
||
saveLocalMessage(sentMessage, this.currentUser?.userId || '');
|
||
this.emit('messageStatusChanged', sentMessage);
|
||
return sentMessage;
|
||
} catch (error) {
|
||
const failedMessage = {
|
||
...message,
|
||
status: 'failed',
|
||
deliveryStatus: '',
|
||
error: error.response?.data?.message || error.message || '发送失败'
|
||
};
|
||
saveLocalMessage(failedMessage, this.currentUser?.userId || '');
|
||
this.emit('messageStatusChanged', failedMessage);
|
||
return failedMessage;
|
||
}
|
||
}
|
||
getContactList() {
|
||
return [];
|
||
}
|
||
async getServerContactList(userId) {
|
||
if (!userId) {
|
||
return [];
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.contactsApi, {
|
||
userId
|
||
}, {
|
||
withCredentials: false,
|
||
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.contactsApi)
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '联系人加载失败');
|
||
}
|
||
return (response.data?.result?.contacts || []).map(item => {
|
||
return this.mapContact(item.uid, {
|
||
alias: item.alias
|
||
}, {
|
||
uid: item.uid,
|
||
displayName: item.displayName,
|
||
name: item.name,
|
||
mobile: item.mobile,
|
||
portrait: item.portrait,
|
||
address: item.address,
|
||
friendAlias: item.alias
|
||
});
|
||
}).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN'));
|
||
}
|
||
async addContact(userId, keyword, reason = '') {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.addContactApi, {
|
||
userId,
|
||
keyword,
|
||
reason
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '添加联系人失败');
|
||
}
|
||
const item = response.data?.result?.contact;
|
||
if (!item?.uid) {
|
||
return null;
|
||
}
|
||
return this.mapContact(item.uid, {
|
||
alias: item.alias
|
||
}, {
|
||
uid: item.uid,
|
||
displayName: item.displayName,
|
||
name: item.name,
|
||
mobile: item.mobile,
|
||
portrait: item.portrait,
|
||
address: item.address,
|
||
friendAlias: item.alias
|
||
});
|
||
}
|
||
normalizeConversation(conversation) {
|
||
const title = getTitle(conversation?.title, conversation?.target || '');
|
||
return {
|
||
...conversation,
|
||
id: conversation?.id || `${conversation?.type === 'single' ? 'single' : 'group'}-${conversation?.target}`,
|
||
target: conversation?.target || conversation?.raw?.target || '',
|
||
title,
|
||
subtitle: conversation?.subtitle || '',
|
||
unread: Number(conversation?.unread || 0),
|
||
portrait: conversation?.portrait || '',
|
||
avatarText: conversation?.avatarText || title.slice(0, 1).toUpperCase(),
|
||
updatedAt: Number(conversation?.updatedAt || Date.now()),
|
||
raw: conversation?.raw || {
|
||
type: conversation?.type === 'single' ? 'single' : 'group',
|
||
target: conversation?.target || '',
|
||
line: 0
|
||
}
|
||
};
|
||
}
|
||
async createGroup(userId, {
|
||
name,
|
||
memberIds = [],
|
||
announcement = '',
|
||
welcomeText = '',
|
||
channel = false
|
||
}) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: channel ? 'create_channel' : 'create_group',
|
||
userId,
|
||
name,
|
||
memberIds,
|
||
announcement,
|
||
welcomeText
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || (channel ? '创建公告群失败' : '创建群组失败'));
|
||
}
|
||
return this.normalizeConversation(response.data?.result?.conversation || {});
|
||
}
|
||
async joinGroup(userId, groupKey) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'join_group',
|
||
userId,
|
||
groupKey
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '加入群组失败');
|
||
}
|
||
return this.normalizeConversation(response.data?.result?.conversation || {});
|
||
}
|
||
async broadcastMessage(userId, targetIds, text) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'broadcast',
|
||
userId,
|
||
targetIds,
|
||
text
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '群发失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async getGroupDetail(userId, groupId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'group_detail',
|
||
userId,
|
||
groupId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '群资料加载失败');
|
||
}
|
||
return response.data?.result?.group || null;
|
||
}
|
||
async getGroupMembers(userId, groupId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'group_members',
|
||
userId,
|
||
groupId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '群员加载失败');
|
||
}
|
||
return response.data?.result?.members || [];
|
||
}
|
||
async updateGroupAlias(userId, groupId, alias) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'update_group_alias',
|
||
userId,
|
||
groupId,
|
||
alias
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '本群昵称保存失败');
|
||
}
|
||
return response.data?.result?.alias || '';
|
||
}
|
||
async leaveGroup(userId, groupId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'leave_group',
|
||
userId,
|
||
groupId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '退出群组失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async dismissGroup(userId, groupId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'dismiss_group',
|
||
userId,
|
||
groupId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '解散群组失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async transferGroup(userId, groupId, targetUserId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'transfer_group',
|
||
userId,
|
||
groupId,
|
||
targetUserId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '转让群组失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async setGroupAdmins(userId, groupId, adminIds) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'set_group_admins',
|
||
userId,
|
||
groupId,
|
||
adminIds
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '管理员设置失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async updateGroupProfile(userId, groupId, {
|
||
name,
|
||
announcement,
|
||
welcomeText
|
||
}) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'update_group_profile',
|
||
userId,
|
||
groupId,
|
||
name,
|
||
announcement,
|
||
welcomeText
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '群资料保存失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async kickGroupMembers(userId, groupId, targetIds) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'kick_group_members',
|
||
userId,
|
||
groupId,
|
||
targetIds
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '踢人失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async updateGroupMuteSetting(userId, groupId, setting) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'update_mute_setting',
|
||
userId,
|
||
groupId,
|
||
...setting
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '禁言设置保存失败');
|
||
}
|
||
return response.data?.result?.muteSetting || null;
|
||
}
|
||
async updateContactAlias(userId, targetId, alias) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.updateAliasApi, {
|
||
userId,
|
||
targetId,
|
||
alias
|
||
}, {
|
||
withCredentials: false,
|
||
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.updateAliasApi)
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '备注名修改失败');
|
||
}
|
||
return response.data?.result?.contact?.alias || '';
|
||
}
|
||
async getProfile(userId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.profileApi, {
|
||
action: 'get',
|
||
userId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '用户资料加载失败');
|
||
}
|
||
return response.data?.result?.profile || null;
|
||
}
|
||
async updateProfile(userId, {
|
||
displayName,
|
||
portraitFile
|
||
}) {
|
||
const formData = new FormData();
|
||
formData.append('action', 'update');
|
||
formData.append('userId', userId);
|
||
formData.append('displayName', displayName);
|
||
if (portraitFile) {
|
||
formData.append('portraitFile', portraitFile);
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.profileApi, formData, {
|
||
withCredentials: false,
|
||
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer)
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '用户资料保存失败');
|
||
}
|
||
return response.data?.result?.profile || null;
|
||
}
|
||
async changePassword({
|
||
oldPassword,
|
||
newPassword
|
||
}) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.changePasswordApi, {
|
||
oldPassword,
|
||
newPassword
|
||
}, {
|
||
withCredentials: false,
|
||
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.changePasswordApi)
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || response.data?.msg || '密码修改失败');
|
||
}
|
||
return true;
|
||
}
|
||
async resetPasswordWithCode({
|
||
mobile,
|
||
resetCode,
|
||
newPassword
|
||
}) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.resetPasswordApi, {
|
||
mobile,
|
||
resetCode,
|
||
newPassword
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || response.data?.msg || '密码设置失败');
|
||
}
|
||
return true;
|
||
}
|
||
refreshContactList() {
|
||
const contacts = this.getContactList();
|
||
this.emit('contactsChanged', contacts);
|
||
return contacts;
|
||
}
|
||
createSingleConversation(userId, userInfo = null) {
|
||
const title = getTitle(userInfo?.title || userInfo?.displayName || userInfo?.name, userId);
|
||
return {
|
||
id: `single-${userId}`,
|
||
type: 'single',
|
||
target: userId,
|
||
title,
|
||
subtitle: '',
|
||
unread: 0,
|
||
portrait: userInfo?.portrait || '',
|
||
avatarText: title.slice(0, 1).toUpperCase(),
|
||
updatedAt: Date.now(),
|
||
raw: {
|
||
type: 'single',
|
||
target: userId,
|
||
line: 0
|
||
}
|
||
};
|
||
}
|
||
mapContact(userId, friend, userInfo) {
|
||
const title = getTitle(userInfo?.friendAlias || friend?.alias || userInfo?.displayName || userInfo?.name, userId);
|
||
return {
|
||
id: userId,
|
||
uid: userId,
|
||
title,
|
||
subtitle: userInfo?.mobile || userInfo?.name || userId,
|
||
portrait: userInfo?.portrait || '',
|
||
address: userInfo?.address || '',
|
||
avatarText: title.slice(0, 1).toUpperCase(),
|
||
alias: friend?.alias || userInfo?.friendAlias || '',
|
||
rawFriend: friend,
|
||
rawUser: userInfo
|
||
};
|
||
}
|
||
on(eventName, handler) {
|
||
if (!this.listeners.has(eventName)) {
|
||
this.listeners.set(eventName, new Set());
|
||
}
|
||
this.listeners.get(eventName).add(handler);
|
||
return () => this.off(eventName, handler);
|
||
}
|
||
off(eventName, handler) {
|
||
this.listeners.get(eventName)?.delete(handler);
|
||
}
|
||
emit(eventName, payload) {
|
||
this.listeners.get(eventName)?.forEach(handler => handler(payload));
|
||
}
|
||
persistAppToken(url, response) {
|
||
const appToken = response.headers?.authtoken || response.headers?.authToken;
|
||
if (appToken) {
|
||
localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.authTokenStoragePrefix + this.getUrlHost(url), appToken);
|
||
}
|
||
}
|
||
getAppAuthHeaders(url) {
|
||
const host = this.getUrlHost(url);
|
||
if (!host) {
|
||
return {};
|
||
}
|
||
const token = localStorage.getItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.authTokenStoragePrefix + host);
|
||
return token ? {
|
||
authToken: token
|
||
} : {};
|
||
}
|
||
getUrlHost(url) {
|
||
try {
|
||
return new URL(url, window.location.origin).host;
|
||
} catch (error) {
|
||
return '';
|
||
}
|
||
}
|
||
}
|
||
const imClient = new HttpImClient();
|
||
|
||
/***/ }),
|
||
|
||
/***/ 5051:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* unused harmony export WildfireImClient */
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2169);
|
||
/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5099);
|
||
/* harmony import */ var _longConnectionImClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3909);
|
||
/* harmony import */ var _documentedHttpImClient__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4355);
|
||
|
||
|
||
|
||
|
||
class UnsupportedWildfireImClient {
|
||
constructor() {
|
||
throw new Error('当前本地社区版 Web 客户端未启用 WildFire Web SDK');
|
||
}
|
||
}
|
||
const imClient = _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'wildfire' ? new UnsupportedWildfireImClient() : _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'custom-ws' || _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'long' ? new _longConnectionImClient__WEBPACK_IMPORTED_MODULE_2__/* .LongConnectionImClient */ .E() : new _documentedHttpImClient__WEBPACK_IMPORTED_MODULE_3__/* .DocumentedHttpImClient */ .u();
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
|
||
/* harmony export */ "wD", 0, /* binding */ imClient
|
||
/* harmony export */ ]);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 3909:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ E: function() { return /* binding */ LongConnectionImClient; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2489);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7588);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1701);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2169);
|
||
/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5099);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const HEARTBEAT_INTERVAL_MS = 25000;
|
||
const RECONNECT_MIN_MS = 1000;
|
||
const RECONNECT_MAX_MS = 15000;
|
||
function buildWsUrl() {
|
||
if (_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsUrl) {
|
||
return _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsUrl;
|
||
}
|
||
const protocol = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.useWss ? 'wss' : 'ws';
|
||
const host = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imServerHost || window.location.hostname;
|
||
const port = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imRoutePort ? `:${_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imRoutePort}` : '';
|
||
const path = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath?.startsWith('/') ? _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath : `/${_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath || 'ws'}`;
|
||
return `${protocol}://${host}${port}${path}`;
|
||
}
|
||
function normalizeConversationId(payload) {
|
||
const target = payload.target || payload.to || payload.receiver || payload.conversationTarget || payload.from || payload.sender;
|
||
return payload.conversationId || (target ? `single-${target}` : '');
|
||
}
|
||
function normalizeIncomingMessage(payload, currentUserId) {
|
||
const item = payload.message || payload;
|
||
const from = item.from || item.sender || item.fromUser || '';
|
||
const target = item.target || item.to || item.receiver || '';
|
||
const direction = from && String(from) === String(currentUserId) ? 'out' : 'in';
|
||
const conversationId = item.conversationId || normalizeConversationId({
|
||
...item,
|
||
target: direction === 'out' ? target : from
|
||
});
|
||
if (!conversationId) {
|
||
return null;
|
||
}
|
||
const status = item.status || item.deliveryStatus || 'sent';
|
||
return {
|
||
id: item.id || item.messageId || item.messageUid || `${Date.now()}${Math.random().toString(16).slice(2)}`,
|
||
messageUid: item.messageUid || item.uid || item.messageId || '',
|
||
conversationId,
|
||
from,
|
||
target,
|
||
direction,
|
||
type: item.type || 'text',
|
||
text: item.text || item.content || item.searchableContent || '',
|
||
status,
|
||
deliveryStatus: item.deliveryStatus || (direction === 'out' ? status : ''),
|
||
timestamp: Number(item.timestamp || item.serverTimestamp || Date.now()),
|
||
displayTimestamp: Number(item.displayTimestamp || item.timestamp || item.serverTimestamp || Date.now()),
|
||
raw: item
|
||
};
|
||
}
|
||
class LongConnectionImClient extends _httpImClient__WEBPACK_IMPORTED_MODULE_5__/* .HttpImClient */ .Y {
|
||
constructor() {
|
||
super();
|
||
this.socket = null;
|
||
this.wsUrl = buildWsUrl();
|
||
this.heartbeatTimer = null;
|
||
this.reconnectTimer = null;
|
||
this.reconnectAttempts = 0;
|
||
this.manualClose = false;
|
||
}
|
||
getSdkVersion() {
|
||
return 'JC-LC/0.1';
|
||
}
|
||
shouldUseMessagePolling() {
|
||
return !this.connected;
|
||
}
|
||
async ensureSdk() {
|
||
if (typeof WebSocket === 'undefined') {
|
||
throw new Error('当前浏览器不支持 WebSocket 长连接');
|
||
}
|
||
return true;
|
||
}
|
||
connect(userId, token) {
|
||
this.currentUser = {
|
||
userId,
|
||
token
|
||
};
|
||
this.manualClose = false;
|
||
this.openSocket();
|
||
}
|
||
disconnect() {
|
||
this.manualClose = true;
|
||
this.clearReconnectTimer();
|
||
this.clearHeartbeatTimer();
|
||
if (this.socket) {
|
||
this.socket.close();
|
||
this.socket = null;
|
||
}
|
||
super.disconnect();
|
||
}
|
||
openSocket() {
|
||
if (this.socket?.readyState === WebSocket.OPEN) {
|
||
this.sendAuthFrame();
|
||
return;
|
||
}
|
||
if (this.socket?.readyState === WebSocket.CONNECTING) {
|
||
return;
|
||
}
|
||
this.emit('connectionStatusChanged', {
|
||
connected: false,
|
||
statusText: '长连接连接中'
|
||
});
|
||
try {
|
||
this.socket = new WebSocket(this.wsUrl);
|
||
this.socket.binaryType = 'arraybuffer';
|
||
} catch (error) {
|
||
this.emit('connectionStatusChanged', {
|
||
connected: false,
|
||
statusText: '长连接创建失败,使用HTTP补偿'
|
||
});
|
||
this.scheduleReconnect();
|
||
return;
|
||
}
|
||
this.socket.onopen = () => {
|
||
this.connected = true;
|
||
this.reconnectAttempts = 0;
|
||
this.emit('connectionStatusChanged', {
|
||
connected: true,
|
||
statusText: '长连接已连接'
|
||
});
|
||
this.sendAuthFrame();
|
||
this.startHeartbeat();
|
||
this.refreshConversationList();
|
||
};
|
||
this.socket.onmessage = event => {
|
||
this.handleFrame(event.data);
|
||
};
|
||
this.socket.onerror = () => {
|
||
this.emit('connectionStatusChanged', {
|
||
connected: false,
|
||
statusText: '长连接异常,使用HTTP补偿'
|
||
});
|
||
};
|
||
this.socket.onclose = () => {
|
||
this.connected = false;
|
||
this.clearHeartbeatTimer();
|
||
this.socket = null;
|
||
if (this.manualClose) {
|
||
return;
|
||
}
|
||
this.emit('connectionStatusChanged', {
|
||
connected: false,
|
||
statusText: '长连接重连中'
|
||
});
|
||
this.scheduleReconnect();
|
||
};
|
||
}
|
||
sendAuthFrame() {
|
||
this.sendFrame({
|
||
type: 'auth',
|
||
userId: this.currentUser?.userId || '',
|
||
token: this.currentUser?.token || '',
|
||
clientId: this.getClientId(),
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.platform,
|
||
timestamp: Date.now()
|
||
});
|
||
}
|
||
sendFrame(frame) {
|
||
if (this.socket?.readyState !== WebSocket.OPEN) {
|
||
return false;
|
||
}
|
||
this.socket.send(JSON.stringify(frame));
|
||
return true;
|
||
}
|
||
handleFrame(rawData) {
|
||
if (rawData instanceof ArrayBuffer) {
|
||
this.emit('rawFrameReceived', rawData);
|
||
return;
|
||
}
|
||
let payload;
|
||
try {
|
||
payload = typeof rawData === 'string' ? JSON.parse(rawData) : rawData;
|
||
} catch (error) {
|
||
return;
|
||
}
|
||
const type = payload.type || payload.event || payload.cmd || '';
|
||
if (type === 'pong' || type === 'auth_ok' || type === 'connected') {
|
||
return;
|
||
}
|
||
if (type === 'contactsChanged') {
|
||
this.emit('contactsChanged', payload.contacts || []);
|
||
return;
|
||
}
|
||
if (type === 'conversationsChanged') {
|
||
this.emit('conversationsChanged', payload.conversations || []);
|
||
return;
|
||
}
|
||
if (type === 'messages' && Array.isArray(payload.messages)) {
|
||
payload.messages.map(message => normalizeIncomingMessage(message, this.currentUser?.userId)).filter(Boolean).forEach(message => this.emit('messageReceived', message));
|
||
return;
|
||
}
|
||
const message = normalizeIncomingMessage(payload, this.currentUser?.userId);
|
||
if (message) {
|
||
this.emit(message.direction === 'out' ? 'messageStatusChanged' : 'messageReceived', message);
|
||
}
|
||
}
|
||
startHeartbeat() {
|
||
this.clearHeartbeatTimer();
|
||
this.heartbeatTimer = window.setInterval(() => {
|
||
this.sendFrame({
|
||
type: 'ping',
|
||
timestamp: Date.now()
|
||
});
|
||
}, HEARTBEAT_INTERVAL_MS);
|
||
}
|
||
clearHeartbeatTimer() {
|
||
if (this.heartbeatTimer) {
|
||
window.clearInterval(this.heartbeatTimer);
|
||
this.heartbeatTimer = null;
|
||
}
|
||
}
|
||
scheduleReconnect() {
|
||
this.clearReconnectTimer();
|
||
const delay = Math.min(RECONNECT_MAX_MS, RECONNECT_MIN_MS * 2 ** this.reconnectAttempts);
|
||
this.reconnectAttempts += 1;
|
||
this.reconnectTimer = window.setTimeout(() => {
|
||
this.openSocket();
|
||
}, delay);
|
||
}
|
||
clearReconnectTimer() {
|
||
if (this.reconnectTimer) {
|
||
window.clearTimeout(this.reconnectTimer);
|
||
this.reconnectTimer = null;
|
||
}
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
|
||
/***/ 926:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2261);
|
||
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5051);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2169);
|
||
|
||
|
||
|
||
|
||
const STORAGE_KEY = 'qmt-web-im-session';
|
||
function normalizeStoredPortrait(portrait) {
|
||
return portrait || '';
|
||
}
|
||
function nextProfilePortrait(profilePortrait, currentPortrait) {
|
||
return normalizeStoredPortrait(profilePortrait) || normalizeStoredPortrait(currentPortrait);
|
||
}
|
||
function inferAccountType(account) {
|
||
return String(account || '').includes('@') ? 2 : 1;
|
||
}
|
||
const useSessionStore = (0,pinia__WEBPACK_IMPORTED_MODULE_1__/* .defineStore */ .nY)('session', {
|
||
state: () => ({
|
||
isAuthenticated: false,
|
||
connecting: false,
|
||
connected: false,
|
||
connectionStatusText: '未连接',
|
||
userId: '',
|
||
token: '',
|
||
displayName: '',
|
||
portrait: '',
|
||
error: '',
|
||
sdkVersion: '',
|
||
eventsBound: false
|
||
}),
|
||
actions: {
|
||
restore() {
|
||
const raw = localStorage.getItem(STORAGE_KEY);
|
||
if (!raw) {
|
||
return;
|
||
}
|
||
try {
|
||
const session = JSON.parse(raw);
|
||
if (session.appServer !== _config__WEBPACK_IMPORTED_MODULE_3__/* .appConfig */ .U.appServer) {
|
||
localStorage.removeItem(STORAGE_KEY);
|
||
return;
|
||
}
|
||
if (session.userId && session.token) {
|
||
if (!session.clientId) {
|
||
localStorage.removeItem(STORAGE_KEY);
|
||
return;
|
||
}
|
||
this.userId = session.userId;
|
||
this.token = session.token;
|
||
this.displayName = session.displayName || session.userId;
|
||
this.portrait = normalizeStoredPortrait(session.portrait);
|
||
this.isAuthenticated = true;
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.restoreClientId(session.clientId);
|
||
this.connect();
|
||
this.refreshProfile();
|
||
}
|
||
} catch (error) {
|
||
localStorage.removeItem(STORAGE_KEY);
|
||
}
|
||
},
|
||
async loginWithPassword(account, password, type = inferAccountType(account)) {
|
||
this.error = '';
|
||
this.connecting = true;
|
||
try {
|
||
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.loginWithPassword(account, password, type);
|
||
this.applyLoginResult(result);
|
||
await this.connect();
|
||
} catch (error) {
|
||
this.error = error.message || '登录失败';
|
||
} finally {
|
||
this.connecting = false;
|
||
}
|
||
},
|
||
async loginWithCode(account, code) {
|
||
this.error = '';
|
||
this.connecting = true;
|
||
try {
|
||
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.loginWithCode(account, code);
|
||
this.applyLoginResult(result);
|
||
await this.connect();
|
||
} catch (error) {
|
||
this.error = error.message || '登录失败';
|
||
} finally {
|
||
this.connecting = false;
|
||
}
|
||
},
|
||
async completePcSessionLogin(result) {
|
||
this.error = '';
|
||
this.connecting = true;
|
||
try {
|
||
this.applyLoginResult(result);
|
||
await this.connect();
|
||
} catch (error) {
|
||
this.error = error.message || '扫码登录失败';
|
||
} finally {
|
||
this.connecting = false;
|
||
}
|
||
},
|
||
async register(payload) {
|
||
this.error = '';
|
||
this.connecting = true;
|
||
try {
|
||
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.register(payload);
|
||
this.applyLoginResult(result);
|
||
await this.connect();
|
||
return result;
|
||
} catch (error) {
|
||
this.error = error.message || '注册失败';
|
||
return null;
|
||
} finally {
|
||
this.connecting = false;
|
||
}
|
||
},
|
||
applyLoginResult(result) {
|
||
this.userId = result.userId || result.uid || result.id || '';
|
||
this.token = result.token || result.imToken || '';
|
||
this.displayName = result.displayName || result.userName || result.name || this.userId;
|
||
this.portrait = normalizeStoredPortrait(result.portrait);
|
||
this.isAuthenticated = Boolean(this.userId && this.token);
|
||
this.persistSession();
|
||
},
|
||
persistSession() {
|
||
localStorage.setItem(STORAGE_KEY, JSON.stringify({
|
||
userId: this.userId,
|
||
token: this.token,
|
||
displayName: this.displayName,
|
||
portrait: this.portrait,
|
||
clientId: _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getClientId(),
|
||
appServer: _config__WEBPACK_IMPORTED_MODULE_3__/* .appConfig */ .U.appServer
|
||
}));
|
||
},
|
||
applyProfile(profile) {
|
||
if (!profile) {
|
||
return;
|
||
}
|
||
this.userId = profile.userId || profile.uid || this.userId;
|
||
this.displayName = profile.displayName || profile.name || this.displayName || this.userId;
|
||
this.portrait = nextProfilePortrait(profile.portrait, this.portrait);
|
||
this.persistSession();
|
||
},
|
||
async refreshProfile() {
|
||
if (!this.userId) {
|
||
return null;
|
||
}
|
||
try {
|
||
const profile = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getProfile(this.userId);
|
||
this.applyProfile(profile);
|
||
return profile;
|
||
} catch (error) {
|
||
return null;
|
||
}
|
||
},
|
||
async saveProfile({
|
||
displayName,
|
||
portraitFile
|
||
}) {
|
||
if (!this.userId) {
|
||
throw new Error('请先登录');
|
||
}
|
||
const profile = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.updateProfile(this.userId, {
|
||
displayName,
|
||
portraitFile
|
||
});
|
||
this.applyProfile(profile);
|
||
return profile;
|
||
},
|
||
async changePassword({
|
||
oldPassword,
|
||
newPassword
|
||
}) {
|
||
if (!this.userId) {
|
||
throw new Error('请先登录');
|
||
}
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.changePassword({
|
||
oldPassword,
|
||
newPassword
|
||
});
|
||
await this.logout();
|
||
return true;
|
||
},
|
||
async resetPasswordWithCode({
|
||
mobile,
|
||
resetCode,
|
||
newPassword
|
||
}) {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.resetPasswordWithCode({
|
||
mobile,
|
||
resetCode,
|
||
newPassword
|
||
});
|
||
return true;
|
||
},
|
||
async connect() {
|
||
if (!this.userId || !this.token) {
|
||
return;
|
||
}
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.ensureSdk();
|
||
this.sdkVersion = _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getSdkVersion();
|
||
this.bindImEvents();
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.connect(this.userId, this.token);
|
||
},
|
||
bindImEvents() {
|
||
if (this.eventsBound) {
|
||
return;
|
||
}
|
||
this.eventsBound = true;
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.on('connectionStatusChanged', status => {
|
||
this.connected = status.connected;
|
||
this.connectionStatusText = status.statusText || (status.connected ? '已连接' : '未连接');
|
||
});
|
||
},
|
||
async logout() {
|
||
try {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.logout?.();
|
||
} catch (error) {
|
||
this.error = error.message || '退出登录失败';
|
||
} finally {
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.disconnect();
|
||
localStorage.removeItem(STORAGE_KEY);
|
||
this.$reset();
|
||
}
|
||
}
|
||
}
|
||
});
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
|
||
/* harmony export */ "B", 0, /* binding */ useSessionStore
|
||
/* harmony export */ ]);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 7067:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4208);
|
||
|
||
|
||
|
||
const __exports__ = _App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 8409:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _DocumentedShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1106);
|
||
|
||
|
||
|
||
const __exports__ = _DocumentedShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 3727:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4524);
|
||
|
||
|
||
|
||
const __exports__ = _LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 4208:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4677);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 1106:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_DocumentedShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_DocumentedShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(865);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 4524:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8607);
|
||
|
||
|
||
/***/ })
|
||
|
||
/******/ });
|
||
/************************************************************************/
|
||
/******/ // The module cache
|
||
/******/ var __webpack_module_cache__ = {};
|
||
/******/
|
||
/******/ // The require function
|
||
/******/ function __webpack_require__(moduleId) {
|
||
/******/ // Check if module is in cache
|
||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||
/******/ if (cachedModule !== undefined) {
|
||
/******/ return cachedModule.exports;
|
||
/******/ }
|
||
/******/ // Create a new module (and put it into the cache)
|
||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||
/******/ // no module.id needed
|
||
/******/ // no module.loaded needed
|
||
/******/ exports: {}
|
||
/******/ };
|
||
/******/
|
||
/******/ // Execute the module function
|
||
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||
/******/
|
||
/******/ // Return the exports of the module
|
||
/******/ return module.exports;
|
||
/******/ }
|
||
/******/
|
||
/******/ // expose the modules object (__webpack_modules__)
|
||
/******/ __webpack_require__.m = __webpack_modules__;
|
||
/******/
|
||
/************************************************************************/
|
||
/******/ /* webpack/runtime/chunk loaded */
|
||
/******/ !function() {
|
||
/******/ var deferred = [];
|
||
/******/ __webpack_require__.O = function(result, chunkIds, fn, priority) {
|
||
/******/ if(chunkIds) {
|
||
/******/ priority = priority || 0;
|
||
/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
|
||
/******/ deferred[i] = [chunkIds, fn, priority];
|
||
/******/ return;
|
||
/******/ }
|
||
/******/ var notFulfilled = Infinity;
|
||
/******/ for (var i = 0; i < deferred.length; i++) {
|
||
/******/ var chunkIds = deferred[i][0];
|
||
/******/ var fn = deferred[i][1];
|
||
/******/ var priority = deferred[i][2];
|
||
/******/ var fulfilled = true;
|
||
/******/ for (var j = 0; j < chunkIds.length; j++) {
|
||
/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {
|
||
/******/ chunkIds.splice(j--, 1);
|
||
/******/ } else {
|
||
/******/ fulfilled = false;
|
||
/******/ if(priority < notFulfilled) notFulfilled = priority;
|
||
/******/ }
|
||
/******/ }
|
||
/******/ if(fulfilled) {
|
||
/******/ deferred.splice(i--, 1)
|
||
/******/ var r = fn();
|
||
/******/ if (r !== undefined) result = r;
|
||
/******/ }
|
||
/******/ }
|
||
/******/ return result;
|
||
/******/ };
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/compat get default export */
|
||
/******/ !function() {
|
||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||
/******/ __webpack_require__.n = function(module) {
|
||
/******/ var getter = module && module.__esModule ?
|
||
/******/ function() { return module['default']; } :
|
||
/******/ function() { return module; };
|
||
/******/ __webpack_require__.d(getter, { a: getter });
|
||
/******/ return getter;
|
||
/******/ };
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/define property getters */
|
||
/******/ !function() {
|
||
/******/ // define getter/value functions for harmony exports
|
||
/******/ __webpack_require__.d = function(exports, definition) {
|
||
/******/ if(Array.isArray(definition)) {
|
||
/******/ var i = 0;
|
||
/******/ while(i < definition.length) {
|
||
/******/ var key = definition[i++];
|
||
/******/ var binding = definition[i++];
|
||
/******/ if(!__webpack_require__.o(exports, key)) {
|
||
/******/ if(binding === 0) {
|
||
/******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
|
||
/******/ } else {
|
||
/******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
|
||
/******/ }
|
||
/******/ } else if(binding === 0) { i++; }
|
||
/******/ }
|
||
/******/ } else {
|
||
/******/ for(var key in definition) {
|
||
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
||
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
||
/******/ }
|
||
/******/ }
|
||
/******/ }
|
||
/******/ };
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/global */
|
||
/******/ !function() {
|
||
/******/ __webpack_require__.g = (function() {
|
||
/******/ if (typeof globalThis === 'object') return globalThis;
|
||
/******/ try {
|
||
/******/ return this || new Function('return this')();
|
||
/******/ } catch (e) {
|
||
/******/ if (typeof window === 'object') return window;
|
||
/******/ }
|
||
/******/ })();
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||
/******/ !function() {
|
||
/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/make namespace object */
|
||
/******/ !function() {
|
||
/******/ // define __esModule on exports
|
||
/******/ __webpack_require__.r = function(exports) {
|
||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||
/******/ }
|
||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||
/******/ };
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/set anonymous default export name */
|
||
/******/ !function() {
|
||
/******/ // set .name for anonymous default exports per ES spec
|
||
/******/ __webpack_require__.dn = function(x) {
|
||
/******/ (Object.getOwnPropertyDescriptor(x, "name") || {}).writable || Object.defineProperty(x, "name", { value: "default", configurable: true });
|
||
/******/ };
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/jsonp chunk loading */
|
||
/******/ !function() {
|
||
/******/ // no baseURI
|
||
/******/
|
||
/******/ // object to store loaded and loading chunks
|
||
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
||
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
|
||
/******/ var installedChunks = {
|
||
/******/ 524: 0
|
||
/******/ };
|
||
/******/
|
||
/******/ // no chunk on demand loading
|
||
/******/
|
||
/******/ // no prefetching
|
||
/******/
|
||
/******/ // no preloaded
|
||
/******/
|
||
/******/ // no HMR
|
||
/******/
|
||
/******/ // no HMR manifest
|
||
/******/
|
||
/******/ __webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };
|
||
/******/
|
||
/******/ // install a JSONP callback for chunk loading
|
||
/******/ var webpackJsonpCallback = function(parentChunkLoadingFunction, data) {
|
||
/******/ var chunkIds = data[0];
|
||
/******/ var moreModules = data[1];
|
||
/******/ var runtime = data[2];
|
||
/******/ // add "moreModules" to the modules object,
|
||
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||
/******/ var moduleId, chunkId, i = 0;
|
||
/******/ if(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {
|
||
/******/ for(moduleId in moreModules) {
|
||
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
|
||
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
|
||
/******/ }
|
||
/******/ }
|
||
/******/ if(runtime) var result = runtime(__webpack_require__);
|
||
/******/ }
|
||
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
|
||
/******/ for(;i < chunkIds.length; i++) {
|
||
/******/ chunkId = chunkIds[i];
|
||
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
|
||
/******/ installedChunks[chunkId][0]();
|
||
/******/ }
|
||
/******/ installedChunks[chunkId] = 0;
|
||
/******/ }
|
||
/******/ return __webpack_require__.O(result);
|
||
/******/ }
|
||
/******/
|
||
/******/ var chunkLoadingGlobal = self["webpackChunkjc_web_im"] = self["webpackChunkjc_web_im"] || [];
|
||
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
|
||
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
|
||
/******/ }();
|
||
/******/
|
||
/************************************************************************/
|
||
/******/
|
||
/******/ // startup
|
||
/******/ // Load entry module and return exports
|
||
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
|
||
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, [504], function() { return __webpack_require__(1406); })
|
||
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
|
||
/******/
|
||
/******/ })()
|
||
;
|
||
//# sourceMappingURL=app.26bc1008.js.map
|