@pisell/pisellos
Version:
一个可扩展的前端模块化SDK框架,支持插件系统
1,594 lines (1,592 loc) • 50.9 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/solution/RegisterAndLogin/index.ts
var RegisterAndLogin_exports = {};
__export(RegisterAndLogin_exports, {
RegisterAndLoginImpl: () => RegisterAndLoginImpl
});
module.exports = __toCommonJS(RegisterAndLogin_exports);
var import_BaseModule = require("../../modules/BaseModule");
var import_types = require("./types");
var import_config = require("./config");
__reExport(RegisterAndLogin_exports, require("./types"), module.exports);
__reExport(RegisterAndLogin_exports, require("./config"), module.exports);
var RegisterAndLoginImpl = class extends import_BaseModule.BaseModule {
constructor(name, version) {
super(name, version);
// 提供给 baseModule 用的默认名称和默认版本
this.defaultName = "registerAndLogin";
this.defaultVersion = "1.0.0";
this.isSolution = true;
this.otherParams = {};
this.channel = "default";
// 内存缓存
this.countriesCache = null;
}
/**
* 重新发送邮箱注册链接
*/
async resendEmailRegisterLink() {
try {
if (!this.store.emailRegisterLinkCode) {
const error = "没有找到邮箱注册链接的 code,请先调用 sendEmailRegisterLink";
this.store.error = error;
return {
status: false,
message: error
};
}
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"resendEmailRegisterLink",
{ code: this.store.emailRegisterLinkCode }
);
if (response.status) {
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationSent,
{
target: "resend",
purpose: import_types.VerificationPurpose.REGISTER
}
);
} else {
this.store.error = response.message || "重新发送注册邀请链接失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationFailed,
{
target: "resend",
error: this.store.error
}
);
}
return response;
} catch (error) {
this.store.error = "重新发送注册邀请链接失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationFailed,
{
target: "resend",
error: this.store.error
}
);
return error;
} finally {
this.store.isLoading = false;
}
}
/**
* 邮箱验证码注册
* @param params 注册参数
* @returns 注册结果
*/
async emailCodeRegister(params) {
try {
this.store.isLoading = true;
this.store.error = null;
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onRegisterStarted,
params
);
const response = await this.apiCaller.call(
"emailCodeRegister",
params
);
if (response.status && response.data) {
const { user, token, refreshToken, expiresAt } = response.data;
if (token) {
this.store.currentUser = user;
this.store.isLoggedIn = true;
}
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onRegisterSuccess,
response.data
);
} else {
this.store.error = response.message || "邮箱验证码注册失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onRegisterFailed, {
error: this.store.error,
params
});
}
return response;
} catch (error) {
this.store.error = "邮箱验证码注册失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onRegisterFailed, {
error: this.store.error,
params
});
throw error;
} finally {
this.store.isLoading = false;
}
}
/**
* 手机验证码注册
*/
async phoneCodeRegister(params) {
try {
this.store.isLoading = true;
this.store.error = null;
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onRegisterStarted,
params
);
const response = await this.apiCaller.call(
"phoneCodeRegister",
params
);
if (response.status && response.data) {
const { user, token, refreshToken, expiresAt } = response.data;
if (token) {
this.store.currentUser = user;
this.store.isLoggedIn = true;
}
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onRegisterSuccess,
response.data
);
} else {
this.store.error = response.message || "注册失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onRegisterFailed, {
error: this.store.error,
params
});
}
return response;
} catch (error) {
this.store.error = error.message || "注册失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onRegisterFailed, {
error: this.store.error,
params
});
throw error;
} finally {
this.store.isLoading = false;
}
}
async initialize(core, options) {
this.core = core;
this.store = {
currentUser: null,
isLoggedIn: false,
isLoading: false,
verificationCodeSent: {},
oauthConfig: options.oauthConfig || {},
error: null,
...options.store
};
this.otherParams = options.otherParams || {};
this.channel = this.otherParams.channel || "default";
this.request = core.getPlugin("request");
this.window = core.getPlugin("window");
if (!this.request) {
throw new Error("RegisterAndLogin 模块需要 request 插件支持");
}
if (!this.window) {
throw new Error("RegisterAndLogin 模块需要 window 插件支持");
}
this.apiCaller = (0, import_config.createApiCaller)(this.request, this.channel);
await this.restoreLoginState();
this.getCountries();
console.log("[RegisterAndLogin] 初始化完成");
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onInited, {});
}
/**
* 从本地存储恢复登录状态
*/
async restoreLoginState() {
try {
const token = this.window.localStorage.getItem("auth_token");
const userInfo = this.window.localStorage.getItem("user_info");
if (token && userInfo) {
const user = JSON.parse(userInfo);
this.store.currentUser = user;
this.store.isLoggedIn = true;
await this.validateToken(token);
}
} catch (error) {
console.warn("[RegisterAndLogin] 恢复登录状态失败:", error);
this.clearLoginState();
}
}
/**
* 验证 token 有效性
*/
async validateToken(token) {
try {
const response = await this.apiCaller.call(
"validateToken",
token
);
if (response.status && response.data) {
this.store.currentUser = response.data;
return true;
} else {
this.clearLoginState();
return false;
}
} catch (error) {
console.warn("[RegisterAndLogin] Token 验证失败:", error);
this.clearLoginState();
return false;
}
}
/**
* 清除登录状态
*/
clearLoginState() {
this.store.currentUser = null;
this.store.isLoggedIn = false;
this.window.localStorage.removeItem("auth_token");
this.window.localStorage.removeItem("user_info");
this.window.localStorage.removeItem("refresh_token");
}
/**
* 发送邮箱验证码
*/
async sendEmailVerificationCode(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"sendEmailVerificationCode",
params
);
if (response.status) {
const now = Date.now();
this.store.verificationCodeSent[params.target] = {
sent: true,
sentAt: now,
expiresAt: now + 5 * 60 * 1e3
// 5分钟过期
};
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationSent,
{
target: params.target,
purpose: params.purpose
}
);
} else {
this.store.error = response.message || "发送验证码失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationFailed,
{
target: params.target,
error: this.store.error
}
);
}
return response;
} catch (error) {
this.store.error = "发送验证码失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationFailed,
{
target: params.target,
error: this.store.error
}
);
return error;
} finally {
this.store.isLoading = false;
}
}
/**
* 发送邮箱登录验证码
*/
async sendEmailLoginCode(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"sendEmailLoginCode",
params
);
if (response.status) {
const now = Date.now();
this.store.verificationCodeSent[params.target] = {
sent: true,
sentAt: now,
expiresAt: now + 5 * 60 * 1e3
// 5分钟过期
};
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationSent,
{
target: params.target,
purpose: params.purpose
}
);
} else {
this.store.error = response.message || "发送验证码失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationFailed,
{
target: params.target,
error: this.store.error
}
);
}
return response;
} catch (error) {
this.store.error = "发送验证码失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationFailed,
{
target: params.target,
error: this.store.error
}
);
return error;
} finally {
this.store.isLoading = false;
}
}
/**
* 发送手机号注册验证码
*/
async sendSmsRegisterCode(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"sendSmsRegisterCode",
params
);
if (response.status) {
const now = Date.now();
this.store.verificationCodeSent[params.phone] = {
sent: true,
sentAt: now,
expiresAt: now + 5 * 60 * 1e3
// 5分钟过期
};
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onSmsVerificationSent,
{
target: params.phone,
purpose: import_types.VerificationPurpose.REGISTER
}
);
} else {
this.store.error = response.message || "发送注册验证码失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onSmsVerificationFailed,
{
target: params.phone,
error: this.store.error
}
);
}
return response;
} catch (error) {
this.store.error = "发送注册验证码失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onSmsVerificationFailed,
{
target: params.phone,
error: this.store.error
}
);
return error;
} finally {
this.store.isLoading = false;
}
}
/**
* 发送邮箱注册邀请链接
*/
async sendEmailRegisterLink(email) {
var _a;
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"sendEmailRegisterLink",
email
);
if (response.status) {
if ((_a = response.data) == null ? void 0 : _a.code) {
this.store.emailRegisterLinkCode = response.data.code;
}
const now = Date.now();
this.store.verificationCodeSent[email] = {
sent: true,
sentAt: now,
expiresAt: now + 24 * 60 * 60 * 1e3
// 24小时过期
};
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationSent,
{
target: email,
purpose: import_types.VerificationPurpose.REGISTER
}
);
} else {
this.store.error = response.message || "发送注册邀请链接失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationFailed,
{
target: email,
error: this.store.error
}
);
}
return response;
} catch (error) {
this.store.error = "发送注册邀请链接失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationFailed,
{
target: email,
error: this.store.error
}
);
return error;
} finally {
this.store.isLoading = false;
}
}
/**
* 验证邮箱注册链接
*/
async verifyEmailRegistrationLink(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"verifyEmailRegistrationLink",
params
);
if (response.status) {
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationVerified,
{
target: "email-registration-link",
purpose: import_types.VerificationPurpose.REGISTER
}
);
} else {
this.store.error = response.message || "邮箱注册链接验证失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationFailed,
{
target: "email-registration-link",
error: this.store.error
}
);
}
return response;
} catch (error) {
this.store.error = "邮箱注册链接验证失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationFailed,
{
target: "email-registration-link",
error: this.store.error
}
);
return error;
} finally {
this.store.isLoading = false;
}
}
/**
* 邮箱密码登录
*/
async emailPasswordLogin(params) {
try {
this.store.isLoading = true;
this.store.error = null;
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginStarted, {
type: "email-password",
email: params.email
});
const response = await this.apiCaller.call(
"emailPasswordLogin",
params
);
if (response.status && response.data) {
this.store.isLoggedIn = true;
this.store.userInfo = response.data.user;
this.store.token = response.data.token;
if (response.data.refreshToken) {
this.store.refreshToken = response.data.refreshToken;
}
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginSuccess, {
user: response.data.user,
token: response.data.token,
loginType: "email-password"
});
} else {
this.store.error = response.message || "邮箱密码登录失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginFailed, {
error: this.store.error,
loginType: "email-password"
});
}
return response;
} catch (error) {
this.store.error = "邮箱密码登录失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginFailed, {
error: this.store.error,
loginType: "email-password"
});
return error;
} finally {
this.store.isLoading = false;
}
}
/**
* 验证验证码
*/
async verifyCode(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"verifyCode",
params
);
if (response.status) {
const hookName = params.type === import_types.VerificationCodeType.EMAIL ? import_types.RegisterAndLoginHooks.onEmailVerificationVerified : import_types.RegisterAndLoginHooks.onSmsVerificationVerified;
await this.core.effects.emit(hookName, {
target: params.target,
purpose: params.purpose
});
} else {
this.store.error = response.message || "验证码验证失败";
const hookName = params.type === import_types.VerificationCodeType.EMAIL ? import_types.RegisterAndLoginHooks.onEmailVerificationFailed : import_types.RegisterAndLoginHooks.onSmsVerificationFailed;
await this.core.effects.emit(hookName, {
target: params.target,
error: this.store.error
});
}
return response;
} catch (error) {
this.store.error = "验证码验证失败";
return error;
} finally {
this.store.isLoading = false;
}
}
/**
* 用户注册
*/
async register(params) {
try {
this.store.isLoading = true;
this.store.error = null;
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onRegisterStarted,
params
);
const response = await this.apiCaller.call(
"register",
params
);
if (response.status && response.data) {
const { user, token, refreshToken, expiresAt } = response.data;
if (token) {
this.store.currentUser = user;
this.store.isLoggedIn = true;
}
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onRegisterSuccess,
response.data
);
} else {
this.store.error = response.message || "注册失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onRegisterFailed, {
error: this.store.error,
params
});
}
return response;
} catch (error) {
this.store.error = "注册失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onRegisterFailed, {
error: this.store.error,
params
});
throw error;
} finally {
this.store.isLoading = false;
}
}
/**
* 用户登录
*/
async login(params) {
try {
this.store.isLoading = true;
this.store.error = null;
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onLoginStarted,
params
);
const response = await this.apiCaller.call(
"login",
params
);
if (response.status && response.data) {
const { user, token, refreshToken } = response.data;
this.store.currentUser = user;
this.store.isLoggedIn = true;
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onLoginSuccess,
response.data
);
} else {
this.store.error = response.message || "登录失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginFailed, {
error: this.store.error,
params
});
}
return response;
} catch (error) {
this.store.error = "登录失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginFailed, {
error: this.store.error,
params
});
throw error;
} finally {
this.store.isLoading = false;
}
}
/**
* OAuth 登录
*/
async oauthLogin(params) {
try {
this.store.isLoading = true;
this.store.error = null;
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onOAuthLoginStarted,
params
);
const response = await this.apiCaller.call("oauthLogin", params);
if (response.status && response.data) {
const { user, token, refreshToken } = response.data;
this.store.currentUser = user;
this.store.isLoggedIn = true;
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onOAuthLoginSuccess,
response.data
);
} else {
this.store.error = response.message || "OAuth 登录失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onOAuthLoginFailed, {
error: this.store.error,
params
});
}
return response;
} catch (error) {
this.store.error = "OAuth 登录失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onOAuthLoginFailed, {
error: this.store.error,
params
});
throw error;
} finally {
this.store.isLoading = false;
}
}
/**
* 用户登出
*/
async logout() {
try {
await this.apiCaller.call("logout");
} catch (error) {
console.warn("[RegisterAndLogin] 登出接口调用失败:", error);
} finally {
this.clearLoginState();
}
}
/** 发送重置密码邮箱链接 */
async sendResetPasswordLink(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"sendResetPasswordLink",
params
);
if (response.status) {
this.store.verificationCodeSent[params.email] = {
sent: true,
sentAt: Date.now(),
expiresAt: Date.now() + 5 * 60 * 1e3
// 5分钟后过期
};
this.core.effects.emit(import_types.RegisterAndLoginHooks.onEmailVerificationSent, {
email: params.email,
purpose: "reset-password-link"
});
} else {
this.store.error = response.message || "发送重置密码链接失败";
}
return response;
} catch (error) {
this.store.error = "发送重置密码链接失败";
return error;
} finally {
this.store.isLoading = false;
}
}
/** 检测重置密码链接code有效性 */
async checkResetPasswordCode(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"checkResetPasswordCode",
params
);
if (!response.status) {
this.store.error = response.message || "验证码无效";
}
return response;
} catch (error) {
this.store.error = "验证码验证失败";
return error;
} finally {
this.store.isLoading = false;
}
}
/** 校验邮件链接 code 有效性 */
async checkEmailLinkCode(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"checkEmailLinkCode",
params
);
if (!response.status) {
this.store.error = response.message || "邮件链接验证码无效";
}
return response;
} catch (error) {
this.store.error = "邮件链接验证码验证失败";
return error;
} finally {
this.store.isLoading = false;
}
}
/** 通过code重置密码 */
async resetPasswordByCode(params) {
try {
this.store.isLoading = true;
this.store.error = null;
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetStarted, {
code: params.code
});
const response = await this.apiCaller.call(
"resetPasswordByCode",
params
);
if (response.status) {
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetSuccess, {
code: params.code
});
} else {
this.store.error = response.message || "密码重置失败";
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetFailed, {
code: params.code,
error: this.store.error
});
}
return response;
} catch (error) {
this.store.error = "密码重置失败";
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetFailed, {
code: params.code,
error: this.store.error
});
return error;
} finally {
this.store.isLoading = false;
}
}
/**
* 重置密码
*/
async resetPassword(params) {
try {
this.store.isLoading = true;
this.store.error = null;
if (params.type === "email") {
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetStarted, {
email: params.target.email
});
} else {
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetStarted, {
phone: params.target.phone
});
}
let response;
if (params.type === "email") {
if (!params.target.email) {
throw new Error("邮箱地址不能为空");
}
response = await this.apiCaller.call(
"resetPasswordByEmail",
{
email: params.target.email,
password: params.password,
code: params.code
}
);
} else {
if (!params.target.phone || !params.target.country_calling_code) {
throw new Error("手机号和国家区号不能为空");
}
response = await this.apiCaller.call(
"resetPasswordByPhone",
{
phone: params.target.phone,
password: params.password,
code: params.code,
country_calling_code: params.target.country_calling_code
}
);
}
if (response.status) {
const key = params.type === "email" ? params.target.email : params.target.phone;
if (this.store.verificationCodeSent[key]) {
delete this.store.verificationCodeSent[key];
}
if (params.type === "email") {
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetSuccess, {
email: params.target.email
});
} else {
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetSuccess, {
phone: params.target.phone
});
}
} else {
this.store.error = response.message || "密码重置失败";
if (params.type === "email") {
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetFailed, {
email: params.target.email,
error: this.store.error
});
} else {
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetFailed, {
phone: params.target.phone,
error: this.store.error
});
}
}
return response;
} catch (error) {
this.store.error = "密码重置失败";
if (params.type === "email") {
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetFailed, {
email: params.target.email,
error: this.store.error
});
} else {
this.core.effects.emit(import_types.RegisterAndLoginHooks.onPasswordResetFailed, {
phone: params.target.phone,
error: this.store.error
});
}
return error;
} finally {
this.store.isLoading = false;
}
}
/** 发送手机登录验证码 */
async sendSmsLoginCode(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"sendSmsLoginCode",
params
);
if (response.status) {
const now = Date.now();
this.store.verificationCodeSent[params.phone] = {
sent: true,
sentAt: now,
expiresAt: now + 5 * 60 * 1e3
// 5分钟过期
};
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onSmsVerificationSent,
{
target: params.phone,
purpose: import_types.VerificationPurpose.LOGIN
}
);
} else {
this.store.error = response.message || "发送登录验证码失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onSmsVerificationFailed,
{
target: params.phone,
error: this.store.error
}
);
}
return response;
} catch (error) {
this.store.error = "发送登录验证码失败";
await this.core.effects.emit(
import_types.RegisterAndLoginHooks.onSmsVerificationFailed,
{
target: params.phone,
error: this.store.error
}
);
return error;
} finally {
this.store.isLoading = false;
}
}
/** 手机号+短信验证码登录 */
async phoneCodeLogin(params) {
try {
this.store.isLoading = true;
this.store.error = null;
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginStarted, {
type: "phone-code",
phone: params.phone
});
const response = await this.apiCaller.call(
"phoneCodeLogin",
params
);
if (response.status && response.data) {
this.store.isLoggedIn = true;
this.store.userInfo = response.data.user;
this.store.token = response.data.token;
if (response.data.refreshToken) {
this.store.refreshToken = response.data.refreshToken;
}
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginSuccess, {
user: response.data.user,
token: response.data.token,
loginType: "phone-code"
});
} else {
this.store.error = response.message || "手机号验证码登录失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginFailed, {
error: this.store.error,
loginType: "phone-code"
});
}
return response;
} catch (error) {
this.store.error = "手机号验证码登录失败";
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginFailed, {
error: this.store.error,
loginType: "phone-code"
});
return error;
} finally {
this.store.isLoading = false;
}
}
formatLoginParams(params) {
const currentUrl = this.window.location.href;
let urlObj = new URL(currentUrl || "");
let source_customer_id = urlObj.searchParams.get("customer");
if (source_customer_id) {
params.source_customer_id = parseInt(source_customer_id);
}
return params;
}
/** Guest 登录 */
async guestLogin() {
var _a, _b;
try {
this.store.isLoading = true;
this.store.error = null;
this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginStarted, {
type: "guest"
});
let guestCode = this.window.localStorage.getItem("guest_code") || "";
let param = {
login_channel: this.channel
};
if (guestCode) {
param.guest_code = guestCode;
}
param = this.formatLoginParams(param);
const response = await this.apiCaller.call("guestLogin", param);
if (response.status && response.data) {
this.store.isLoggedIn = true;
this.store.userInfo = response.data.user;
this.store.token = response.data.token;
if (response.data.refreshToken) {
this.store.refreshToken = response.data.refreshToken;
}
if ((_b = (_a = response.data) == null ? void 0 : _a.customer) == null ? void 0 : _b.guest_code) {
this.window.localStorage.setItem("guest_code", response.data.customer.guest_code);
}
this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginSuccess, {
user: response.data.user,
token: response.data.token,
loginType: "guest"
});
} else {
this.store.error = response.message || "Guest 登录失败";
this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginFailed, {
error: this.store.error,
loginType: "guest"
});
}
return response;
} catch (error) {
this.store.error = "Guest 登录失败";
this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginFailed, {
error: this.store.error,
loginType: "guest"
});
return error;
} finally {
this.store.isLoading = false;
}
}
/** 检查邮箱是否已注册 */
async checkEmailExists(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call("checkEmailExists", params);
if (!response.status) {
this.store.error = response.message || "检查邮箱失败";
}
return response;
} catch (error) {
this.store.error = "检查邮箱失败";
return error;
} finally {
this.store.isLoading = false;
}
}
/** 检查邮箱验证码是否有效 */
async checkEmailCode(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call("checkEmailCode", params);
if (!response.status) {
this.store.error = response.message || "检查邮箱验证码失败";
}
return response;
} catch (error) {
this.store.error = "检查邮箱验证码失败";
return error;
} finally {
this.store.isLoading = false;
}
}
/** 检查手机验证码是否有效 */
async checkMobileCode(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call("checkMobileCode", params);
if (!response.status) {
this.store.error = response.message || "检查手机验证码失败";
}
return response;
} catch (error) {
this.store.error = "检查手机验证码失败";
return error;
} finally {
this.store.isLoading = false;
}
}
/** 手机号密码登录 */
async phonePasswordLogin(params) {
try {
this.store.isLoading = true;
this.store.error = null;
this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginStarted, {
type: "phone-password",
phone: params.phone
});
const response = await this.apiCaller.call(
"phonePasswordLogin",
params
);
if (response.status && response.data) {
this.store.isLoggedIn = true;
this.store.userInfo = response.data.user;
this.store.token = response.data.token;
if (response.data.refreshToken) {
this.store.refreshToken = response.data.refreshToken;
}
this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginSuccess, {
user: response.data.user,
token: response.data.token,
loginType: "phone-password"
});
} else {
this.store.error = response.message || "手机号密码登录失败";
this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginFailed, {
error: this.store.error,
loginType: "phone-password"
});
}
return response;
} catch (error) {
this.store.error = "手机号密码登录失败";
this.core.effects.emit(import_types.RegisterAndLoginHooks.onLoginFailed, {
error: this.store.error,
loginType: "phone-password"
});
return error;
} finally {
this.store.isLoading = false;
}
}
/** 发送密码重置邮箱验证码 */
async sendPasswordResetEmail(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"sendPasswordResetEmail",
params
);
if (response.status) {
const now = Date.now();
this.store.verificationCodeSent[params.email] = {
sent: true,
sentAt: now,
expiresAt: now + 10 * 60 * 1e3
// 10分钟过期
};
this.core.effects.emit(import_types.RegisterAndLoginHooks.onEmailVerificationSent, {
target: params.email,
purpose: import_types.VerificationPurpose.PASSWORD_RESET
});
} else {
this.store.error = response.message || "发送密码重置验证码失败";
this.core.effects.emit(
import_types.RegisterAndLoginHooks.onEmailVerificationFailed,
{
target: params.email,
error: this.store.error
}
);
}
return response;
} catch (error) {
this.store.error = "发送密码重置验证码失败";
this.core.effects.emit(import_types.RegisterAndLoginHooks.onEmailVerificationFailed, {
target: params.email,
error: this.store.error
});
return error;
} finally {
this.store.isLoading = false;
}
}
/** 发送手机号验证码重置密码 */
async sendPasswordResetSms(params) {
try {
this.store.isLoading = true;
this.store.error = null;
const response = await this.apiCaller.call(
"sendPasswordResetSms",
params
);
if (response.status) {
return response;
} else {
this.store.error = response.message || "发送手机号验证码重置密码失败";
}
return response;
} catch (error) {
this.store.error = "发送手机号验证码重置密码失败";
return error;
} finally {
this.store.isLoading = false;
}
}
/**
* 获取当前用户信息
*/
getCurrentUser() {
return this.store.currentUser;
}
/**
* 检查是否已登录
*/
isLoggedIn() {
return this.store.isLoggedIn;
}
/**
* 获取加载状态
*/
isLoading() {
return this.store.isLoading;
}
/**
* 获取错误信息
*/
getError() {
return this.store.error;
}
/**
* 清除错误信息
*/
clearError() {
this.store.error = null;
}
/**
* 检查验证码是否已发送且未过期
*/
isVerificationCodeSent(target) {
const codeInfo = this.store.verificationCodeSent[target];
if (!codeInfo || !codeInfo.sent) {
return false;
}
return Date.now() < codeInfo.expiresAt;
}
/**
* 获取验证码剩余时间(秒)
*/
getVerificationCodeRemainingTime(target) {
const codeInfo = this.store.verificationCodeSent[target];
if (!codeInfo || !codeInfo.sent) {
return 0;
}
const remaining = Math.max(0, codeInfo.expiresAt - Date.now());
return Math.ceil(remaining / 1e3);
}
/**
* 初始化 Facebook SDK
*/
async initFacebookSDK(token) {
return new Promise((resolve, reject) => {
if (typeof window === "undefined") {
reject(new Error("Facebook SDK 只能在浏览器环境中使用"));
return;
}
if (window.FB) {
resolve();
return;
}
const script = document.createElement("script");
script.src = "https://connect.facebook.net/en_US/sdk.js";
script.async = true;
script.defer = true;
script.crossOrigin = "anonymous";
script.onload = () => {
window.FB.init({
appId: token,
cookie: true,
xfbml: true,
version: "v18.0"
});
resolve();
};
script.onerror = () => {
reject(new Error("Facebook SDK 加载失败"));
};
document.head.appendChild(script);
});
}
/**
* 初始化 Apple SDK
*/
async initAppleSDK() {
return new Promise((resolve, reject) => {
if (typeof window === "undefined") {
reject(new Error("Apple SDK 只能在浏览器环境中使用"));
return;
}
if (window.AppleID) {
resolve();
return;
}
const script = document.createElement("script");
script.src = "https://file.mypisell-dev.com/static/apple.js";
script.async = true;
script.defer = true;
script.crossOrigin = "anonymous";
script.onload = () => {
setTimeout(() => {
if (window.AppleID) {
resolve();
} else {
reject(new Error("Apple SDK 加载失败:AppleID 对象不可用"));
}
}, 100);
};
script.onerror = () => {
reject(new Error("Apple SDK 加载失败"));
};
document.head.appendChild(script);
});
}
/**
* Facebook 登录
*/
async loginWithFacebook(token) {
console.log("[RegisterAndLogin] Facebook 登录开始", {
tokenLength: (token == null ? void 0 : token.length) || 0,
timestamp: Date.now()
});
await this.initFacebookSDK(token);
console.log("[RegisterAndLogin] Facebook SDK 初始化完成,准备调用 FB.login");
return new Promise((resolve, reject) => {
console.log("[RegisterAndLogin] 调用 FB.login", {
scope: "email,public_profile"
});
window.FB.login(
async (response) => {
console.log("[RegisterAndLogin] FB.login 回调触发", {
hasAuthResponse: Boolean(response == null ? void 0 : response.authResponse),
status: response == null ? void 0 : response.status
});
if (response.authResponse) {
try {
console.log("[RegisterAndLogin] 调用后端 facebookLogin 接口");
const result = await this.apiCaller.call("facebookLogin", {
token: response.authResponse.accessToken
});
console.log("[RegisterAndLogin] facebookLogin 接口返回成功", {
hasResult: Boolean(result)
});
resolve(result);
} catch (error) {
console.error("[RegisterAndLogin] facebookLogin 接口调用失败", error);
reject(error);
}
} else {
console.warn("[RegisterAndLogin] FB.login 用户取消授权或无 authResponse", response);
reject(new Error("facebook_login_cancel"));
}
},
{ scope: "email,public_profile" }
);
});
}
/**
* Apple 登录(需要在支持的环境中使用)
*/
async loginWithApple(token) {
console.log("[RegisterAndLogin] Apple 登录开始", {
tokenLength: (token == null ? void 0 : token.length) || 0,
timestamp: Date.now()
});
await this.initAppleSDK();
console.log("[RegisterAndLogin] Apple SDK 初始化完成");
return new Promise((resolve, reject) => {
var _a, _b, _c, _d;
try {
console.log("[RegisterAndLogin] 创建临时 Apple SignIn 按钮节点");
const appleSignInDiv = document.createElement("div");
appleSignInDiv.id = "appleid-signin-temp";
appleSignInDiv.setAttribute("data-color", "black");
appleSignInDiv.setAttribute("data-border", "false");
appleSignInDiv.setAttribute("data-type", "sign-in");
appleSignInDiv.setAttribute("data-mode", "logo-only");
appleSignInDiv.setAttribute("data-logo-size", "small");
appleSignInDiv.style.opacity = "0";
appleSignInDiv.style.position = "absolute";
appleSignInDiv.style.left = "-9999px";
appleSignInDiv.style.top = "-9999px";
appleSignInDiv.style.width = "1px";
appleSignInDiv.style.height = "1px";
document.body.appendChild(appleSignInDiv);
console.log("[RegisterAndLogin] Apple SignIn 按钮已添加到文档");
if ((_b = (_a = window.AppleID) == null ? void 0 : _a.auth) == null ? void 0 : _b.init) {
console.log("[RegisterAndLogin] 调用 AppleID.auth.init");
window.AppleID.auth.init({
clientId: token,
// 使用传入的 token 作为 clientId
scope: "name email",
redirectURI: window.location.origin,
state: "signin",
usePopup: true
});
} else {
console.warn("[RegisterAndLogin] AppleID.auth.init 方法不可用");
}
if ((_d = (_c = window.AppleID) == null ? void 0 : _c.auth) == null ? void 0 : _d.signIn) {
console.log("[RegisterAndLogin] 调用 AppleID.auth.signIn");
window.AppleID.auth.signIn().then(async (authResult) => {
var _a2, _b2;
try {
if (document.body.contains(appleSignInDiv)) {
document.body.removeChild(appleSignInDiv);
}
console.log("[RegisterAndLogin] Apple SignIn 成功,临时节点已移除", {
hasAuthorization: Boolean(authResult == null ? void 0 : authResult.authorization),
hasUser: Boolean(authResult == null ? void 0 : authResult.user)
});
const authorizationCode = (_a2 = authResult.authorization) == null ? void 0 : _a2.code;
const identityToken = (_b2 = authResult.authorization) == null ? void 0 : _b2.id_token;
console.log("[RegisterAndLogin] Apple 授权结果解析", {
hasAuthorizationCode: Boolean(authorizationCode),
hasIdentityToken: Boolean(identityToken)
});
console.log("[RegisterAndLogin] 调用后端 appleLogin 接口");
const result = await this.apiCaller.call("appleLogin", {
code: identityToken || authorizationCode,
login_channel: this.channel
});
console.log("[RegisterAndLogin] appleLogin 接口返回成功", {
hasResult: Boolean(result)
});
resolve(result);
} catch (error) {
console.error("[RegisterAndLogin] 处理 Apple 登录结果失败", error);
reject(error);
}
}).catch((error) => {
if (document.body.contains(appleSignInDiv)) {
document.body.removeChild(appleSignInDiv);
}
console.error("[RegisterAndLogin] Apple SignIn Promise 拒绝", error);
reject(new Error("Apple 登录失败: " + ((error == null ? void 0 : error.error) || (error == null ? void 0 : error.message) || "未知错误")));
});
} else {
console.error("[RegisterAndLogin] AppleID.auth.signIn 方法不可用");
reject(new Error("Apple SDK 未正确加载"));
}
} catch (error) {
console.error("[RegisterAndLogin] Apple 登录流程异常", error);
reject(error);
}
});
}
/**
* 更新 OAuth 配置
*/
updateOAuthConfig(config) {
this.store.oauthConfig = {
...this.store.oauthConfig,
...config
};
}
/**
* 获取当前渠道
*/
getCurrentChannel() {
return this.channel;
}
/**
* 获取 API 调用器(用于高级用法)
*/
getApiCaller() {
return this.apiCaller;
}
/**
* 获取国家区号列表
*/
async getCountries() {
const CACHE_KEY = "pisell_countries_cache";
try {
this.store.isLoading = true;
this.store.error = null;
if (this.countriesCache) {
this.store.isLoading = false;
return this.countriesCache;
}
let cachedData = null;
try {
const cached = this.window.localStorage.getItem(CACHE_KEY);
if (cached) {
cachedData = JSON.parse(cached);
}
} catch (error) {
console.warn("[RegisterAndLogin] localStorage 缓存解析失败:", error);
}
if (cachedData && Array.isArray(cachedData) && cachedData.length > 0) {
this.countriesCache = cachedData;
this.updateCountriesCache(CACHE_KEY, cachedData);
this.store.isLoading = false;
return cachedData;
}
const response = await this.apiCaller.call("getCountries");
if (response.status && response.data) {
const countries = response.data;
this.countriesCache = countries;
try {
localStorage.setItem(CACHE_KEY, JSON.stringify(countries));
} catch (error) {
console.warn("[RegisterAndLogin] localStorage 存储失败:", error);
}
return countries;
} else {
this.store.error = response.message || "获取国家区号失败";
throw new Error(this.store.error);
}
} catch (error) {
this.store.error = "获取国家区号失败";
console.error("[RegisterAndLogin] 获取国家区号失败:", error);
throw error;
} finally {
this.store.isLoading = false;
}
}
/**
* 异步更新国家缓存数据
*/
async updateCountriesCache(cacheKey, cachedData) {
try {
const response = await this.apiCaller.call("getCountries");
if (response.status && response.data) {
const newData = response.data;
const hasChanged = newData.length !== cachedData.length || JSON.stringify(newData) !== JSON.stringify(cachedData);
if (hasChanged) {
this.countriesCache = newData;
try {
localStorage.setItem(cacheKey, JSON.stringify(newData));
} catch (error) {
console.warn("[RegisterAndLogin] localStorage 更新失败:", error);
}
console.log("[RegisterAndLogin] 国家数据已更新");
}
}
} catch (error) {
console.warn("[RegisterAndLogin] 后台更新国家数据失败:", error);
}
}
async destroy() {
await this.core.effects.emit(import_types.RegisterAndLoginHooks.onDestroy, {});
console.log("[RegisterAndLogin] 已销毁");
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
RegisterAndLoginImpl,
...require("./types"),
...require("./config")
});