功能説明
這是一個基於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);
}
}`
本文章為轉載內容,我們尊重原作者對文章享有的著作權。如有內容錯誤或侵權問題,歡迎原作者聯繫我們進行內容更正或刪除文章。