基于HarmonyOS Next的生活服务类应用开发实战:AppGallery Connect集成指
基于HarmonyOS Next的生活服务类应用开发实战:AppGallery Connect集成指南
一、AppGallery Connect简介与环境准备
AppGallery Connect是华为为开发者提供的一站式应用服务平台,它为HarmonyOS应用开发提供了丰富的后端能力支持。在生活服务类应用中,我们可以利用AppGallery Connect实现用户认证、数据存储、推送通知等核心功能。
首先需要确保开发环境配置正确:
- 安装最新版DevEco Studio(建议4.0及以上版本)
- 注册华为开发者账号
- 在AppGallery Connect中创建项目并启用所需服务
// 示例:在config.json中添加AppGallery Connect配置 { "app": { "bundleName": "com.example.lifeservice", "vendor": "example", "version": { "code": 1, "name": "1.0" }, "apiVersion": { "compatible": 8, "target": 9, "releaseType": "Release" } }, "deviceConfig": { "default": { "agconnect": { "api_key": "YOUR_API_KEY", // 从AGC控制台获取 "app_id": "YOUR_APP_ID", // 从AGC控制台获取 "cp_id": "YOUR_CP_ID", // 从AGC控制台获取 "product_id": "YOUR_PRODUCT_ID" } } } }
二、用户认证服务集成
生活服务类应用通常需要用户系统来提供个性化服务。AppGallery Connect提供了多种认证方式,包括手机号、邮箱、华为账号等。
2.1 初始化认证服务
import agconnect from '@hw-agconnect/api'; import '@hw-agconnect/auth-component'; // 在应用启动时初始化AGC async function initAGC() { try { await agconnect.instance().init(); console.log('AGC初始化成功'); } catch (error) { console.error('AGC初始化失败:', error); } } // 在EntryAbility的onCreate中调用 export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { initAGC(); } }
2.2 实现手机号登录功能
// 登录页面组件 @Component struct LoginPage { @State phoneNumber: string = ''; @State verifyCode: string = ''; @State isCounting: boolean = false; @State countdown: number = 60; // 发送验证码 async sendVerifyCode() { if (!this.phoneNumber) { prompt.showToast({ message: '请输入手机号' }); return; } try { const authService = agconnect.auth().getAuthService(); await authService.requestPhoneVerifyCode('86', this.phoneNumber); this.startCountdown(); prompt.showToast({ message: '验证码已发送' }); } catch (error) { prompt.showToast({ message: '发送验证码失败: ' + error.message }); } } // 倒计时处理 startCountdown() { this.isCounting = true; const timer = setInterval(() => { if (this.countdown <= 0) { clearInterval(timer); this.isCounting = false; this.countdown = 60; } else { this.countdown--; } }, 1000); } // 执行登录 async doLogin() { if (!this.phoneNumber || !this.verifyCode) { prompt.showToast({ message: '请输入手机号和验证码' }); return; } try { const authService = agconnect.auth().getAuthService(); const credential = agconnect.auth.PhoneAuthProvider.credentialWithVerifyCode( '86', this.phoneNumber, this.verifyCode ); const user = await authService.signIn(credential); prompt.showToast({ message: '登录成功: ' + user.getUid() }); // 跳转到主页 router.replaceUrl({ url: 'pages/HomePage' }); } catch (error) { prompt.showToast({ message: '登录失败: ' + error.message }); } } build() { Column() { TextInput({ placeholder: '请输入手机号' }) .width('90%') .height(50) .type(InputType.Number) .onChange((value: string) => { this.phoneNumber = value; }) Row() { TextInput({ placeholder: '请输入验证码' }) .width('60%') .height(50) .type(InputType.Number) .onChange((value: string) => { this.verifyCode = value; }) Button(this.isCounting ? `${this.countdown}秒后重试` : '获取验证码') .width('30%') .height(50) .enabled(!this.isCounting) .onClick(() => this.sendVerifyCode()) } .width('90%') .justifyContent(FlexAlign.SpaceBetween) Button('登录') .width('90%') .height(50) .margin({ top: 20 }) .onClick(() => this.doLogin()) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) } }
三、云数据库服务集成
生活服务类应用通常需要存储用户数据、服务信息等。AppGallery Connect提供了云数据库服务,支持实时同步和离线缓存。
3.1 初始化云数据库
import '@hw-agconnect/database-server'; // 数据库服务工具类 class CloudDBHelper { private static instance: CloudDBHelper; private cloudDB: any; private constructor() { this.initCloudDB(); } static getInstance(): CloudDBHelper { if (!CloudDBHelper.instance) { CloudDBHelper.instance = new CloudDBHelper(); } return CloudDBHelper.instance; } private async initCloudDB() { try { const agc = agconnect.instance(); this.cloudDB = agc.cloudDB(); await this.cloudDB.initEnv(); console.log('CloudDB初始化成功'); } catch (error) { console.error('CloudDB初始化失败:', error); } } // 获取数据库实例 getCloudDB() { return this.cloudDB; } } // 在应用启动时初始化 CloudDBHelper.getInstance();
3.2 定义数据模型与CRUD操作
// 定义服务项目数据模型 @Class class ServiceItem { @Field() id: string = ''; // 服务ID @Field() name: string = ''; // 服务名称 @Field() category: string = ''; // 服务分类 @Field() price: number = 0; // 服务价格 @Field() description: string = ''; // 服务描述 @Field() createTime: number = 0; // 创建时间戳 constructor(partial?: Partial<ServiceItem>) { if (partial) { Object.assign(this, partial); } } } // 服务管理类 class ServiceManager { private cloudDB: any; constructor() { this.cloudDB = CloudDBHelper.getInstance().getCloudDB(); } // 添加服务 async addService(item: ServiceItem): Promise<boolean> { try { item.id = this.generateId(); item.createTime = new Date().getTime(); await this.cloudDB.insert(ServiceItem, item); return true; } catch (error) { console.error('添加服务失败:', error); return false; } } // 查询所有服务 async getAllServices(): Promise<ServiceItem[]> { try { const query = this.cloudDB.createQuery(ServiceItem); const result = await this.cloudDB.executeQuery(query); return result.getSnapshotObjects(); } catch (error) { console.error('查询服务失败:', error); return []; } } // 按分类查询服务 async getServicesByCategory(category: string): Promise<ServiceItem[]> { try { const query = this.cloudDB.createQuery(ServiceItem) .equalTo('category', category) .orderByDesc('createTime'); const result = await this.cloudDB.executeQuery(query); return result.getSnapshotObjects(); } catch (error) { console.error('按分类查询失败:', error); return []; } } // 生成唯一ID private generateId(): string { return 'srv_' + Math.random().toString(36).substr(2, 9); } }
3.3 实现服务列表界面
// 服务列表页面组件 @Component struct ServiceListPage { private serviceManager: ServiceManager = new ServiceManager(); @State serviceItems: ServiceItem[] = []; @State selectedCategory: string = 'all'; @State categories: string[] = ['all', 'cleaning', 'repair', 'delivery']; aboutToAppear() { this.loadServices(); } async loadServices() { if (this.selectedCategory === 'all') { this.serviceItems = await this.serviceManager.getAllServices(); } else { this.serviceItems = await this.serviceManager.getServicesByCategory(this.selectedCategory); } } build() { Column() { // 分类筛选 Scroll(.horizontal) { Row() { ForEach(this.categories, (category: string) => { Button(category) .margin(5) .stateEffect(this.selectedCategory === category) .onClick(() => { this.selectedCategory = category; this.loadServices(); }) }) } } .height(50) // 服务列表 List({ space: 10 }) { ForEach(this.serviceItems, (item: ServiceItem) => { ListItem() { ServiceItemCard({ item: item }) } }, (item: ServiceItem) => item.id) } .layoutWeight(1) .width('100%') } .width('100%') .height('100%') } } // 服务项卡片组件 @Component struct ServiceItemCard { @Prop item: ServiceItem; build() { Column() { Text(this.item.name) .fontSize(18) .fontWeight(FontWeight.Bold) Text(this.item.description) .fontSize(14) .margin({ top: 5 }) .maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis }) Row() { Text(`¥${this.item.price}`) .fontSize(16) .fontColor(Color.Red) Blank() Text(this.item.category) .fontSize(12) .fontColor(Color.Gray) } .width('100%') .margin({ top: 10 }) } .padding(10) .width('100%') .backgroundColor(Color.White) .borderRadius(8) .shadow({ radius: 4, color: '#999', offsetX: 1, offsetY: 1 }) } }
四、云函数与支付集成
生活服务类应用通常需要处理订单和支付流程。AppGallery Connect提供了云函数和支付服务来简化这些复杂流程。
4.1 创建订单云函数
// 前端调用创建订单 async function createOrder(serviceId: string, userId: string): Promise<any> { try { const agc = agconnect.instance(); const functionCall = agc.function().wrap('createOrder-$latest'); const result = await functionCall.call({ serviceId: serviceId, userId: userId }); return result.getValue(); } catch (error) { console.error('创建订单失败:', error); throw error; } } // 云函数示例代码(后端) /* exports.handler = async (event, context) => { const { serviceId, userId } = event; // 1. 验证服务是否存在 const service = await db.collection('services').doc(serviceId).get(); if (!service.exists) { throw new Error('服务不存在'); } // 2. 创建订单记录 const order = { orderId: generateOrderId(), serviceId, userId, amount: service.data().price, status: 'pending', createTime: new Date().getTime() }; await db.collection('orders').add(order); // 3. 返回支付参数 return { orderId: order.orderId, amount: order.amount, serviceName: service.data().name }; }; */
4.2 集成支付功能
import iap from '@hw-iap/api'; // 支付功能封装 class PaymentService { // 发起支付 static async pay(orderInfo: any): Promise<boolean> { try { const productInfo = { priceType: iap.PriceType.IN_APP_CONSUMABLE, // 消耗型商品 productId: orderInfo.orderId, productName: orderInfo.serviceName, amount: orderInfo.amount, currency: 'CNY' }; const result = await iap.createPurchaseIntent(productInfo); if (result.returnCode === 0) { // 支付成功,更新订单状态 await this.confirmOrder(orderInfo.orderId); return true; } else { throw new Error(`支付失败: ${result.errMsg}`); } } catch (error) { console.error('支付过程出错:', error); throw error; } } // 确认订单 private static async confirmOrder(orderId: string) { const agc = agconnect.instance(); const functionCall = agc.function().wrap('confirmOrder-$latest'); await functionCall.call({ orderId }); } } // 在订单页面使用 @Component struct OrderPage { @State orderInfo: any = null; @State isLoading: boolean = true; aboutToAppear() { this.loadOrder(); } async loadOrder() { try { const serviceId = router.getParams()?.serviceId; const userId = await this.getCurrentUserId(); this.orderInfo = await createOrder(serviceId, userId); } catch (error) { prompt.showToast({ message: '获取订单失败: ' + error.message }); } finally { this.isLoading = false; } } async handlePay() { try { this.isLoading = true; await PaymentService.pay(this.orderInfo); prompt.showToast({ message: '支付成功' }); router.back(); } catch (error) { prompt.showToast({ message: '支付失败: ' + error.message }); } finally { this.isLoading = false; } } build() { Column() { if (this.isLoading) { LoadingProgress() .height(50) .width(50) } else if (this.orderInfo) { Text('订单详情') .fontSize(20) .margin({ bottom: 20 }) Text(`服务: ${this.orderInfo.serviceName}`) .fontSize(16) .margin({ bottom: 10 }) Text(`金额: ¥${this.orderInfo.amount}`) .fontSize(18) .fontColor(Color.Red) .margin({ bottom: 20 }) Button('立即支付') .width('80%') .height(50) .onClick(() => this.handlePay()) } } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) } }
五、消息推送与通知
生活服务类应用需要及时通知用户订单状态变化。AppGallery Connect提供了推送服务,支持多种消息类型。
5.1 集成推送服务
import push from '@hw-push/api'; // 推送服务初始化 async function initPushService() { try { await push.init(); console.log('推送服务初始化成功'); // 获取推送token const token = await push.getToken(); console.log('推送Token:', token); // 监听消息 push.onMessageReceived((message) => { console.log('收到推送消息:', message); this.handlePushMessage(message); }); } catch (error) { console.error('推送服务初始化失败:', error); } } // 处理推送消息 function handlePushMessage(message: any) { const notification = { content: { contentType: push.ContentType.NOTIFICATION, normal: { title: message.notification?.title || '新消息', body: message.notification?.body || '您有一条新消息', clickAction: { type: push.ClickAction.TYPE_APP, intent: message.intent } } } }; push.createNotification(notification) .then(() => console.log('通知创建成功')) .catch((error) => console.error('通知创建失败:', error)); } // 在Ability的onCreate中调用 initPushService();
5.2 发送订单状态通知
// 后端云函数示例代码 /* exports.sendOrderNotification = async (orderId, status) => { const order = await db.collection('orders').doc(orderId).get(); if (!order.exists) return; const user = await db.collection('users').doc(order.data().userId).get(); const token = user.data().pushToken; const message = { notification: { title: '订单状态更新', body: `您的订单${orderId}状态已变更为${status}` }, data: { orderId: orderId, type: 'order_update' }, token: token }; await admin.messaging().send(message); }; */
六、应用发布与数据分析
完成开发后,可以通过AppGallery Connect发布应用并监控应用表现。
6.1 应用发布准备
- 在AppGallery Connect中创建应用
- 配置应用信息、图标、截图等
- 设置定价和分发区域
- 生成签名证书
// 在config.json中添加发布配置 { "app": { // ...其他配置 "distributionFilter": { "countries": ["CN", "US", "UK"], // 分发国家 "apiCompatible": 8, "apiTarget": 9 } } }
6.2 集成数据分析
AppGallery Connect提供了应用数据分析服务,帮助开发者了解用户行为。
import analytics from '@hw-analytics/api'; // 记录自定义事件 function logEvent(eventName: string, params?: object) { analytics.instance().logEvent(eventName, params); } // 示例:记录服务浏览事件 @Component struct ServiceDetailPage { @Prop serviceId: string; aboutToAppear() { logEvent('view_service', { service_id: this.serviceId, timestamp: new Date().getTime() }); } } // 设置用户属性 async function setUserProperties(userId: string) { await analytics.instance().setUserId(userId); await analytics.instance().setUserProfile({ user_level: 'vip', // 用户等级 last_login: new Date().toISOString() // 最后登录时间 }); }
七、总结与最佳实践
通过本教程,我们完成了一个基于HarmonyOS Next的生活服务类应用核心功能开发,涵盖了:
- 用户认证系统实现
- 云数据库集成与服务管理
- 订单与支付流程处理
- 消息推送与通知系统
- 应用发布与数据分析
最佳实践建议:
- 模块化设计:将AGC相关功能封装成独立模块,便于维护和复用
- 错误处理:对所有云服务调用做好错误处理和用户提示
- 数据安全:敏感操作应在云函数中实现,而非前端直接处理
- 性能优化:合理使用本地缓存减少云数据库查询
- 用户体验:关键操作提供加载状态反馈
通过AppGallery Connect的丰富服务,开发者可以快速构建功能完善的生活服务类应用,而将更多精力集中在业务逻辑和用户体验优化上。