Commit ee10fbb7 by chunhong.mu

refactor(*): 优化sdk架构和使用

parent e6591ad0
// HTTP 适配器
export { uniAdapter } from "./uni-adapter"
export { webAdapter } from "./web-adapter"
import type { SdkCore } from "./sdk-core"
/**
* HTTP 请求服务
* 提供静态 get/post 方法,用于简单的 HTTP 请求
*/
export default class HttpRequest {
protected sdk!: SdkCore
public static get<T>(url: string, params?: any) {
throw new Error("sdk instance not set")
}
public static post<T>(url: string, data?: any) {
throw new Error("sdk instance not set")
}
}
/**
* 增强版 HttpRequest,支持传入 sdk 实例
*/
export class HttpRequestWithSdk {
constructor(protected sdk: SdkCore) {}
public get<T>(url: string, params?: any) {
return this.sdk.getAxios().get<{}, T>(url, { params })
}
public post<T>(url: string, data?: any) {
return this.sdk.getAxios().post<{}, T>(url, data)
}
}
// 图片/文件 URL 构建
export { buildFilePath, buildImage } from "./image-builder"
// SDK 核心
export {
ClientId,
Environment,
getAuthHandlers,
PASSPORT_ANONYMOUS_SERVICE,
PASSPORT_SERVICE,
PASSPORT_SUB_PROJECT,
registerAuthHandlers,
Sdk,
wxDistributerUrlConfig,
} from "./sdk"
export type {
AuthHandlers,
SdkConfig,
SdkInitOptions,
} from "./sdk"
// Token 管理
export { decodeToken, TokenManager } from "./token-manager"
// 监控
export { Product, webMonitor } from "./web-monitor"
export type { MonitorOption } from "./web-monitor"
/**
* Passport 公共常量
* 定义子项目名称和服务名称
*/
/** 子项目名称 */
export const PASSPORT_SUB_PROJECT = "uniplat_base"
/** 匿名服务名称 */
export const PASSPORT_ANONYMOUS_SERVICE = {
SystemUser: "anonymous/system.user",
SystemAuth: "anonymous/system.auth",
SystemWechat: "anonymous/system.wechat",
} as const
/** 认证服务名称 */
export const PASSPORT_SERVICE = {
SystemUser: "system.user",
SystemAuth: "system.auth",
SystemWechat: "system.wechat",
} as const
import type { UniplatSdk } from "uniplat-sdk"
/**
* SDK 控制器
* 负责构建图片路径、文件路径等
*/
export class SdkController {
public static buildImage(
sdk: UniplatSdk,
url: string,
w?: number,
h?: number,
view?: boolean,
) {
if (/^http/.test(url)) {
// 将错误的"//fs"转换为"/fs"
return url.replace(/\/\/fs/, "/fs")
}
// 移除前面可能存在的"/"
const t = url.replace(/^\/(.*)/, "$1")
return (
sdk.global.baseUrl +
sdk.mediaController.buildThumbnail(t, w, h, view)
)
}
public static buildFilePath(
sdk: UniplatSdk,
url: string,
notForceDownload?: boolean,
) {
if (/^http/.test(url)) {
return url
}
if (url.startsWith("/")) {
return sdk.global.baseUrl + url.replace("/", "")
}
return (
sdk.global.baseUrl +
url +
(notForceDownload
? `?parameters=${encodeURIComponent(
JSON.stringify({
forceDownload: false,
}),
)}`
: "")
)
}
}
export interface SdkConfig {
uniplatApi: string
rootEntrance: string
logEnv: string
clientId: string
domainService: {
subProjectName: string
serviceName: string
}
}
export interface SdkInitOptions {
baseUrl: string
sse?: boolean
axiosTimeout?: number
refreshInterval?: number
}
...@@ -4,7 +4,6 @@ import type { ...@@ -4,7 +4,6 @@ import type {
SdkListRowPredictObject, SdkListRowPredictObject,
} from "uniplat-sdk" } from "uniplat-sdk"
import type { AxiosAdapter } from "uniplat-sdk/build/main/helpers/axios" import type { AxiosAdapter } from "uniplat-sdk/build/main/helpers/axios"
import type { SdkConfig } from "./sdk-types"
import { import {
decodeJwt, decodeJwt,
UniplatSdk, UniplatSdk,
...@@ -13,9 +12,54 @@ import { ...@@ -13,9 +12,54 @@ import {
import { Tree } from "uniplat-sdk/build/main/model/tree/tree" import { Tree } from "uniplat-sdk/build/main/model/tree/tree"
import { buildFilePath, buildImage } from "./image-builder" import { buildFilePath, buildImage } from "./image-builder"
/** // ==================== 类型定义 ====================
* 环境枚举
*/ export interface SdkConfig {
uniplatApi: string
rootEntrance: string
logEnv: string
clientId: string
domainService: {
subProjectName: string
serviceName: string
}
}
export interface SdkInitOptions {
baseUrl: string
sse?: boolean
axiosTimeout?: number
refreshInterval?: number
}
export interface AuthHandlers {
clearLoginMsg: () => void
logout: (jump?: boolean, loginUrl?: string) => void
afterSdkLogin: () => Promise<any>
getDeviceInfoWidthCache: () => void
}
// ==================== 常量定义 ====================
/** 子项目名称 */
export const PASSPORT_SUB_PROJECT = "uniplat_base"
/** 匿名服务名称 */
export const PASSPORT_ANONYMOUS_SERVICE = {
SystemUser: "anonymous/system.user",
SystemAuth: "anonymous/system.auth",
SystemWechat: "anonymous/system.wechat",
} as const
/** 认证服务名称 */
export const PASSPORT_SERVICE = {
SystemUser: "system.user",
SystemAuth: "system.auth",
SystemWechat: "system.wechat",
} as const
// ==================== 环境/客户端枚举 ====================
export enum Environment { export enum Environment {
Dev = "dev", Dev = "dev",
Test = "test", Test = "test",
...@@ -23,9 +67,6 @@ export enum Environment { ...@@ -23,9 +67,6 @@ export enum Environment {
Stage = "stage", Stage = "stage",
} }
/**
* 客户端 ID 枚举
*/
export enum ClientId { export enum ClientId {
None = "", None = "",
QqxbApp = "qqxb-hrm-app-ios", QqxbApp = "qqxb-hrm-app-ios",
...@@ -44,9 +85,8 @@ export enum ClientId { ...@@ -44,9 +85,8 @@ export enum ClientId {
Donghu = "donghu-web-pc", Donghu = "donghu-web-pc",
} }
/** // ==================== URL 配置 ====================
* Passport 配置
*/
const qqxbPassportConfig = new Map<Environment, string>([ const qqxbPassportConfig = new Map<Environment, string>([
[ [
Environment.Dev, Environment.Dev,
...@@ -60,9 +100,6 @@ const qqxbPassportConfig = new Map<Environment, string>([ ...@@ -60,9 +100,6 @@ const qqxbPassportConfig = new Map<Environment, string>([
[Environment.Stage, "https://pre-passport.qinqinxiaobao.com"], [Environment.Stage, "https://pre-passport.qinqinxiaobao.com"],
]) ])
/**
* 微信分销商 URL 配置
*/
export const wxDistributerUrlConfig = new Map<Environment, string>([ export const wxDistributerUrlConfig = new Map<Environment, string>([
[Environment.Dev, "http://wechat.test.teammix.qqxb.cn"], [Environment.Dev, "http://wechat.test.teammix.qqxb.cn"],
[Environment.Test, "https://pre-wx-distributer.teammix.com"], [Environment.Test, "https://pre-wx-distributer.teammix.com"],
...@@ -70,13 +107,26 @@ export const wxDistributerUrlConfig = new Map<Environment, string>([ ...@@ -70,13 +107,26 @@ export const wxDistributerUrlConfig = new Map<Environment, string>([
[Environment.Stage, "https://pre-wx-distributer.teammix.com"], [Environment.Stage, "https://pre-wx-distributer.teammix.com"],
]) ])
export class SdkCore { // ==================== AuthHandlers 管理 ====================
let authHandlers: AuthHandlers | null = null
export function registerAuthHandlers(h: AuthHandlers) {
authHandlers = h
}
export function getAuthHandlers(): AuthHandlers | null {
return authHandlers
}
// ==================== Sdk 核心类 ====================
export class Sdk {
private uniplatSdk!: UniplatSdk private uniplatSdk!: UniplatSdk
private readonly handler = new UniplatSdkExtender() private readonly handler = new UniplatSdkExtender()
private token!: string private token!: string
public orgId!: number public orgId!: number
// UICore 合并的属性
private client = ClientId.None private client = ClientId.None
private passportUrl = "" private passportUrl = ""
private wxDistributerUrl = "" private wxDistributerUrl = ""
...@@ -100,22 +150,26 @@ export class SdkCore { ...@@ -100,22 +150,26 @@ export class SdkCore {
}) })
this.uniplatSdk.getAxios().defaults.timeout = 10e3 this.uniplatSdk.getAxios().defaults.timeout = 10e3
this.uniplatSdk.global.rootEntrance = config.rootEntrance this.uniplatSdk.global.rootEntrance = config.rootEntrance
// UICore 初始化逻辑 this.client = (config.clientId as ClientId) || ClientId.None
this.client = config.clientId as ClientId || ClientId.None
const envir = (config.logEnv as Environment) || Environment.Dev const envir = (config.logEnv as Environment) || Environment.Dev
this.passportUrl = qqxbPassportConfig.get(envir) || qqxbPassportConfig.get(Environment.Dev)! this.passportUrl =
this.wxDistributerUrl = wxDistributerUrlConfig.get(envir) || wxDistributerUrlConfig.get(Environment.Dev)! qqxbPassportConfig.get(envir) ||
qqxbPassportConfig.get(Environment.Dev)!
this.wxDistributerUrl =
wxDistributerUrlConfig.get(envir) ||
wxDistributerUrlConfig.get(Environment.Dev)!
} }
public setupEventHandlers(handlers: { public setupEventHandlers(handlers: {
onTokenExpiring: () => void onTokenExpiring: () => void
onUniversalError: (error: any) => void onUniversalError: (error: any) => void
}) { }) {
this.uniplatSdk.events.addUniversalErrorResponseCallback(handlers.onUniversalError) this.uniplatSdk.events.addUniversalErrorResponseCallback(
handlers.onUniversalError,
)
this.uniplatSdk.events.addTokenExpiring(handlers.onTokenExpiring) this.uniplatSdk.events.addTokenExpiring(handlers.onTokenExpiring)
} }
...@@ -139,9 +193,6 @@ export class SdkCore { ...@@ -139,9 +193,6 @@ export class SdkCore {
return this.wxDistributerUrl return this.wxDistributerUrl
} }
/**
* 构建 Passport 登出 URL
*/
public buildPassport4Logout(redirect?: string) { public buildPassport4Logout(redirect?: string) {
if (redirect) { if (redirect) {
return `${this.passportUrl}?redirectUrl=${redirect}&logout=1` return `${this.passportUrl}?redirectUrl=${redirect}&logout=1`
...@@ -234,9 +285,6 @@ export class SdkCore { ...@@ -234,9 +285,6 @@ export class SdkCore {
return decodeJwt<T>(token) return decodeJwt<T>(token)
} }
/**
* 获取 Axios 实例(用于 Web 项目直接调用)
*/
public getAxios() { public getAxios() {
return this.uniplatSdk.getAxios() return this.uniplatSdk.getAxios()
} }
......
...@@ -12,10 +12,10 @@ export enum LoginApiName { ...@@ -12,10 +12,10 @@ export enum LoginApiName {
} }
/** /**
* Passport Token 控制 * Token 管理
* 负责 Token 的保存、验证、获取用户信息等 * 负责 Token 的保存、验证、获取用户信息等
*/ */
export class PassportTokenController { export class TokenManager {
private static readonly key = "JWT_TOKEN" private static readonly key = "JWT_TOKEN"
private static baseUrl = "" private static baseUrl = ""
private static ssr = false private static ssr = false
...@@ -27,7 +27,7 @@ export class PassportTokenController { ...@@ -27,7 +27,7 @@ export class PassportTokenController {
} }
/** /**
* 设置自定义存储实例(由 SdkCore 传入) * 设置自定义存储实例
*/ */
public static setupStorage(storage: Storage) { public static setupStorage(storage: Storage) {
this.storageInstance = storage this.storageInstance = storage
...@@ -70,7 +70,7 @@ export class PassportTokenController { ...@@ -70,7 +70,7 @@ export class PassportTokenController {
const o = r as Index.loginByPassportRequestResult const o = r as Index.loginByPassportRequestResult
if (o.jwt) { if (o.jwt) {
if (this.ssr) { if (this.ssr) {
(sdk.global as any).ssr = true ;(sdk.global as any).ssr = true
} }
this.storage.setItem(this.key, o.jwt) this.storage.setItem(this.key, o.jwt)
} }
...@@ -78,7 +78,6 @@ export class PassportTokenController { ...@@ -78,7 +78,6 @@ export class PassportTokenController {
} else { } else {
if (this.ssr) { if (this.ssr) {
// SSR mode requires sdk.global to be set // SSR mode requires sdk.global to be set
// This should be handled by the caller
} }
this.storage.setItem(this.key, token) this.storage.setItem(this.key, token)
return Promise.resolve() return Promise.resolve()
...@@ -112,8 +111,7 @@ export class PassportTokenController { ...@@ -112,8 +111,7 @@ export class PassportTokenController {
public static checkTokenExit() { public static checkTokenExit() {
const cache = const cache =
this.storage.getItem(this.key) || this.storage.getItem(this.key) || ((window as any).jwtToken)
(window as any).jwtToken
return cache return cache
} }
......
...@@ -30,7 +30,7 @@ enum ProductTable { ...@@ -30,7 +30,7 @@ enum ProductTable {
Error = "error", Error = "error",
} }
export interface SdkMonitorOption { export interface MonitorOption {
userAgent?: boolean userAgent?: boolean
envir: string envir: string
product: Product product: Product
...@@ -106,7 +106,7 @@ class WebMonitor { ...@@ -106,7 +106,7 @@ class WebMonitor {
public useSdk( public useSdk(
sdk: UniplatSdk, sdk: UniplatSdk,
options: SdkMonitorOption, options: MonitorOption,
adapter?: AxiosAdapter, adapter?: AxiosAdapter,
) { ) {
this.envir = options.envir this.envir = options.envir
...@@ -173,4 +173,4 @@ class WebMonitor { ...@@ -173,4 +173,4 @@ class WebMonitor {
} }
} }
export const monitor = new WebMonitor() export const webMonitor = new WebMonitor()
...@@ -3,38 +3,49 @@ export { uniAdapter } from "./adapters/uni-adapter" ...@@ -3,38 +3,49 @@ export { uniAdapter } from "./adapters/uni-adapter"
export { webAdapter } from "./adapters/web-adapter" export { webAdapter } from "./adapters/web-adapter"
// HTTP 请求服务
export { HttpRequestWithSdk } from "./core/http-request"
export { default as HttpRequest } from "./core/http-request"
// 图片/文件 URL 构建 // 图片/文件 URL 构建
export { buildFilePath, buildImage } from "./core/image-builder" export { buildFilePath, buildImage } from "./core/image-builder"
// 监控 // SDK 核心(合并了类型、常量、AuthHandlers)
export { monitor, Product } from "./core/monitor"
export type { SdkMonitorOption } from "./core/monitor"
// Passport 公共常量
export { export {
ClientId,
Environment,
getAuthHandlers,
PASSPORT_ANONYMOUS_SERVICE, PASSPORT_ANONYMOUS_SERVICE,
PASSPORT_SERVICE, PASSPORT_SERVICE,
PASSPORT_SUB_PROJECT, PASSPORT_SUB_PROJECT,
} from "./core/passport-constants" registerAuthHandlers,
Sdk,
// SDK 控制器 wxDistributerUrlConfig,
export { SdkController } from "./core/sdk-controller" } from "./core/sdk"
// SDK 核心 export type {
export { ClientId, Environment, SdkCore, wxDistributerUrlConfig } from "./core/sdk-core" AuthHandlers,
SdkConfig,
SdkInitOptions,
} from "./core/sdk"
export type { SdkConfig, SdkInitOptions } from "./core/sdk-types" export { Sdk as SdkCore } from "./core/sdk"
// Token 管理 // Token 管理
export { decodeToken, PassportTokenController } from "./core/token-manager" export { decodeToken, TokenManager } from "./core/token-manager"
// 向后兼容别名
export { TokenManager as PassportTokenController } from "./core/token-manager"
// 监控
export { Product, webMonitor } from "./core/web-monitor"
export type { MonitorOption } from "./core/web-monitor"
// 小程序模块
export * from "./mini-program"
// 服务工厂函数
export { createLoginService, LoginApiName } from "./services/login-service"
export type { LoginRegisterResult, RegisterChannel } from "./services/login-service"
// 认证处理器 export { createVerifyService, VerifyApiName } from "./services/verify-service"
export { getAuthHandlers, registerAuthHandlers } from "./services/auth-handlers"
export type { AuthHandlers } from "./services/auth-handlers" export type { VerifyImageResult } from "./services/verify-service"
...@@ -22,9 +22,6 @@ export { ...@@ -22,9 +22,6 @@ export {
export type { MiniProgramNavConfig } from "./mini-program" export type { MiniProgramNavConfig } from "./mini-program"
// 分享
export { createShareMixin, finalShareData, setShareData } from "./share"
// 小程序版本更新 // 小程序版本更新
export { updateManager } from "./update-manager" export { updateManager } from "./update-manager"
......
import { ref } from "vue"
const defaultShareData = {
title: "亲亲创客",
path: "/pages/home/index",
imageUrl: "",
}
export const finalShareData = ref<{
[key: string]: {
title: string
path: string
imageUrl: string
}
}>({})
/**
* 设置当前页面分享
*/
export function setShareData(shareData: {
title?: string
path?: string
imageUrl?: string
}) {
const pages = getCurrentPages()
const p = pages[pages.length - 1]
const route = (p as any).route || ""
finalShareData.value = {
...finalShareData.value,
[route]: {
...defaultShareData,
...shareData,
},
}
}
/**
* 创建全局分享 mixin,所有页面默认携带 shareAppMessage 配置
*/
export function createShareMixin() {
return {
onShareAppMessage() {
const pages = getCurrentPages()
const p = pages[pages.length - 1]
const route = (p as any).route || ""
return finalShareData.value[route] || defaultShareData
},
}
}
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* 微信登录服务 * 微信登录服务
* 提供微信小程序绑定手机号登录等功能 * 提供微信小程序绑定手机号登录等功能
*/ */
import type { SdkCore } from "../core/sdk-core" import type { Sdk } from "../core/sdk"
import { import {
PASSPORT_ANONYMOUS_SERVICE, PASSPORT_ANONYMOUS_SERVICE,
PASSPORT_SUB_PROJECT, PASSPORT_SUB_PROJECT,
} from "../core/passport-constants" } from "../core/sdk"
export enum WechatLoginApiName { export enum WechatLoginApiName {
BindPhone = "bind_phone", BindPhone = "bind_phone",
...@@ -28,7 +28,7 @@ export interface WechatLoginResult { ...@@ -28,7 +28,7 @@ export interface WechatLoginResult {
} }
export class WechatLoginService { export class WechatLoginService {
constructor(private sdk: SdkCore) {} constructor(private sdk: Sdk) {}
/** /**
* 微信小程序绑定手机号登录 * 微信小程序绑定手机号登录
......
/**
* 认证处理器接口
* 用于解耦 HTTP 请求层与登录服务层之间的依赖
*/
export interface AuthHandlers {
clearLoginMsg: () => void
logout: (jump?: boolean, loginUrl?: string) => void
afterSdkLogin: () => Promise<any>
getDeviceInfoWidthCache: () => void
}
let handlers: AuthHandlers | null = null
/**
* 注册认证处理器
*/
export function registerAuthHandlers(h: AuthHandlers) {
handlers = h
}
/**
* 获取已注册的认证处理器
*/
export function getAuthHandlers(): AuthHandlers | null {
return handlers
}
// 服务工厂函数
export { createLoginService, LoginApiName } from "./login-service"
export type { LoginRegisterResult, RegisterChannel } from "./login-service"
export { createVerifyService, VerifyApiName } from "./verify-service"
export type { VerifyImageResult } from "./verify-service"
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
* 登录服务 * 登录服务
* 提供密码登录、验证码登录等功能 * 提供密码登录、验证码登录等功能
*/ */
import type { SdkCore } from "../core/sdk-core" import type { UniplatSdk } from "uniplat-sdk"
import { import {
PASSPORT_ANONYMOUS_SERVICE, PASSPORT_ANONYMOUS_SERVICE,
PASSPORT_SERVICE,
PASSPORT_SUB_PROJECT, PASSPORT_SUB_PROJECT,
} from "../core/passport-constants" } from "../core/sdk"
export enum LoginApiName { export enum LoginApiName {
LoginWithPassword = "loginWithPassword", LoginWithPassword = "loginWithPassword",
...@@ -42,73 +43,12 @@ export interface RegisterChannel { ...@@ -42,73 +43,12 @@ export interface RegisterChannel {
[key: string]: any [key: string]: any
} }
export class LoginService { export function createLoginService(sdk: UniplatSdk, clientId: string) {
constructor(private sdk: SdkCore) {}
/**
* 密码登录
*/
public login(username: string, password: string) {
return this.sdk.core
.domainService(
PASSPORT_SUB_PROJECT,
PASSPORT_ANONYMOUS_SERVICE.SystemUser,
LoginApiName.LoginWithPassword,
)
.post<LoginRegisterResult>({
password,
username,
client_id: this.sdk.clientId,
})
}
/**
* 验证码登录
*/
public verifyCodeLogin(
mobile: string,
verifycode: string,
optional?: RegisterChannel,
) {
const data: Record<string, any> = {
mobile,
verifycode,
client_id: this.sdk.clientId,
}
if (optional) {
Object.assign(data, this.buildNotNullProperty(optional))
}
return this.sdk.core
.domainService(
PASSPORT_SUB_PROJECT,
PASSPORT_ANONYMOUS_SERVICE.SystemUser,
LoginApiName.LoginWithVerifyCode,
)
.post<LoginRegisterResult>(data)
}
/**
* 刷新登录
*/
public refreshLogin(
optional?: RegisterChannel,
deviceInfo?: Record<string, string>,
) {
const p = optional || {}
return this.sdk.core
.domainService(
PASSPORT_SUB_PROJECT,
PASSPORT_SERVICE.SystemUser,
LoginApiName.RefreshToken,
)
.post(p, { client_id: this.sdk.clientId, ...deviceInfo })
}
/** /**
* 移除 value 为 0、null、"" 的值 * 移除 value 为 0、null、"" 的值
* 注册接口对一些值有要求,比如活动 id 要么不传要么>0 不能传"" * 注册接口对一些值有要求,比如活动 id 要么不传要么>0 不能传""
*/ */
private buildNotNullProperty(o: Record<string, any>) { function buildNotNullProperty(o: Record<string, any>) {
const t = {} as Record<string, string | number | boolean> const t = {} as Record<string, string | number | boolean>
for (const p in o) { for (const p in o) {
const v = o[p] const v = o[p]
...@@ -118,4 +58,65 @@ export class LoginService { ...@@ -118,4 +58,65 @@ export class LoginService {
} }
return t return t
} }
return {
/**
* 密码登录
*/
login(username: string, password: string) {
return sdk
.domainService(
PASSPORT_SUB_PROJECT,
PASSPORT_ANONYMOUS_SERVICE.SystemUser,
LoginApiName.LoginWithPassword,
)
.post<LoginRegisterResult>({
password,
username,
client_id: clientId,
})
},
/**
* 验证码登录
*/
verifyCodeLogin(
mobile: string,
verifycode: string,
optional?: RegisterChannel,
) {
const data: Record<string, any> = {
mobile,
verifycode,
client_id: clientId,
}
if (optional) {
Object.assign(data, buildNotNullProperty(optional))
}
return sdk
.domainService(
PASSPORT_SUB_PROJECT,
PASSPORT_ANONYMOUS_SERVICE.SystemUser,
LoginApiName.LoginWithVerifyCode,
)
.post<LoginRegisterResult>(data)
},
/**
* 刷新登录
*/
refreshLogin(
optional?: RegisterChannel,
deviceInfo?: Record<string, string>,
) {
const p = optional || {}
return sdk
.domainService(
PASSPORT_SUB_PROJECT,
PASSPORT_SERVICE.SystemUser,
LoginApiName.RefreshToken,
)
.post(p, { client_id: clientId, ...deviceInfo })
},
}
} }
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* 验证码服务 * 验证码服务
* 提供图形验证码生成、短信验证码发送等功能 * 提供图形验证码生成、短信验证码发送等功能
*/ */
import type { SdkCore } from "../core/sdk-core" import type { UniplatSdk } from "uniplat-sdk"
import { import {
PASSPORT_ANONYMOUS_SERVICE, PASSPORT_ANONYMOUS_SERVICE,
PASSPORT_SUB_PROJECT, PASSPORT_SUB_PROJECT,
} from "../core/passport-constants" } from "../core/sdk"
export enum VerifyApiName { export enum VerifyApiName {
SendVerifyCode = "sendVerifyCode", SendVerifyCode = "sendVerifyCode",
...@@ -18,70 +18,70 @@ export interface VerifyImageResult { ...@@ -18,70 +18,70 @@ export interface VerifyImageResult {
seed: string seed: string
} }
export class VerifyService { export function createVerifyService(sdk: UniplatSdk, clientId: string) {
constructor(private sdk: SdkCore) {} return {
/**
* 生成图形验证码
*/
generateImage(): VerifyImageResult {
const result = sdk.getVerifyImageAndSeed() as any
return {
img: result.img,
seed: String(result.seed),
}
},
/** /**
* 生成图形验证码 * 发送短信验证码(需要图形验证码)
*/ */
public generateImage(): VerifyImageResult { sendVerifyCode(mobile: string, seed: string, verifycode: string) {
const result = this.sdk.core.getVerifyImageAndSeed() as any return sdk
return { .domainService(
img: result.img, PASSPORT_SUB_PROJECT,
seed: String(result.seed), PASSPORT_ANONYMOUS_SERVICE.SystemUser,
} VerifyApiName.SendVerifyCode,
} )
.request<
/** Record<string, unknown>,
* 发送短信验证码(需要图形验证码) Record<string, unknown>,
*/ void
public sendVerifyCode(mobile: string, seed: string, verifycode: string) { >("post", { data: { mobile, seed, verifycode } })
return this.sdk.core },
.domainService(
PASSPORT_SUB_PROJECT,
PASSPORT_ANONYMOUS_SERVICE.SystemUser,
VerifyApiName.SendVerifyCode,
)
.request<
Record<string, unknown>,
Record<string, unknown>,
void
>("post", { data: { mobile, seed, verifycode } })
}
/** /**
* 发送短信验证码(使用 token) * 发送短信验证码(使用 token)
*/ */
public sendVerifyCodeWithToken(mobile: string, token: string) { sendVerifyCodeWithToken(mobile: string, token: string) {
return this.sdk.core return sdk
.domainService( .domainService(
PASSPORT_SUB_PROJECT, PASSPORT_SUB_PROJECT,
PASSPORT_ANONYMOUS_SERVICE.SystemUser, PASSPORT_ANONYMOUS_SERVICE.SystemUser,
VerifyApiName.SendVerifyCode, VerifyApiName.SendVerifyCode,
) )
.request< .request<
Record<string, unknown>, Record<string, unknown>,
Record<string, unknown>, Record<string, unknown>,
void void
>("post", { data: { mobile, token } }) >("post", { data: { mobile, token } })
} },
/** /**
* 验证手机号 * 验证手机号
*/ */
public verifyMobile(mobile: string, verifycode: string) { verifyMobile(mobile: string, verifycode: string) {
return this.sdk.core return sdk
.domainService( .domainService(
PASSPORT_SUB_PROJECT, PASSPORT_SUB_PROJECT,
PASSPORT_ANONYMOUS_SERVICE.SystemUser, PASSPORT_ANONYMOUS_SERVICE.SystemUser,
VerifyApiName.VerifyMobile, VerifyApiName.VerifyMobile,
) )
.request< .request<
Record<string, unknown>, Record<string, unknown>,
Record<string, unknown>, Record<string, unknown>,
{ check_result: boolean } { check_result: boolean }
>("post", { >("post", {
data: { mobile, verifycode, client_id: this.sdk.clientId }, data: { mobile, verifycode, client_id: clientId },
}) })
},
} }
} }
import type { SdkConfig } from '@common/sdk' import type { SdkConfig } from '@common/sdk'
import { PassportTokenController, SdkCore, webAdapter } from '@common/sdk' import { Sdk, TokenManager, webAdapter } from '@common/sdk'
import { LoginService } from '@common/sdk/services/login-service' import { createLoginService } from '@common/sdk/services/login-service'
import { VerifyService } from '@common/sdk/services/verify-service' import { createVerifyService } from '@common/sdk/services/verify-service'
/** /**
* qqqf-admin SDK 配置 * qqqf-admin SDK 配置
...@@ -20,19 +20,19 @@ const sdkConfig: SdkConfig = { ...@@ -20,19 +20,19 @@ const sdkConfig: SdkConfig = {
/** /**
* 创建并初始化 SDK * 创建并初始化 SDK
*/ */
export const sdk = new SdkCore(sdkConfig, webAdapter) export const sdk = new Sdk(sdkConfig, webAdapter)
/** /**
* 创建服务实例(依赖注入 SDK * 创建服务(函数式,无需实例化
*/ */
export const loginService = new LoginService(sdk) export const loginService = createLoginService(sdk.core, sdk.clientId)
export const verifyService = new VerifyService(sdk) export const verifyService = createVerifyService(sdk.core, sdk.clientId)
/** /**
* 初始化 Token(如果有) * 初始化 Token(如果有)
*/ */
export function initToken() { export function initToken() {
const token = PassportTokenController.hasToken() const token = TokenManager.hasToken()
if (token) { if (token) {
sdk.core.loginByToken({ sdk.core.loginByToken({
token: token as string, token: token as string,
......
import type { RouteRecordRaw } from 'vue-router' import type { RouteRecordRaw } from 'vue-router'
import { PassportTokenController } from '@common/sdk' import { TokenManager } from '@common/sdk'
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
const routes: RouteRecordRaw[] = [ const routes: RouteRecordRaw[] = [
...@@ -24,7 +24,7 @@ const router = createRouter({ ...@@ -24,7 +24,7 @@ const router = createRouter({
router.beforeEach((to, _from, next) => { router.beforeEach((to, _from, next) => {
document.title = (to.meta.title as string) || '亲亲企服管理后台' document.title = (to.meta.title as string) || '亲亲企服管理后台'
const token = PassportTokenController.hasToken() const token = TokenManager.hasToken()
if (to.meta.requiresAuth && !token) { if (to.meta.requiresAuth && !token) {
next({ path: '/login', query: { redirect: to.fullPath } }) next({ path: '/login', query: { redirect: to.fullPath } })
} }
......
import type { UserInfo } from '../types/auth' import type { UserInfo } from '../types/auth'
import { PassportTokenController } from '@common/sdk' import { TokenManager } from '@common/sdk'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref } from 'vue' import { ref } from 'vue'
export const useAuthStore = defineStore('auth', () => { export const useAuthStore = defineStore('auth', () => {
const token = ref<string>(PassportTokenController.hasToken() || '') const token = ref<string>(TokenManager.hasToken() || '')
const userInfo = ref<UserInfo | null>(null) const userInfo = ref<UserInfo | null>(null)
function setToken(newToken: string) { function setToken(newToken: string) {
token.value = newToken token.value = newToken
PassportTokenController.saveToken2Storage(newToken) TokenManager.saveToken2Storage(newToken)
} }
function setUserInfo(info: UserInfo) { function setUserInfo(info: UserInfo) {
...@@ -19,7 +19,7 @@ export const useAuthStore = defineStore('auth', () => { ...@@ -19,7 +19,7 @@ export const useAuthStore = defineStore('auth', () => {
function logout() { function logout() {
token.value = '' token.value = ''
userInfo.value = null userInfo.value = null
PassportTokenController.clearToken() TokenManager.clearToken()
} }
return { token, userInfo, setToken, setUserInfo, logout } return { token, userInfo, setToken, setUserInfo, logout }
......
<script lang="ts" setup> <script lang="ts" setup>
import { PassportTokenController } from "@common/sdk" import { TokenManager } from "@common/sdk"
import { onLaunch } from "@dcloudio/uni-app" import { onLaunch } from "@dcloudio/uni-app"
import { sdk } from "@/api/http" import { sdk } from "@/api/http"
...@@ -9,7 +9,7 @@ onLaunch(() => { ...@@ -9,7 +9,7 @@ onLaunch(() => {
}) })
function sdkInit() { function sdkInit() {
const token = PassportTokenController.hasToken() const token = TokenManager.hasToken()
if (token) { if (token) {
sdk.core.loginByToken({ sdk.core.loginByToken({
token: token as string, token: token as string,
......
import { PassportTokenController, SdkCore, uniAdapter } from "@common/sdk" import { Sdk as SdkBase, TokenManager, uniAdapter } from "@common/sdk"
import { LoginService } from "@common/sdk/services/login-service" import { createLoginService } from "@common/sdk/services/login-service"
import { VerifyService } from "@common/sdk/services/verify-service" import { createVerifyService } from "@common/sdk/services/verify-service"
import { config } from "@/config" import { config } from "@/config"
class Sdk extends SdkCore { class Sdk extends SdkBase {
constructor() { constructor() {
super(config, uniAdapter) super(config, uniAdapter)
} }
...@@ -45,10 +45,10 @@ class UniStorage implements Storage { ...@@ -45,10 +45,10 @@ class UniStorage implements Storage {
} }
// 设置小程序存储实例(替代 localStorage) // 设置小程序存储实例(替代 localStorage)
PassportTokenController.setupStorage(new UniStorage()) TokenManager.setupStorage(new UniStorage())
// 创建服务实例(依赖注入 SDK // 创建服务(函数式,无需实例化
const loginService = new LoginService(sdk) export const loginService = createLoginService(sdk.core, sdk.clientId)
const verifyService = new VerifyService(sdk) export const verifyService = createVerifyService(sdk.core, sdk.clientId)
export { loginService, sdk, verifyService } export { sdk }
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { PassportTokenController } from "@common/sdk" import { TokenManager } from "@common/sdk"
import { onLoad } from "@dcloudio/uni-app" import { onLoad } from "@dcloudio/uni-app"
import { ref } from "vue" import { ref } from "vue"
import { miniProgramBindPhone } from "@/api/login-service" import { miniProgramBindPhone } from "@/api/login-service"
...@@ -105,7 +105,7 @@ async function doWxLogin(e: any) { ...@@ -105,7 +105,7 @@ async function doWxLogin(e: any) {
e.detail.iv, e.detail.iv,
) )
// 保存 token // 保存 token
PassportTokenController.saveToken2Storage(result.jwt) TokenManager.saveToken2Storage(result.jwt)
uni.hideLoading() uni.hideLoading()
uni.showToast({ title: "登录成功", icon: "success" }) uni.showToast({ title: "登录成功", icon: "success" })
setTimeout(() => { setTimeout(() => {
......
...@@ -141,7 +141,7 @@ ...@@ -141,7 +141,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VerifyImageResult } from "@common/sdk" import type { VerifyImageResult } from "@common/sdk"
import { PassportTokenController } from "@common/sdk" import { TokenManager } from "@common/sdk"
import { onLoad } from "@dcloudio/uni-app" import { onLoad } from "@dcloudio/uni-app"
import { computed, reactive, ref } from "vue" import { computed, reactive, ref } from "vue"
import { loginService, verifyService } from "@/api/http" import { loginService, verifyService } from "@/api/http"
...@@ -257,7 +257,7 @@ async function smsLogin() { ...@@ -257,7 +257,7 @@ async function smsLogin() {
smsLoading.value = true smsLoading.value = true
try { try {
const result = await loginService.verifyCodeLogin(smsModel.mobile, smsModel.code) const result = await loginService.verifyCodeLogin(smsModel.mobile, smsModel.code)
PassportTokenController.saveToken2Storage(result.jwt) TokenManager.saveToken2Storage(result.jwt)
uni.showToast({ title: "登录成功", icon: "success" }) uni.showToast({ title: "登录成功", icon: "success" })
setTimeout(() => { setTimeout(() => {
const redirect = uni.getStorageSync("loginRedirect") || "/pages/home/index" const redirect = uni.getStorageSync("loginRedirect") || "/pages/home/index"
...@@ -284,7 +284,7 @@ async function passwordLogin() { ...@@ -284,7 +284,7 @@ async function passwordLogin() {
pwdLoading.value = true pwdLoading.value = true
try { try {
const result = await loginService.login(passwordModel.username, passwordModel.password) const result = await loginService.login(passwordModel.username, passwordModel.password)
PassportTokenController.saveToken2Storage(result.jwt) TokenManager.saveToken2Storage(result.jwt)
uni.showToast({ title: "登录成功", icon: "success" }) uni.showToast({ title: "登录成功", icon: "success" })
setTimeout(() => { setTimeout(() => {
const redirect = uni.getStorageSync("loginRedirect") || "/pages/home/index" const redirect = uni.getStorageSync("loginRedirect") || "/pages/home/index"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment