HarmonyOS 6.1 开源生态实战:从“自用”到“贡献”的三方库开发

HarmonyOS 6.1 开源生态实战:从“自用”到“贡献”的三方库开发
系列生态共建篇·第53篇。跨端篇后有开源爱好者问“我在电商Demo里写了很多通用组件如SKU选择器、地址联动能不能抽离出来给社区用怎么做成标准的OpenHarmony三方库” 这正是开源生态的魅力。今天我们将电商Demo中的通用支付模块和SKU选择组件抽离、封装发布为一个标准的OpenHarmony三方库HAR包并上架到OHPMOpenHarmony Package Manager仓库。我们将覆盖库工程搭建、API设计、文档撰写、单元测试、CI发布全流程。全程基于API23含官方文档未涉及的“多目标构建”和“语义化版本控制”技巧。一、前言为什么“造轮子”也要讲姿势很多开发者写过“工具类”但那只是“代码片段”。真正的三方库需要具备独立性不依赖具体业务如电商Demo可独立编译和运行。通用性API设计抽象能适应多种场景如支付模块支持支付宝、微信、银联。稳定性经过充分测试版本迭代不破坏兼容性。易用性文档齐全示例清晰一键集成。OHPM是OpenHarmony的官方包管理器类似于npmNode.js或MavenAndroid。今天我们将把电商Demo中的“支付功能”提炼成一个名为harmony/payment-kit的高质量三方库并贡献给开源社区。二、核心概念辨析代码片段 vs 三方库维度代码片段 (Utils/Snippets)三方库 (Library/HAR)复用性​低需复制粘贴修改高一键集成 (ohpm install)维护性​差分散在各项目中好集中维护版本化管理测试​无或简陋完善包含单元测试、集成测试文档​注释为主独立文档、API参考、示例工程依赖​隐式依赖项目环境显式声明依赖自动解决发布​口头分享OHPM中央仓库可检索三、代码实现从“业务代码”到“开源库”3.1 创建HAR库工程步骤1新建Library Module在DevEco Studio中File-New-Module-Static Library (HAR)。命名为payment-kit。步骤2工程结构规划payment-kit/ ├── src/main/ets/ │ ├── components/ # UI组件如支付密码弹窗 │ │ └── PayPasswordDialog.ets │ ├── core/ # 核心逻辑 │ │ ├── PaymentManager.ets │ │ └── ChannelAdapter.ets │ ├── models/ # 数据模型 │ │ └── PaymentInfo.ets │ ├── utils/ # 工具类 │ │ └── SignUtil.ets │ ├── index.ets # 对外暴露的API入口关键 │ └── resources/ # 资源文件 ├── src/test/ets/ # 单元测试 ├── oh-package.json5 # 库配置文件类似package.json └── README.md # 项目说明文档3.2 抽离核心逻辑支付管理器创建src/main/ets/core/PaymentManager.ets// 定义支付渠道枚举 export enum PayChannel { ALIPAY alipay, WECHAT wechat, UNIONPAY unionpay, HUAWEI_IAP huawei_iap // 华为IAP } // 定义支付结果回调 export interface PaymentCallback { onSuccess?(result: PaymentResult): void onFailed?(code: number, msg: string): void onCancel?(): void } // 支付管理器单例 export class PaymentManager { private static instance: PaymentManager private channels: MapPayChannel, ChannelAdapter new Map() private currentCallback: PaymentCallback | null null static getInstance(): PaymentManager { if (!PaymentManager.instance) { PaymentManager.instance new PaymentManager() } return PaymentManager.instance } /** * 注册支付渠道适配器 */ registerChannel(channel: PayChannel, adapter: ChannelAdapter): void { this.channels.set(channel, adapter) console.log(支付渠道注册成功: ${channel}) } /** * 发起支付 */ pay(info: PaymentInfo, callback: PaymentCallback): void { this.currentCallback callback const adapter this.channels.get(info.channel) if (!adapter) { callback.onFailed?.(-1, 支付渠道 ${info.channel} 未注册) return } // 参数校验 if (!this.validateParams(info)) { callback.onFailed?.(-2, 支付参数校验失败) return } // 调用具体渠道的支付逻辑 adapter.pay(info, { onSuccess: (result) { this.handleSuccess(result) }, onFailed: (code, msg) { this.handleFailed(code, msg) }, onCancel: () { this.handleCancel() } }) } /** * 参数校验 */ private validateParams(info: PaymentInfo): boolean { if (!info.orderId || !info.amount || info.amount 0) { return false } return true } private handleSuccess(result: PaymentResult): void { console.log(支付成功:, result) this.currentCallback?.onSuccess?.(result) } private handleFailed(code: number, msg: string): void { console.error(支付失败:, code, msg) this.currentCallback?.onFailed?.(code, msg) } private handleCancel(): void { console.log(支付取消) this.currentCallback?.onCancel?.() } } // 渠道适配器接口策略模式 export interface ChannelAdapter { pay(info: PaymentInfo, callback: PaymentCallback): void }3.3 实现具体渠道华为IAP适配器创建src/main/ets/core/adapters/HuaweiIAPAdapter.etsimport { iap } from kit.IAPKit import { PaymentCallback, ChannelAdapter, PaymentInfo, PaymentResult } from ../PaymentManager export class HuaweiIAPAdapter implements ChannelAdapter { async pay(info: PaymentInfo, callback: PaymentCallback): Promisevoid { try { // 1. 创建订单 const order await iap.createPurchaseOrder({ productId: info.productId!, quantity: info.quantity || 1 }) // 2. 发起支付 const payResult await iap.pay(order) // 3. 处理支付结果 if (payResult.returnCode 0) { const result: PaymentResult { orderId: info.orderId, transactionId: payResult.inAppPurchaseData?.inAppPurchaseData?.orderId || , channel: huawei_iap, rawData: JSON.stringify(payResult) } callback.onSuccess?.(result) } else { callback.onFailed?.(payResult.returnCode, payResult.errMsg || 支付失败) } } catch (err) { console.error(华为IAP支付异常:, err) callback.onFailed?.(-3, 支付过程发生异常) } } }3.4 定义对外API入口文件关键src/main/ets/index.ets是库的“脸面”必须清晰、简洁。// 核心类 export { PaymentManager } from ./core/PaymentManager export { HuaweiIAPAdapter } from ./core/adapters/HuaweiIAPAdapter // 导出枚举和接口方便使用者 export { PayChannel } from ./core/PaymentManager export type { PaymentCallback, PaymentResult } from ./core/PaymentManager export type { PaymentInfo } from ./models/PaymentInfo // 提供便捷的初始化函数 import { PaymentManager } from ./core/PaymentManager import { HuaweiIAPAdapter } from ./core/adapters/HuaweiIAPAdapter export function initPaymentKit(): PaymentManager { const manager PaymentManager.getInstance() // 默认注册华为IAP渠道 manager.registerChannel(PayChannel.HUAWEI_IAP, new HuaweiIAPAdapter()) return manager }3.5 配置库信息oh-package.json5{ name: harmony/payment-kit, version: 1.0.0, description: A universal payment kit for HarmonyOS, supporting multiple channels., main: src/main/ets/index.ets, author: listening777, license: Apache-2.0, keywords: [harmonyos, payment, iap, alipay, wechat], repository: { type: git, url: https://gitee.com/your_repo/payment-kit.git }, dependencies: { ohos/iap: ^1.0.0 // 声明对IAP Kit的依赖 }, devDependencies: { ohos/hypium: ^1.0.0 // 单元测试框架 }, ohos: { minAPIVersion: 11, // 支持的最低API版本 targetAPIVersion: 12 // 目标API版本 } }3.6 编写README.md门面担当# harmony/payment-kit 一个用于HarmonyOS的通用支付聚合库旨在简化多支付渠道的集成流程。 ## 特性 - **一键集成**一行代码初始化支持链式调用。 - **可扩展**通过适配器模式轻松接入新支付渠道。 - ️ **类型安全**完整的TypeScript类型定义。 - **跨端支持**基于ArkUI-X支持HarmonyOS、Android、iOS。 ## 安装bashohpm install harmony/payment-kit## 快速开始typescriptimport { initPaymentKit, PayChannel, PaymentInfo } from harmony/payment-kit// 1. 初始化const paymentKit initPaymentKit()// 2. 构建支付信息const info: PaymentInfo {orderId: ORDER_123456,amount: 99.8,currency: CNY,channel: PayChannel.HUAWEI_IAP,productId: product_001, // 华为IAP商品IDsubject: 测试商品}// 3. 发起支付paymentKit.pay(info, {onSuccess: (result) {console.log(支付成功:, result.transactionId)},onFailed: (code, msg) {console.error(支付失败:, code, msg)},onCancel: () {console.log(用户取消支付)}})## API文档 ### PaymentManager - registerChannel(channel: PayChannel, adapter: ChannelAdapter): 注册支付渠道。 - pay(info: PaymentInfo, callback: PaymentCallback): 发起支付。 ### PaymentInfo | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | orderId | string | 是 | 商户订单号 | | amount | number | 是 | 支付金额 | | channel | PayChannel | 是 | 支付渠道 | | productId | string | 否 | 商品IDIAP需要 | ## 贡献指南 欢迎PR请确保 1. 代码通过ohpm run lint检查。 2. 新增功能包含单元测试。 3. 更新README文档。 ## 许可证 Apache License 2.0四、踩坑记录官方文档没写的开源细节API设计的“洁癖”三方库的API一旦发布修改成本极高。原则宁缺毋滥。不要在1.0.0版本暴露过多的内部方法。使用export严格控制对外API内部类使用internal或文件夹隔离。资源命名的“隔离”如果库中使用了图片、字符串等资源务必添加前缀如pk_防止与主工程资源冲突。例如$r(app.media.pk_pay_icon)。多目标构建Multi-target Build如果库需要支持HarmonyOS和OpenHarmony社区版需要注意API差异。使用条件编译// 条件编译仅HarmonyOS支持 // ts-ignore if (canIUse(SystemCapability.ArkUI.ArkUI.Full)) { // HarmonyOS特有逻辑 }版本号的“敬畏”严格遵守语义化版本SemVer主版本.次版本.修订号。主版本不兼容的API修改如重构了支付流程。次版本向后兼容的功能新增如增加了新的支付渠道。修订号向后兼容的问题修正如修复了某个NullPointerException。OHPM发布的“门槛”首次发布需要实名认证个人或企业。包名name必须全局唯一且不能以ohos/开头那是官方包。建议使用组织名/包名的格式。