Compare commits
1 Commits
feat/camca
...
test/hw-se
| Author | SHA1 | Date | |
|---|---|---|---|
| 1cfd2db49e |
@@ -98,6 +98,54 @@ export default {
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef H5_XCX_5G_QUICKAPP_COM || H5_XCX_AIGC_QUICKAPP_COM || H5_5G_AIGC_QUICKAPP_COM || H5_TEST_AIGC_QUICKAPP_COM
|
||||
this._huaweiSignIn(callback);
|
||||
// #endif
|
||||
},
|
||||
|
||||
/**
|
||||
* 华为快应用帐号登录
|
||||
*/
|
||||
async _huaweiSignIn(callback) {
|
||||
try {
|
||||
const HwService = require('@/common/js/hw-jssdk.js').default;
|
||||
// 确保 HwService 已初始化
|
||||
if (!HwService.isQuickAppEnv()) {
|
||||
console.warn('[Auth] 非快应用环境,跳过华为帐号登录');
|
||||
return;
|
||||
}
|
||||
const userInfo = await HwService.Account.signIn();
|
||||
if (userInfo && userInfo.openId) {
|
||||
// 将华为 openId 传给后端换取系统 token
|
||||
this.$api.sendRequest({
|
||||
url: '/wechat/api/quickapp/huawei_auth',
|
||||
data: {
|
||||
openid: userInfo.openId,
|
||||
unionid: userInfo.unionId,
|
||||
nickname: userInfo.displayName,
|
||||
avatar: userInfo.avatarUrl,
|
||||
gender: userInfo.gender
|
||||
},
|
||||
success: res => {
|
||||
if (res.code >= 0) {
|
||||
if (res.data.openid) this.authInfo.hw_openid = res.data.openid;
|
||||
if (res.data.unionid) this.authInfo.hw_unionid = res.data.unionid;
|
||||
typeof callback == 'function' && callback(this.authInfo);
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message ? res.message : '华为帐号登录失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Auth] 华为帐号登录失败:', error);
|
||||
this.$util.showToast({
|
||||
title: '华为帐号登录失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,5 +120,16 @@ export default {
|
||||
pingInterval: 1500,
|
||||
|
||||
// 版本号
|
||||
version: '1.0'
|
||||
version: '1.0',
|
||||
|
||||
// 华为快应用 HwService 配置
|
||||
// 需在 AppGallery Connect 创建应用后获取
|
||||
huawei: {
|
||||
// AGC 应用配置(替换为实际的 AGC 配置值)
|
||||
appId: '', // 应用ID
|
||||
clientId: '', // 客户端ID
|
||||
clientSecret: '', // 客户端密钥(注意安全,建议由后端下发)
|
||||
// 华为帐号登录回调地址
|
||||
redirectUri: window.location.origin + '/hwappx/common/',
|
||||
}
|
||||
};
|
||||
@@ -61,6 +61,9 @@ class EventBus {
|
||||
return 'xhs'
|
||||
// #endif
|
||||
|
||||
// #ifdef H5_XCX_5G_QUICKAPP_COM || H5_XCX_AIGC_QUICKAPP_COM || H5_5G_AIGC_QUICKAPP_COM || H5_TEST_AIGC_QUICKAPP_COM
|
||||
return 'quickapp'
|
||||
// #endif
|
||||
|
||||
return 'unknown'
|
||||
}
|
||||
|
||||
@@ -37,6 +37,11 @@ const app_type = 'app';
|
||||
const app_type_name = 'APP';
|
||||
// #endif
|
||||
|
||||
// #ifdef H5_XCX_5G_QUICKAPP_COM || H5_XCX_AIGC_QUICKAPP_COM || H5_5G_AIGC_QUICKAPP_COM || H5_TEST_AIGC_QUICKAPP_COM
|
||||
const app_type = 'quickapp';
|
||||
const app_type_name = '快应用';
|
||||
// #endif
|
||||
|
||||
export default {
|
||||
sendRequest(params) {
|
||||
if (!Config.baseUrl) {
|
||||
|
||||
361
common/js/hw-jssdk.js
Normal file
361
common/js/hw-jssdk.js
Normal file
@@ -0,0 +1,361 @@
|
||||
/**
|
||||
* 华为快应用 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 }
|
||||
158
docs/hwservice-integration-guide.md
Normal file
158
docs/hwservice-integration-guide.md
Normal file
@@ -0,0 +1,158 @@
|
||||
# 华为快应用 HwService JS SDK 集成指南
|
||||
|
||||
## 概述
|
||||
|
||||
本文档介绍如何将该 uni-app 项目以 H5 壳模式部署到华为快应用平台,并集成华为 HwService JS SDK(帐号服务 + 分析服务)。
|
||||
|
||||
## 项目架构
|
||||
|
||||
```
|
||||
H5 壳模式快应用架构:
|
||||
┌─────────────────────────────────────┐
|
||||
│ 华为快应用引擎 (QuickApp Runtime) │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ WebView (H5 页面) │ │
|
||||
│ │ ┌───────────────────────────┐ │ │
|
||||
│ │ │ uni-app 应用 │ │ │
|
||||
│ │ │ ├─ common/js/hw-jssdk.js │ │ │
|
||||
│ │ │ ├─ common/js/auth.js │ │ │
|
||||
│ │ │ └─ store/index.js │ │ │
|
||||
│ │ └───────────────────────────┘ │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
│ │ HwService Bridge │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ HMS Core (华为移动服务) │ │
|
||||
│ │ ├─ Account Kit (帐号服务) │ │
|
||||
│ │ ├─ Analytics Kit (分析服务) │ │
|
||||
│ │ └─ Push Kit (推送服务,可选) │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 部署前准备
|
||||
|
||||
### 1. 华为 AppGallery Connect 配置
|
||||
|
||||
1. 登录 [AppGallery Connect](https://developer.huawei.com/consumer/cn/service/josp/agc/index.html)
|
||||
2. 创建应用(选择「快应用」类型)
|
||||
3. 开启以下服务:
|
||||
- **华为帐号服务 (Account Kit)**
|
||||
- **华为分析服务 (Analytics Kit)**(可选)
|
||||
- **华为推送服务 (Push Kit)**(可选)
|
||||
4. 下载 `agconnect-services.json` 配置文件
|
||||
5. 将配置文件放入项目根目录
|
||||
|
||||
### 2. 安装 npm 依赖
|
||||
|
||||
```bash
|
||||
# 基础桥接库(必装,提供 hmsjsb.invoke 桥接能力)
|
||||
npm install --save @hw-hmscore/hms-js-base
|
||||
|
||||
# 华为分析服务封装包(可选,提供更完善的 API 封装)
|
||||
npm install --save @hw-hmscore/analytics-sdk-quickapp
|
||||
```
|
||||
|
||||
**注意:**
|
||||
- **Account Kit(帐号服务)** 和 **Push Kit(推送服务)** 没有独立的 quickapp npm 包,统一通过 `@hw-hmscore/hms-js-base` 的 `hmsjsb.invoke()` 桥接调用
|
||||
- `@hw-hmscore/analytics-sdk-quickapp` 版本 `6.10.0-301`(ISC 许可证),**可选安装**——不装则走 invoke 桥接
|
||||
- 相关 npm 包由华为官方发布(`hmscore@huawei.com`)
|
||||
|
||||
### 3. 配置 HUAWEI 条件编译
|
||||
|
||||
本项目的 `package.json` 已为各快应用域名定义自定义发行脚本:
|
||||
|
||||
| 脚本名 | 条件编译标记 | 用途 |
|
||||
|--------|------------|------|
|
||||
| `h5-xcx20.5g-quickapp.com` | `H5_XCX_5G_QUICKAPP_COM` | 5G 快应用 |
|
||||
| `h5-xcx.aigc-quickapp.com` | `H5_XCX_AIGC_QUICKAPP_COM` | AIGC 快应用 |
|
||||
| `h5-5g.aigc-quickapp.com` | `H5_5G_AIGC_QUICKAPP_COM` | 5G AIGC 快应用 |
|
||||
| `h5-test.aigc-quickapp.com` | `H5_TEST_AIGC_QUICKAPP_COM` | 测试快应用 |
|
||||
|
||||
当使用 HBuilderX → 发行 → 自定义发行 时,对应的 `#ifdef` 条件编译块会被激活。
|
||||
|
||||
### 4. 配置华为参数
|
||||
|
||||
编辑 `common/js/config.js` 中的 `huawei` 配置项:
|
||||
|
||||
```javascript
|
||||
huawei: {
|
||||
appId: '你的AGC应用ID',
|
||||
clientId: '你的客户端ID',
|
||||
clientSecret: '你的客户端密钥(建议由后端下发)',
|
||||
redirectUri: window.location.origin + '/hwappx/common/',
|
||||
}
|
||||
```
|
||||
|
||||
**注意**:`clientSecret` 敏感信息建议由后端接口动态下发,避免在前端硬编码。
|
||||
|
||||
## 后端配合
|
||||
|
||||
### 新增接口
|
||||
|
||||
华为帐号登录需要后端增加以下接口:
|
||||
|
||||
| 接口路径 | 方法 | 说明 |
|
||||
|---------|------|------|
|
||||
| `/wechat/api/quickapp/huawei_auth` | POST | 华为 openId 换 token |
|
||||
|
||||
**请求参数**:
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `openid` | string | 华为帐号 openId |
|
||||
| `unionid` | string | 华为帐号 unionId(可选) |
|
||||
| `nickname` | string | 用户昵称 |
|
||||
| `avatar` | string | 头像 URL |
|
||||
| `gender` | int | 性别(0:未知 1:男 2:女) |
|
||||
|
||||
**返回格式**(需与现有登录接口保持一致):
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"openid": "华为openId",
|
||||
"unionid": "华为unionId"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 已修改的文件清单
|
||||
|
||||
| 文件 | 变更类型 | 说明 |
|
||||
|------|---------|------|
|
||||
| `common/js/hw-jssdk.js` | **新增** | HwService 统一封装(Account/Analytics/Push) |
|
||||
| `common/js/auth.js` | 修改 | 新增 `_huaweiSignIn` 方法,快应用环境下使用华为帐号登录 |
|
||||
| `common/js/http.js` | 修改 | 新增 `H5_XCX_*_QUICKAPP_COM` 条件编译,请求类型为 `quickapp` |
|
||||
| `common/js/event-bus.js` | 修改 | 新增 `quickapp` 平台检测分支 |
|
||||
| `common/js/config.js` | 修改 | 新增 `huawei` 配置项 |
|
||||
| `store/index.js` | 修改 | 新增 `huaweiAccountInfo` 状态/`initHwService` action |
|
||||
|
||||
## 发布流程
|
||||
|
||||
1. 使用 HBuilderX 打开项目
|
||||
2. 修改 `manifest.json` → Web 配置 → 基础路径(`/hwappx/common/`)
|
||||
3. 选择「发行」→「自定义发行」→ 选择对应的快应用脚本
|
||||
4. 构建完成后,将 `unpackage/dist/build/web/` 目录打包为 zip
|
||||
5. 使用华为快应用 IDE 导入并发布
|
||||
|
||||
## 验证方式
|
||||
|
||||
### 检查 HwService 是否可用
|
||||
```javascript
|
||||
const HwService = require('@/common/js/hw-jssdk.js').default;
|
||||
console.log('是否快应用环境:', HwService.isQuickAppEnv());
|
||||
```
|
||||
|
||||
### 验证华为帐号登录
|
||||
在华为手机上打开快应用,点击登录,应弹出华为帐号授权窗口。
|
||||
|
||||
### 验证分析服务
|
||||
集成后可在 AppGallery Connect 控制台查看埋点数据。
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **H5 壳模式限制**:HwService 依赖华为快应用引擎注入的 Bridge,在普通浏览器中不可用
|
||||
2. **真机测试**:必须在华为手机上测试,模拟器可能无法完整模拟 Bridge
|
||||
3. **条件编译生效**:必须通过 HBuilderX 的自定义发行脚本构建,`#ifdef` 标记才会生效
|
||||
4. **clientSecret 安全**:建议由后端接口动态下发,不要前端硬编码
|
||||
5. **登录降级**:如果华为帐号服务不可用,建议提供短信验证码或其他登录方式作为降级方案
|
||||
@@ -89,6 +89,8 @@ const store = new Vuex.Store({
|
||||
status: false,
|
||||
path: ''
|
||||
},
|
||||
// 华为快应用帐号信息
|
||||
huaweiAccountInfo: null,
|
||||
},
|
||||
mutations: {
|
||||
// 设置是否可以领取新人礼
|
||||
@@ -246,8 +248,17 @@ const store = new Vuex.Store({
|
||||
// 设置主题颜色
|
||||
setThemeColor(state, value) {
|
||||
state.themeColor = value;
|
||||
},
|
||||
// 华为快应用帐号信息
|
||||
setHuaweiAccountInfo(state, value) {
|
||||
state.huaweiAccountInfo = value;
|
||||
if (value) {
|
||||
uni.setStorageSync('huaweiAccountInfo', value);
|
||||
} else {
|
||||
uni.removeStorageSync('huaweiAccountInfo');
|
||||
}
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
// AI智能助手配置
|
||||
globalAIKefuConfig: state => state.globalAIKefuConfig,
|
||||
@@ -303,6 +314,8 @@ const store = new Vuex.Store({
|
||||
this.commit('setGlobalStoreInfo', null);
|
||||
}
|
||||
this.commit('setInitStatus', true)
|
||||
// 初始化华为快应用 HwService(H5 壳模式下的快应用环境)
|
||||
this.dispatch('initHwService');
|
||||
resolve(data);
|
||||
}
|
||||
}
|
||||
@@ -441,6 +454,30 @@ const store = new Vuex.Store({
|
||||
console.error('设置主题颜色失败', e);
|
||||
}
|
||||
// console.log('themeColor => ', this.state.themeColor);
|
||||
},
|
||||
// 初始化华为快应用 HwService
|
||||
initHwService() {
|
||||
// #ifdef H5_XCX_5G_QUICKAPP_COM || H5_XCX_AIGC_QUICKAPP_COM || H5_5G_AIGC_QUICKAPP_COM || H5_TEST_AIGC_QUICKAPP_COM
|
||||
try {
|
||||
const HwService = require('@/common/js/hw-jssdk.js').default;
|
||||
if (HwService.isQuickAppEnv()) {
|
||||
HwService.init().then(() => {
|
||||
console.log('[Store] HwService 初始化成功');
|
||||
// 检查是否有缓存的华为帐号信息
|
||||
const cachedInfo = uni.getStorageSync('huaweiAccountInfo');
|
||||
if (cachedInfo) {
|
||||
this.commit('setHuaweiAccountInfo', cachedInfo);
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('[Store] HwService 初始化失败:', err);
|
||||
});
|
||||
} else {
|
||||
console.log('[Store] 非快应用环境,跳过 HwService 初始化');
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('[Store] HwService 未配置,跳过初始化');
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user