Files
lucky_shop/common/js/hw-jssdk.js

362 lines
10 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 华为快应用 HwService JS SDK 统一封装
* 用于 H5 壳模式下的快应用环境,通过 hms-js-base 桥接层调用 HMS Core 服务
*
* 架构说明:
* - 所有 HMS 服务通过 @hw-hmscore/hms-js-base 的 hmsjsb.invoke() 统一桥接
* - Analytics Kit 有独立封装 @hw-hmscore/analytics-sdk-quickapp(可选安装)
* - Account Kit 无独立 quickapp npm 包,直接通过 hmsjsb.invoke 调用
* - Push Kit 无独立 quickapp npm 包,直接通过 hmsjsb.invoke 调用
*
* 使用方式:
* import HwService from '@/common/js/hw-jssdk.js'
*
* // 初始化
* await HwService.init()
*
* // 华为帐号登录
* const userInfo = await HwService.Account.signIn()
*
* // 分析服务埋点
* HwService.Analytics.onEvent('event_name', { key: 'value' })
*
* @version 1.1.0
*/
// hms-js-base 提供底层 JS Bridge 桥接能力
let hmsjsb = null
let hmsbase = null
// Analytics SDK 独立包(可选安装)
let HiAnalytics = null
// #ifdef H5_XCX_5G_QUICKAPP_COM || H5_XCX_AIGC_QUICKAPP_COM || H5_5G_AIGC_QUICKAPP_COM || H5_TEST_AIGC_QUICKAPP_COM
try {
// 加载基础桥接库(必装)
const hmsBase = require('@hw-hmscore/hms-js-base')
hmsjsb = hmsBase.hmsjsb
hmsbase = hmsBase.hmsbase
// 尝试加载 Analytics SDK(可选)
try {
HiAnalytics = require('@hw-hmscore/analytics-sdk-quickapp')
} catch (e) {
console.log('[HwService] Analytics SDK 未安装,将使用 invoke 桥接方式')
}
} catch (e) {
console.log('[HwService] hms-js-base 未安装或不在快应用环境')
}
// #endif
class HwService {
constructor() {
this._initialized = false
this._config = null
// 子服务实例
this.Account = null
this.Analytics = null
this.Push = null
}
/**
* 判断当前是否运行在快应用引擎环境
*/
isQuickAppEnv() {
// #ifdef H5_XCX_5G_QUICKAPP_COM || H5_XCX_AIGC_QUICKAPP_COM || H5_5G_AIGC_QUICKAPP_COM || H5_TEST_AIGC_QUICKAPP_COM
if (typeof window !== 'undefined') {
return !!(
window.qa ||
window.__HwService__ ||
window.hms ||
hmsjsb || // hms-js-base 加载成功
navigator.userAgent.indexOf('QuickApp') > -1
)
}
// #endif
return false
}
/**
* 初始化 HwService
* @param {Object} config { appId, clientId, clientSecret }
*/
async init(config = {}) {
if (this._initialized) {
console.log('[HwService] 已初始化,跳过')
return
}
this._config = config
console.log('[HwService] 开始初始化...')
try {
// 子服务实例化
this.Account = new AccountService(hmsjsb)
this.Analytics = new AnalyticsService(hmsjsb, HiAnalytics)
this.Push = new PushService(hmsjsb)
this._initialized = true
console.log('[HwService] 初始化完成')
} catch (error) {
console.error('[HwService] 初始化失败:', error)
throw error
}
}
}
// ============================================================
// 底层 invoke 封装
// ============================================================
/**
* 通过 hmsjsb.invoke 调用 HMS Core API 的 Promise 封装
* @param {Object} hmsjsbRef hmsjsb 引用
* @param {string} apiName API 名称
* @param {Object} args 参数
* @returns {Promise<Object>}
*/
function invokeHmsApi(hmsjsbRef, apiName, args = {}) {
return new Promise((resolve, reject) => {
if (!hmsjsbRef || typeof hmsjsbRef.invoke !== 'function') {
reject(new Error('[HwService] hmsjsb.invoke 不可用'))
return
}
hmsjsbRef.invoke({
apiName,
args,
success: (res) => resolve(res),
fail: (err) => reject(err)
})
})
}
// ============================================================
// 华为帐号服务 (Account Kit)
// 通过 hmsjsb.invoke 桥接(无独立 npm 包)
// ============================================================
class AccountService {
constructor(hmsjsbRef) {
this._hmsjsb = hmsjsbRef
}
/**
* 华为帐号登录
* @param {Array} scopes 授权范围
* @returns {Promise<Object>} 用户信息
*/
async signIn(scopes = ['openid', 'profile']) {
console.log('[HwService.Account] signIn...')
// apiName 需根据实际华为文档确认,常见值有:
// 'accountSignIn' | 'com.huawei.hms.api.Account.signIn'
const result = await invokeHmsApi(this._hmsjsb, 'accountSignIn', { scopes })
return this._formatUserInfo(result)
}
/**
* 静默获取华为帐号用户信息
*/
async getUserInfo() {
const result = await invokeHmsApi(this._hmsjsb, 'accountGetUserInfo', {})
return this._formatUserInfo(result)
}
/**
* 退出登录
*/
async signOut() {
try {
await invokeHmsApi(this._hmsjsb, 'accountSignOut', {})
} catch (e) {
console.warn('[HwService.Account] signOut 失败:', e)
}
}
/**
* 统一格式化用户信息
*/
_formatUserInfo(rawInfo) {
if (!rawInfo) return null
return {
openId: rawInfo.openId || rawInfo.openid || '',
unionId: rawInfo.unionId || rawInfo.unionid || '',
displayName: rawInfo.displayName || rawInfo.nickName || rawInfo.nickname || '',
avatarUrl: rawInfo.avatarUrl || rawInfo.avatar || rawInfo.headPictureUrl || '',
gender: rawInfo.gender || 0,
country: rawInfo.country || '',
province: rawInfo.province || '',
city: rawInfo.city || '',
raw: rawInfo
}
}
}
// ============================================================
// 华为分析服务 (Analytics Kit)
// 支持 @hw-hmscore/analytics-sdk-quickapp(优先)或 invoke 桥接
// ============================================================
class AnalyticsService {
constructor(hmsjsbRef, hiAnalyticsSdk) {
this._hmsjsb = hmsjsbRef
this._sdk = hiAnalyticsSdk
}
/**
* 上报事件
* @param {string} eventName 事件名称
* @param {Object} params 事件参数
*/
onEvent(eventName, params = {}) {
// 方案一:Analytics SDK(独立封装包)
if (this._sdk && typeof this._sdk.onEvent === 'function') {
this._sdk.onEvent(eventName, params)
return
}
if (this._sdk && typeof this._sdk.HiAnalytics?.getInstance === 'function') {
try {
const instance = this._sdk.HiAnalytics.getInstance()
instance.onEvent(eventName, params)
return
} catch (e) {
// fallthrough
}
}
// 方案二:invoke 桥接
if (this._hmsjsb) {
this._hmsjsb.invoke({
apiName: 'analyticsOnEvent',
args: { eventName, params },
success: () => {},
fail: (err) => console.warn('[HwService.Analytics] onEvent 失败:', err)
})
return
}
// fallback
console.log('[HwService.Analytics] onEvent (fallback):', eventName, params)
}
/**
* 设置用户属性
* @param {Object} profile
*/
setUserProfile(profile = {}) {
if (this._sdk && typeof this._sdk.setUserProfile === 'function') {
this._sdk.setUserProfile(profile)
return
}
if (this._sdk && typeof this._sdk.HiAnalytics?.getInstance === 'function') {
try {
const instance = this._sdk.HiAnalytics.getInstance()
instance.setUserProfile(profile)
return
} catch (e) {}
}
if (this._hmsjsb) {
this._hmsjsb.invoke({
apiName: 'analyticsSetUserProfile',
args: { profile },
success: () => {},
fail: (err) => console.warn('[HwService.Analytics] setUserProfile 失败:', err)
})
return
}
console.log('[HwService.Analytics] setUserProfile (fallback):', profile)
}
/**
* 设置用户 ID
* @param {string} userId
*/
setUserId(userId) {
if (this._sdk && typeof this._sdk.setUserId === 'function') {
this._sdk.setUserId(userId)
return
}
if (this._sdk && typeof this._sdk.HiAnalytics?.getInstance === 'function') {
try {
const instance = this._sdk.HiAnalytics.getInstance()
instance.setUserId(userId)
return
} catch (e) {}
}
if (this._hmsjsb) {
this._hmsjsb.invoke({
apiName: 'analyticsSetUserId',
args: { userId },
success: () => {},
fail: (err) => console.warn('[HwService.Analytics] setUserId 失败:', err)
})
return
}
console.log('[HwService.Analytics] setUserId (fallback):', userId)
}
/**
* 页面浏览事件
*/
onPageView(pageName, pageClassOverride = '') {
this.onEvent('$PageView', {
pageName,
pageClassOverride: pageClassOverride || pageName
})
}
}
// ============================================================
// 华为推送服务 (Push Kit)
// 通过 hmsjsb.invoke 桥接(无独立 npm 包)
// ============================================================
class PushService {
constructor(hmsjsbRef) {
this._hmsjsb = hmsjsbRef
this._token = null
}
/**
* 获取推送令牌
*/
async getToken() {
if (this._token) return this._token
try {
const result = await invokeHmsApi(this._hmsjsb, 'pushGetToken', {})
this._token = result.token || result
return this._token
} catch (e) {
console.warn('[HwService.Push] getToken 不可用:', e)
return null
}
}
/**
* 监听推送令牌变更
*/
onTokenReceived(callback) {
if (!this._hmsjsb) return
this._hmsjsb.on('pushOnToken', callback)
}
/**
* 监听消息到达
*/
onMessageReceived(callback) {
if (!this._hmsjsb) return
this._hmsjsb.on('pushOnMessageReceived', callback)
}
/**
* 监听通知点击
*/
onNotificationClicked(callback) {
if (!this._hmsjsb) return
this._hmsjsb.on('pushOnNotificationClicked', callback)
}
}
// ============================================================
// 导出单例
// ============================================================
const hwService = new HwService()
export default hwService
export { AccountService, AnalyticsService, PushService }