下面我将介绍如何在HarmonyOS 5中使用ArkUI-X框架实现一个生活缴费小程序,包含水电煤缴费、话费充值、缴费记录查询等功能。

项目结构

/LifePaymentApp
  ├── entry
  │   └── src
  │       ├── main
  │       │   ├── ets
  │       │   │   ├── components
  │       │   │   │   ├── BillCard.ets       // 账单卡片组件
  │       │   │   │   ├── PaymentForm.ets    // 支付表单组件
  │       │   │   │   ├── RecordItem.ets     // 记录项组件
  │       │   │   ├── pages
  │       │   │   │   ├── HomePage.ets       // 首页
  │       │   │   │   ├── PaymentPage.ets    // 缴费页面
  │       │   │   │   ├── RecordsPage.ets    // 缴费记录页面
  │       │   │   │   ├── ProfilePage.ets    // 个人中心
  │       │   │   ├── model
  │       │   │   │   ├── Bill.ets           // 账单数据模型
  │       │   │   │   ├── Payment.ets         // 支付数据模型
  │       │   │   │   ├── User.ets            // 用户数据模型
  │       │   ├── resources
  │       │   │   ├── base
  │       │   │   │   ├── element             // 图标等资源

实现步骤

1. 创建数据模型

Bill.ets (账单模型)
export class Bill {
  id: string;
  type: 'electric' | 'water' | 'gas' | 'phone'; // 账单类型
  account: string;      // 账户号码
  amount: number;       // 账单金额
  dueDate: string;      // 缴费截止日期
  paid: boolean = false; // 是否已支付
  
  constructor(id: string, type: string, account: string, amount: number, dueDate: string) {
    this.id = id;
    this.type = type;
    this.account = account;
    this.amount = amount;
    this.dueDate = dueDate;
  }
}
Payment.ets (支付记录模型)
export class Payment {
  id: string;
  billId: string;      // 关联的账单ID
  amount: number;      // 支付金额
  paymentTime: string; // 支付时间
  method: 'alipay' | 'wechat' | 'bank'; // 支付方式
  
  constructor(id: string, billId: string, amount: number, paymentTime: string, method: string) {
    this.id = id;
    this.billId = billId;
    this.amount = amount;
    this.paymentTime = paymentTime;
    this.method = method;
  }
}
User.ets (用户模型)
export class User {
  userId: string;
  name: string;
  phone: string;
  savedAccounts: SavedAccount[] = []; // 保存的缴费账户
  
  constructor(userId: string, name: string, phone: string) {
    this.userId = userId;
    this.name = name;
    this.phone = phone;
  }
}

export class SavedAccount {
  type: 'electric' | 'water' | 'gas' | 'phone';
  accountNumber: string;
  accountName: string;
  
  constructor(type: string, accountNumber: string, accountName: string) {
    this.type = type;
    this.accountNumber = accountNumber;
    this.accountName = accountName;
  }
}

2. 创建组件

BillCard.ets (账单卡片组件)
@Component
export struct BillCard {
  @Prop bill: Bill;
  @Prop onPay: () => void;
  
  build() {
    Column() {
      Row() {
        // 根据账单类型显示不同图标
        Image(this.getBillIcon())
          .width(30)
          .height(30)
          .margin({ right: 10 })
        
        Column() {
          Text(this.getBillTypeName())
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
          Text(`账户: ${this.bill.account}`)
            .fontSize(12)
        }
        .layoutWeight(1)
        
        Text(`¥${this.bill.amount.toFixed(2)}`)
          .fontSize(18)
          .fontColor(this.bill.paid ? Color.Green : Color.Red)
      }
      
      Row({ space: 20 }) {
        Text(`截止日期: ${this.bill.dueDate}`)
          .fontSize(12)
        
        if (!this.bill.paid) {
          Button('立即缴费', { type: ButtonType.Capsule })
            .width(100)
            .height(30)
            .fontSize(12)
            .onClick(() => this.onPay())
        } else {
          Text('已支付', { style: { color: Color.Green } })
            .fontSize(12)
        }
      }
      .margin({ top: 10 })
      .width('100%')
      .justifyContent(FlexAlign.SpaceBetween)
    }
    .padding(15)
    .borderRadius(10)
    .backgroundColor(Color.White)
    .margin({ bottom: 10 })
    .shadow({ radius: 2, color: '#f0f0f0', offsetX: 1, offsetY: 1 })
  }
  
