基于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的丰富服务,开发者可以快速构建功能完善的生活服务类应用,而将更多精力集中在业务逻辑和用户体验优化上。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。