功能説明
這是一個基於HarmonyOS ArkTS開發的簡易個人記賬本應用,主要功能包括:

核心功能
添加記賬記錄 - 記錄收入/支出,包含金額、類別、日期、備註
查看記賬列表 - 以卡片形式展示所有記賬記錄
編輯記錄 - 修改已保存的記賬信息
刪除記錄 - 刪除不需要的記賬記錄
收支統計 - 實時統計總收入、總支出和結餘
分類篩選 - 按類別篩選查看記錄
完整代碼

`// 簡易個人記賬本

// 文件名:PersonalAccountBook.etsimport promptAction from '@ohos.promptAction';
// 記賬記錄數據模型

class AccountRecord {

id: number = 0;

type: string = '支出'; // 收入/支出

amount: number = 0;

category: string = '餐飲';

date: string = '';

note: string = '';constructor(id: number, type: string = '支出', amount: number = 0,

category: string = '餐飲', date: string = '', note: string = '') {

this.id = id;

this.type = type;

this.amount = amount;

this.category = category;

this.date = date;

this.note = note;

}

}@Entry

@Component

struct PersonalAccountBook {

// 記賬記錄列表

@State accountList: AccountRecord[] = [];// 收支統計

@State totalIncome: number = 0;

@State totalExpense: number = 0;

@State balance: number = 0;// 編輯相關狀態

@State currentRecord: AccountRecord = new AccountRecord(0);

@State showEditDialog: boolean = false;

@State isEditing: boolean = false;

@State selectedType: string = '支出';// 類別選項

@State expenseCategories: string[] = ['餐飲', '交通', '購物', '娛樂', '醫療', '其他'];

@State incomeCategories: string[] = ['工資', '獎金', '投資', '兼職', '其他'];// 當前篩選類別

@State selectedCategory: string = '全部';// 組件生命週期

aboutToAppear() {

this.initSampleData();

this.calculateStatistics();

}// 初始化示例數據

initSampleData() {

this.accountList = [

new AccountRecord(1, '支出', 35.5, '餐飲', '2024-01-15', '午餐'),

new AccountRecord(2, '收入', 8500, '工資', '2024-01-10', '1月份工資'),

new AccountRecord(3, '支出', 128, '購物', '2024-01-12', '購買書籍'),

new AccountRecord(4, '支出', 15, '交通', '2024-01-14', '地鐵費'),

new AccountRecord(5, '收入', 500, '兼職', '2024-01-08', '兼職收入')

];

}// 構建主界面

build() {

Column({ space: 0 }) {

// 頂部標題欄

this.buildHeader()// 收支統計卡片
  this.buildStatisticsCard()
  
  // 類別篩選
  this.buildCategoryFilter()
  
  // 記賬列表
  this.buildRecordList()
}
.width('100%')
.height('100%')
.backgroundColor('#F8F9FA')}
// 頂部標題欄

@Builder

buildHeader() {

Row() {

Text('個人記賬本')

.fontSize(22)

.fontWeight(FontWeight.Bold)

.fontColor('#FFFFFF')

.layoutWeight(1)Button('記賬')
    .width(70)
    .height(35)
    .fontSize(14)
    .backgroundColor('#FFFFFF')
    .fontColor('#007DFF')
    .onClick(() => {
      this.addNewRecord();
    })
}
.width('100%')
.padding({ left: 16, right: 16, top: 12, bottom: 12 })
.backgroundColor('#007DFF')}
// 收支統計卡片

@Builder

buildStatisticsCard() {

Column({ space: 8 }) {

// 總收入

Row() {

Text('總收入')

.fontSize(16)

.fontColor('#666666')

.layoutWeight(1)

Text('¥' + this.totalIncome.toFixed(2))

.fontSize(20)

.fontWeight(FontWeight.Bold)

.fontColor('#4CAF50')

}

.width('100%')// 總支出
  Row() {
    Text('總支出')
      .fontSize(16)
      .fontColor('#666666')
      .layoutWeight(1)
    Text('¥' + this.totalExpense.toFixed(2))
      .fontSize(20)
      .fontWeight(FontWeight.Bold)
      .fontColor('#FF5722')
  }
  .width('100%')
  
  // 結餘
  Row() {
    Text('結餘')
      .fontSize(16)
      .fontColor('#666666')
      .layoutWeight(1)
    Text('¥' + this.balance.toFixed(2))
      .fontSize(22)
      .fontWeight(FontWeight.Bold)
      .fontColor('#007DFF')
  }
  .width('100%')
}
.width('90%')
.padding(16)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.margin({ top: 16, bottom: 16 })
.shadow({ radius: 4, color: '#E0E0E0', offsetX: 1, offsetY: 2 })}
// 類別篩選

@Builder

buildCategoryFilter() {

Scroll(.horizontal) {

Row({ space: 8 }) {

// "全部"選項

Text('全部')

.fontSize(14)

.padding({ left: 12, right: 12, top: 6, bottom: 6 })

.backgroundColor(this.selectedCategory === '全部' ? '#007DFF' : '#FFFFFF')

.fontColor(this.selectedCategory === '全部' ? '#FFFFFF' : '#666666')

.borderRadius(16)

.onClick(() => {

this.selectedCategory = '全部';

})// 支出類別
    ForEach(this.expenseCategories, (category: string) => {
      Text(category)
        .fontSize(14)
        .padding({ left: 12, right: 12, top: 6, bottom: 6 })
        .backgroundColor(this.selectedCategory === category ? '#FF5722' : '#FFFFFF')
        .fontColor(this.selectedCategory === category ? '#FFFFFF' : '#666666')
        .borderRadius(16)
        .onClick(() => {
          this.selectedCategory = category;
        })
    })
    
    // 收入類別
    ForEach(this.incomeCategories, (category: string) => {
      Text(category)
        .fontSize(14)
        .padding({ left: 12, right: 12, top: 6, bottom: 6 })
        .backgroundColor(this.selectedCategory === category ? '#4CAF50' : '#FFFFFF')
        .fontColor(this.selectedCategory === category ? '#FFFFFF' : '#666666')
        .borderRadius(16)
        .onClick(() => {
          this.selectedCategory = category;
        })
    })
  }
  .padding({ left: 16, right: 16 })
}
.width('100%')
.margin({ bottom: 12 })}
// 記賬列表

@Builder

buildRecordList() {

List({ space: 8 }) {

ForEach(this.getFilteredRecords(), (record: AccountRecord) => {

ListItem() {

this.buildRecordItem(record)

}

})

}

.width('100%')

.layoutWeight(1)

.padding({ left: 16, right: 16 })// 編輯對話框
if (this.showEditDialog) {
  this.buildEditDialog()
}}
// 記賬列表項

@Builder

buildRecordItem(record: AccountRecord) {

Column({ space: 6 }) {

// 第一行:類別和金額

Row() {

// 類別標籤

Text(record.category)

.fontSize(12)

.padding({ left: 8, right: 8, top: 4, bottom: 4 })

.backgroundColor(record.type === '收入' ? '#E8F5E9' : '#FFEBEE')

.fontColor(record.type === '收入' ? '#4CAF50' : '#FF5722')

.borderRadius(10)// 日期
    Text(record.date)
      .fontSize(12)
      .fontColor('#999999')
      .layoutWeight(1)
      .margin({ left: 8 })
    
    // 金額
    Text((record.type === '收入' ? '+' : '-') + '¥' + record.amount.toFixed(2))
      .fontSize(18)
      .fontWeight(FontWeight.Bold)
      .fontColor(record.type === '收入' ? '#4CAF50' : '#FF5722')
  }
  .width('100%')
  
  // 第二行:備註
  if (record.note) {
    Row() {
      Text(record.note)
        .fontSize(14)
        .fontColor('#666666')
        .maxLines(1)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
    }
    .width('100%')
  }
  
  // 第三行:操作按鈕
  Row({ space: 12 }) {
    Button('編輯')
      .width(70)
      .height(30)
      .fontSize(12)
      .backgroundColor('#2196F3')
      .onClick(() => {
        this.editRecord(record);
      })
    
    Button('刪除')
      .width(70)
      .height(30)
      .fontSize(12)
      .backgroundColor('#FF5722')
      .onClick(() => {
        this.deleteRecord(record.id);
      })
  }
  .width('100%')
  .justifyContent(FlexAlign.End)
  .margin({ top: 8 })
}
.width('100%')
.padding(12)
.backgroundColor('#FFFFFF')
.borderRadius(8)
.shadow({ radius: 2, color: '#E0E0E0', offsetX: 1, offsetY: 1 })}
// 編輯對話框

@Builder

buildEditDialog() {

Column() {

// 標題

Text(this.isEditing ? '編輯記錄' : '添加記錄')

.fontSize(18)

.fontWeight(FontWeight.Bold)

.margin({ top: 20, bottom: 16 })// 收支類型選擇
  Row({ space: 20 }) {
    Radio({ value: '支出', group: 'recordType' })
      .checked(this.currentRecord.type === '支出')
      .onChange((isChecked: boolean) => {
        if (isChecked) {
          this.currentRecord.type = '支出';
        }
      })
    Text('支出')
      .fontSize(16)
      .onClick(() => {
        this.currentRecord.type = '支出';
      })
    
    Radio({ value: '收入', group: 'recordType' })
      .checked(this.currentRecord.type === '收入')
      .onChange((isChecked: boolean) => {
        if (isChecked) {
          this.currentRecord.type = '收入';
        }
      })
    Text('收入')
      .fontSize(16)
      .onClick(() => {
        this.currentRecord.type = '收入';
      })
  }
  .margin({ bottom: 16 })
  
  // 金額輸入
  TextInput({ placeholder: '輸入金額', text: this.currentRecord.amount > 0 ? this.currentRecord.amount.toString() : '' })
    .width('90%')
    .height(45)
    .type(InputType.Number)
    .margin({ bottom: 12 })
    .onChange((value: string) => {
      this.currentRecord.amount = parseFloat(value) || 0;
    })
  
  // 類別選擇
  Row({ space: 8 }) {
    ForEach(
      this.currentRecord.type === '支出' ? this.expenseCategories : this.incomeCategories,
      (category: string) => {
        Text(category)
          .fontSize(14)
          .padding({ left: 12, right: 12, top: 6, bottom: 6 })
          .backgroundColor(this.currentRecord.category === category ? '#007DFF' : '#F0F0F0')
          .fontColor(this.currentRecord.category === category ? '#FFFFFF' : '#666666')
          .borderRadius(16)
          .onClick(() => {
            this.currentRecord.category = category;
          })
      }
    )
  }
  .width('90%')
  .margin({ bottom: 12 })
  
  // 日期輸入
  TextInput({ placeholder: '日期(如:2024-01-15)', text: this.currentRecord.date })
    .width('90%')
    .height(45)
    .margin({ bottom: 12 })
    .onChange((value: string) => {
      this.currentRecord.date = value;
    })
  
  // 備註輸入
  TextInput({ placeholder: '備註(可選)', text: this.currentRecord.note })
    .width('90%')
    .height(45)
    .margin({ bottom: 20 })
    .onChange((value: string) => {
      this.currentRecord.note = value;
    })
  
  // 操作按鈕
  Row({ space: 20 }) {
    Button('取消')
      .width(120)
      .height(40)
      .fontSize(16)
      .backgroundColor('#9E9E9E')
      .onClick(() => {
        this.showEditDialog = false;
      })
    
    Button(this.isEditing ? '保存' : '添加')
      .width(120)
      .height(40)
      .fontSize(16)
      .backgroundColor('#007DFF')
      .onClick(() => {
        this.saveRecord();
      })
  }
  .margin({ bottom: 20 })
}
.width('85%')
.backgroundColor('#FFFFFF')
.borderRadius(12)
.shadow({ radius: 20, color: '#00000040' })
.position({ x: '7.5%', y: '10%' })}
// 添加新記錄

addNewRecord() {

const newId = this.accountList.length > 0 ?

Math.max(...this.accountList.map(item => item.id)) + 1 : 1;

const today = new Date();

const dateStr = ${today.getFullYear()}-${(today.getMonth() + 1).toString().padStart(2, '0')}-${today.getDate().toString().padStart(2, '0')};this.currentRecord = new AccountRecord(
  newId,
  '支出',
  0,
  '餐飲',
  dateStr,
  ''
);
this.isEditing = false;
this.showEditDialog = true;}
// 編輯記錄

editRecord(record: AccountRecord) {

this.currentRecord = { ...record };

this.isEditing = true;

this.showEditDialog = true;

}// 保存記錄

saveRecord() {

if (this.currentRecord.amount <= 0) {

promptAction.showToast({ message: '請輸入有效金額', duration: 2000 });

return;

}if (!this.currentRecord.date) {
  promptAction.showToast({ message: '請輸入日期', duration: 2000 });
  return;
}

if (this.isEditing) {
  // 更新現有記錄
  const index = this.accountList.findIndex(item => item.id === this.currentRecord.id);
  if (index >= 0) {
    this.accountList[index] = { ...this.currentRecord };
  }
  promptAction.showToast({ message: '記錄更新成功', duration: 2000 });
} else {
  // 添加新記錄
  this.accountList.push({ ...this.currentRecord });
  promptAction.showToast({ message: '記錄添加成功', duration: 2000 });
}

this.showEditDialog = false;
this.calculateStatistics();}
// 刪除記錄

deleteRecord(id: number) {

promptAction.showDialog({

title: '確認刪除',

message: '確定要刪除這條記錄嗎?',

buttons: [

{ text: '取消', color: '#666666' },

{ text: '刪除', color: '#FF5722' }

]

}).then((result) => {

if (result.index === 1) {

const index = this.accountList.findIndex(item => item.id === id);

if (index >= 0) {

this.accountList.splice(index, 1);

promptAction.showToast({ message: '刪除成功', duration: 2000 });

this.calculateStatistics();

}

}

});

}// 計算收支統計

calculateStatistics() {

this.totalIncome = 0;

this.totalExpense = 0;this.accountList.forEach(record => {
  if (record.type === '收入') {
    this.totalIncome += record.amount;
  } else {
    this.totalExpense += record.amount;
  }
});

this.balance = this.totalIncome - this.totalExpense;}
// 獲取篩選後的記錄

getFilteredRecords(): AccountRecord[] {

if (this.selectedCategory === '全部') {

return this.accountList;

}

return this.accountList.filter(record => record.category === this.selectedCategory);

}

}`