  private getBillIcon(): Resource {
    switch(this.bill.type) {
      case 'electric': return $r('app.media.electric');
      case 'water': return $r('app.media.water');
      case 'gas': return $r('app.media.gas');
      case 'phone': return $r('app.media.phone');
      default: return $r('app.media.other');
    }
  }
  
  private getBillTypeName(): string {
    switch(this.bill.type) {
      case 'electric': return '电费';
      case 'water': return '水费';
      case 'gas': return '燃气费';
      case 'phone': return '话费';
      default: return '其他';
    }
  }
}
PaymentForm.ets (支付表单组件)
@Component
export struct PaymentForm {
  @Link bill: Bill;
  @State paymentMethod: 'alipay' | 'wechat' | 'bank' = 'alipay';
  @State agreeTerms: boolean = false;
  
  build() {
    Column({ space: 15 }) {
      // 账单信息
      Row() {
        Text('缴费项目:')
          .fontSize(14)
        Text(this.getBillTypeName())
          .fontSize(14)
          .layoutWeight(1)
          .textAlign(TextAlign.End)
      }
      
      Row() {
        Text('账户号码:')
          .fontSize(14)
        Text(this.bill.account)
          .fontSize(14)
          .layoutWeight(1)
          .textAlign(TextAlign.End)
      }
      
      Row() {
        Text('缴费金额:')
          .fontSize(14)
        Text(`¥${this.bill.amount.toFixed(2)}`)
          .fontSize(16)
          .fontColor(Color.Red)
          .layoutWeight(1)
          .textAlign(TextAlign.End)
      }
      
      Divider()
      
      // 支付方式选择
      Text('选择支付方式')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
      
      RadioGroup({ group: 'paymentMethod' }) {
        Radio({ value: 'alipay' })
          .checked(this.paymentMethod === 'alipay')
        Text('支付宝')
          .fontSize(14)
          .margin({ left: 10 })
        
        Radio({ value: 'wechat' })
          .checked(this.paymentMethod === 'wechat')
          .margin({ left: 20 })
        Text('微信支付')
          .fontSize(14)
          .margin({ left: 10 })
        
        Radio({ value: 'bank' })
          .checked(this.paymentMethod === 'bank')
          .margin({ left: 20 })
        Text('银行卡')
          .fontSize(14)
          .margin({ left: 10 })
      }
      .onChange((value: string) => {
        this.paymentMethod = value as any;
      })
      .margin({ top: 5, bottom: 10 })
      
      // 协议勾选
      Row() {
        Checkbox()
          .select(this.agreeTerms)
          .onChange((checked: boolean) => {
            this.agreeTerms = checked;
          })
        Text('我已阅读并同意《缴费服务协议》')
          .fontSize(12)
          .textDecoration(TextDecoration.Underline)
          .onClick(() => {
            // 打开协议页面
          })
      }
      
      // 支付按钮
      Button('确认支付', { type: ButtonType.Capsule })
        .width('100%')
        .height(40)
        .fontSize(16)
        .enabled(this.agreeTerms)
        .onClick(() => {
          // 触发支付逻辑
        })
    }
    .padding(20)
    .backgroundColor(Color.White)
    .borderRadius(10)
  }
  
  private getBillTypeName(): string {
    switch(this.bill.type) {
      case 'electric': return '电费';
      case 'water': return '水费';
      case 'gas': return '燃气费';
      case 'phone': return '话费';
      default: return '其他';
    }
  }
}

3. 创建页面

HomePage.ets (首页)
@Entry
@Component
struct HomePage {
  @State user: User = new User('123', '张三', '13800138000');
  @State bills: Bill[] = [
    new Bill('1', 'electric', '123456789', 125.50, '2023-12-25'),
    new Bill('2', 'water', '987654321', 68.00, '2023-12-20'),
    new Bill('3', 'gas', '456123789', 42.30, '2023-12-15')
  ];
  
