一大波改动
这个提交包含在:
父节点
460ba5f112
当前提交
66801ca26c
@ -1 +0,0 @@
|
||||
../XuqmGroup-Web/node_modules
|
||||
2233
package-lock.json
自动生成的
普通文件
2233
package-lock.json
自动生成的
普通文件
文件差异内容过多而无法显示
加载差异
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@xuqm/vue3-sdk",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.2",
|
||||
"description": "XuqmGroup Vue3 SDK — IM & platform integration for web",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
export const DEFAULT_API_BASE_URL = 'https://dev.xuqinmin.com'
|
||||
export const DEFAULT_IM_WS_URL = 'wss://dev.xuqinmin.com/ws/im'
|
||||
export const DEFAULT_IM_WS_URL = 'wss://im.dev.xuqinmin.com/ws/im'
|
||||
|
||||
@ -44,6 +44,13 @@ export class ImClient {
|
||||
private listeners: { [K in keyof ImEventMap]?: Set<EventListener<K>> } = {}
|
||||
private subscriptionSeed = 0
|
||||
private subscriptions = new Map<string, string>() // destination -> id
|
||||
private readonly tokenOverride: (() => string | null) | null
|
||||
private readonly wsUrlOverride: string | null
|
||||
|
||||
constructor(options?: { tokenSupplier?: () => string | null; wsUrl?: string }) {
|
||||
this.tokenOverride = options?.tokenSupplier ?? null
|
||||
this.wsUrlOverride = options?.wsUrl ?? null
|
||||
}
|
||||
|
||||
on<K extends keyof ImEventMap>(event: K, handler: EventListener<K>): this {
|
||||
const store = this.listeners as Record<string, Set<unknown>>
|
||||
@ -66,9 +73,10 @@ export class ImClient {
|
||||
|
||||
connect(): void {
|
||||
if (this.destroyed) return
|
||||
const config = getConfig()
|
||||
const token = getToken()
|
||||
const url = `${config.wsUrl || DEFAULT_IM_WS_URL}?token=${token ?? ''}`
|
||||
const config = (() => { try { return getConfig() } catch { return { debug: false, wsUrl: '', appKey: '' } } })()
|
||||
const token = this.tokenOverride ? this.tokenOverride() : getToken()
|
||||
const baseWsUrl = this.wsUrlOverride ?? config.wsUrl ?? DEFAULT_IM_WS_URL
|
||||
const url = `${baseWsUrl || DEFAULT_IM_WS_URL}?token=${token ?? ''}`
|
||||
|
||||
this.ws = new WebSocket(url)
|
||||
let buffer = ''
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
import { ref, onUnmounted } from 'vue'
|
||||
import { ImClient } from './ImClient'
|
||||
import type { ImMessage } from '../types'
|
||||
|
||||
export interface StoreReviewNotification {
|
||||
event: string
|
||||
appKey: string
|
||||
versionId: string
|
||||
storeType: string
|
||||
reviewState: string
|
||||
reviewReason: string
|
||||
stage: string
|
||||
batchId: string
|
||||
publishStatus: string
|
||||
source: string
|
||||
timestamp: number
|
||||
}
|
||||
|
||||
export interface UseStoreReviewNotificationOptions {
|
||||
tokenSupplier: () => Promise<string>
|
||||
onNotification: (notification: StoreReviewNotification) => void
|
||||
wsUrl?: string
|
||||
}
|
||||
|
||||
export function useStoreReviewNotification(options: UseStoreReviewNotificationOptions) {
|
||||
const connected = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
let client: ImClient | null = null
|
||||
let currentToken: string | null = null
|
||||
|
||||
async function connect() {
|
||||
try {
|
||||
currentToken = await options.tokenSupplier()
|
||||
} catch (e) {
|
||||
error.value = e instanceof Error ? e.message : 'Failed to fetch platform IM token'
|
||||
return
|
||||
}
|
||||
|
||||
client = new ImClient({ tokenSupplier: () => currentToken, wsUrl: options.wsUrl })
|
||||
|
||||
client.on('connected', () => {
|
||||
connected.value = true
|
||||
error.value = null
|
||||
})
|
||||
|
||||
client.on('disconnected', () => {
|
||||
connected.value = false
|
||||
})
|
||||
|
||||
client.on('error', (e) => {
|
||||
error.value = e instanceof Error ? e.message : (e as Event).type ?? 'IM connection error'
|
||||
})
|
||||
|
||||
client.on('message', (msg: ImMessage) => {
|
||||
if (msg.msgType !== 'NOTIFY') return
|
||||
try {
|
||||
const payload =
|
||||
typeof msg.content === 'string'
|
||||
? (JSON.parse(msg.content) as StoreReviewNotification)
|
||||
: (msg.content as unknown as StoreReviewNotification)
|
||||
if (payload?.event === 'store_review_update') {
|
||||
options.onNotification(payload)
|
||||
}
|
||||
} catch {
|
||||
// ignore malformed NOTIFY content
|
||||
}
|
||||
})
|
||||
|
||||
client.connect()
|
||||
}
|
||||
|
||||
function disconnect() {
|
||||
client?.disconnect()
|
||||
client = null
|
||||
connected.value = false
|
||||
}
|
||||
|
||||
onUnmounted(disconnect)
|
||||
|
||||
return { connect, disconnect, connected, error }
|
||||
}
|
||||
@ -67,6 +67,8 @@ export {
|
||||
syncOfflineMessages,
|
||||
} from './im/api'
|
||||
export { useIm } from './im/useIm'
|
||||
export { useStoreReviewNotification } from './im/useStoreReviewNotification'
|
||||
export type { StoreReviewNotification, UseStoreReviewNotificationOptions } from './im/useStoreReviewNotification'
|
||||
export type {
|
||||
SDKConfig,
|
||||
MsgType,
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户