  build() {
    Column() {
      // 顶部用户信息
      Row() {
        Image($r('app.media.avatar'))
          .width(50)
          .height(50)
          .borderRadius(25)
          .margin({ right: 10 })
        
        Column() {
          Text(this.user.name)
            .fontSize(18)
            .fontWeight(FontWeight.Bold)
          Text(`手机号: ${this.user.phone}`)
            .fontSize(12)
            .fontColor('#999')
        }
      }
      .padding(15)
      .width('100%')
      .backgroundColor('#f8f8f8')
      
      // 快捷入口
      Grid() {
        GridItem() {
          Column() {
            Image($r('app.media.electric'))
              .width(40)
              .height(40)
            Text('电费')
              .fontSize(12)
              .margin({ top: 5 })
          }
          .onClick(() => {
            // 跳转电费页面
          })
        }
        
        // 其他入口(水费、燃气费、话费等)...
      }
      .columnsTemplate('1fr 1fr 1fr 1fr')
      .rowsGap(15)
      .columnsGap(15)
      .margin(15)
      
      // 待缴费账单
      Text('待缴费账单')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .margin({ left: 15, top: 10, bottom: 5 })
      
      Scroll() {
        Column() {
          ForEach(this.bills.filter(bill => !bill.paid), (bill: Bill) => {
            BillCard({
              bill: bill,
              onPay: () => {
                // 跳转支付页面
              }
            })
          })
        }
        .padding(15)
      }
      .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
  }
}
PaymentPage.ets (缴费页面)
@Component
export struct PaymentPage {
  @Link bill: Bill;
  @State paymentSuccess: boolean = false;
  
  build() {
    Column() {
      if (!this.paymentSuccess) {
        PaymentForm({ bill: $bill })
      } else {
        this.buildSuccessView()
      }
    }
    .padding(15)
    .width('100%')
    .height('100%')
    .backgroundColor('#f8f8f8')
  }
  
  @Builder buildSuccessView() {
    Column({ space: 20 }) {
      Image($r('app.media.success'))
        .width(80)
        .height(80)
      
      Text('支付成功')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      
      Text(`缴费金额: ¥${this.bill.amount.toFixed(2)}`)
        .fontSize(16)
      
      Text(`缴费账户: ${this.bill.account}`)
        .fontSize(14)
      
      Button('返回首页', { type: ButtonType.Capsule })
        .width(200)
        .height(40)
        .margin({ top: 30 })
        .onClick(() => {
          // 返回首页
        })
    }
    .width('100%')
    .padding(30)
    .backgroundColor(Color.White)
    .borderRadius(10)
  }
}

4. 添加底部导航

@Entry
@Component
struct MainPage {
  @State currentTab: number = 0;
  
  build() {
    Column() {
      // 内容区域
      TabContent({ currentTab: this.currentTab }) {
        HomePage()
          .tabBar('首页')
        
        RecordsPage()
          .tabBar('记录')
        
        ProfilePage()
          .tabBar('我的')
      }
      .layoutWeight(1)
      
      // 底部导航栏
      TabBar({ currentTab: this.currentTab }) {
        TabBarItem({
          icon: $r('app.media.home'),
          text: '首页',
          index: 0
        })
        
        TabBarItem({
          icon: $r('app.media.records'),
          text: '记录',
          index: 1
        })
        
        TabBarItem({
          icon: $r('app.media.profile'),
          text: '我的',
          index: 2
        })
      }
      .onChange((index: number) => {
        this.currentTab = index;
      })
      .barMode(BarMode.Fixed)
      .barWidth('100%')
      .barHeight(56)
    }
    .width('100%')
    .height('100%')
  }
}

功能扩展建议

  1. ​账单自动查询​​:对接公共服务API实现账单自动查询
  2. ​自动缴费​​:设置自动缴费规则,到期自动扣款
  3. ​缴费提醒​​:设置缴费提醒通知
  4. ​多账户管理​​:管理多个家庭成员的缴费账户
  5. ​缴费统计​​:统计月度、年度缴费情况
  6. ​电子发票​​:生成和下载缴费电子发票
  7. ​优惠活动​​:集成缴费优惠活动信息

注意事项

  1. 支付功能需要对接真实的支付接口
  2. 用户敏感信息需要加密存储
  3. 考虑不同设备的屏幕适配
  4. 实现网络状态检测和离线模式
  5. 添加加载状态和错误处理
  6. 遵循鸿蒙应用的设计规范

这个生活缴费小程序展示了ArkUI-X在实用型应用开发中的能力,通过组件化设计和状态管理,实现了清晰的界面和流畅的用户体验。你可以根据实际需求进一步扩展功能和完善细节。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