在智慧农业应用中,成本核算系统是农场经营管理的核心模块之一。通过精准记录和分析各项农业生产成本,农户可以更好地掌握经营状况,优化资源配置,提高经济效益。本系统基于HarmonyOS平台开发,采用现代化的数据模型和交互设计,为农业生产者提供了一套完整的成本管理解决方案。
成本核算系统的核心在于数据模型的设计。我们采用面向对象的思想,将成本记录抽象为多个相互关联的接口:
typescript复制/**
* 成本记录接口
*/
export interface CostAccountingRecord {
id: string; // 记录唯一标识
fieldId: string; // 关联地块ID
fieldName: string; // 地块名称
category: string; // 成本分类(种子/肥料/农药/人工)
item: string; // 具体项目名称
quantity: number; // 数量
unit: string; // 单位
unitPrice: number; // 单价
totalCost: number; // 总成本
date: number; // 发生日期
supplier?: string; // 供应商(可选)
notes?: string; // 备注(可选)
createdAt: number; // 创建时间
}
这种设计具有以下优势:
为了支持多维度的成本分析,我们设计了专门的统计接口:
typescript复制/**
* 成本统计信息接口
*/
export interface CostStatistics {
totalCost: number; // 总成本
recordCount: number; // 记录数量
categoryBreakdown: CategoryCost[]; // 分类成本明细
monthlyTrend: MonthlyCost[]; // 月度成本趋势
}
统计功能实现的关键点在于:
CostAccountingService是系统的核心服务类,提供了完整的成本管理功能:
typescript复制class CostAccountingService {
// 基础CRUD操作
async getAllRecords(): Promise<CostAccountingRecord[]>
async addRecord(record: CostAccountingRecord): Promise<boolean>
async updateRecord(record: CostAccountingRecord): Promise<boolean>
async deleteRecord(id: string): Promise<boolean>
// 筛选查询
async getRecordsByCategory(category: string): Promise<CostAccountingRecord[]>
async getRecordsByField(fieldId: string): Promise<CostAccountingRecord[]>
// 统计分析
async getStatistics(): Promise<CostStatistics>
async getMonthlyTotalCost(): Promise<number>
async getFieldCostStatistics(fieldId: string): Promise<number>
}
分类成本统计的实现逻辑:
typescript复制// 使用Map结构累加各分类的成本
const categoryMap = new Map<string, number>();
for (const record of records) {
const current = categoryMap.get(record.category) || 0;
categoryMap.set(record.category, current + record.totalCost);
}
// 转换为数组并计算百分比
const total = Array.from(categoryMap.values()).reduce((a, b) => a + b, 0);
const categoryBreakdown = Array.from(categoryMap.entries()).map(([category, cost]) => ({
category,
cost,
percentage: (cost / total) * 100
}));
// 按成本降序排序
categoryBreakdown.sort((a, b) => b.cost - a.cost);
月度趋势统计的实现:
typescript复制// 初始化最近6个月的数据结构
const monthlyMap = new Map<string, number>();
const now = new Date();
for (let i = 5; i >= 0; i--) {
const date = new Date(now.getFullYear(), now.getMonth() - i, 1);
const monthKey = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}`;
monthlyMap.set(monthKey, 0);
}
// 累加各月成本
for (const record of records) {
const date = new Date(record.date);
const monthKey = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}`;
if (monthlyMap.has(monthKey)) {
monthlyMap.set(monthKey, (monthlyMap.get(monthKey) || 0) + record.totalCost);
}
}
成本核算列表页面(CostAccountingPage.ets)是系统的核心交互界面,主要功能包括:
页面采用典型的HarmonyOS ArkUI开发模式,主要结构如下:
typescript复制@Entry
@ComponentV2
export struct CostAccountingPage {
@Local costRecords: CostAccountingRecord[] = [];
@Local statistics: CostStatistics | null = null;
@Local selectedCategory: string = '全部';
build() {
Column() {
this.buildHeader() // 顶部导航栏
if (this.isLoading) {
this.buildLoading()
} else {
Column() {
this.buildSummary() // 统计卡片
this.buildAnalysis() // 分析图表
this.buildCategoryFilter() // 分类筛选
this.buildCostList() // 记录列表
}
}
this.buildAddButton() // 添加按钮
}
}
}
统计卡片组件:
typescript复制@Builder
buildSummary() {
Column({ space: 12 }) {
Text('总成本')
.fontSize(14)
Text(`¥${this.statistics?.totalCost.toFixed(2) || '0.00'}`)
.fontSize(32)
.fontWeight(FontWeight.Bold)
.fontColor('#FF6B6B')
Row({ space: 16 }) {
Text(`${this.statistics?.recordCount || 0} 条记录`)
Text(`${this.statistics?.categoryBreakdown.length || 0} 个类别`)
}
}
.width('100%')
.padding(24)
.backgroundColor($r('app.color.card_background'))
.margin(16)
.borderRadius(12)
}
分类筛选组件:
typescript复制@Builder
buildCategoryFilter() {
Scroll() {
Row({ space: 8 }) {
ForEach(this.costCategories, (category: string) => {
Text(category)
.fontSize(14)
.fontColor(this.selectedCategory === category ?
Color.White : $r('app.color.text_primary'))
.padding({ left: 16, right: 16, top: 8, bottom: 8 })
.backgroundColor(this.selectedCategory === category ?
$r('app.color.primary_professional') : $r('app.color.card_background'))
.borderRadius(16)
.onClick(() => {
this.selectedCategory = category;
})
})
}
}
.scrollable(ScrollDirection.Horizontal)
}
添加成本记录页面(AddCostRecordPage.ets)提供完整的表单功能:
分类与项目的联动实现:
typescript复制private itemOptions: Record<string, string[]> = {
'种子': ['玉米种子', '小麦种子', '水稻种子'],
'肥料': ['复合肥', '尿素', '磷肥'],
// 其他分类选项...
};
@Builder
buildItemInput() {
Column({ space: 8 }) {
Text('项目名称 *')
.fontSize(14)
Row() {
Text(this.item || '请选择项目')
.fontSize(15)
.layoutWeight(1)
Text('▼')
.fontSize(12)
}
.onClick(() => {
if (!this.selectedCategory) {
promptAction.showToast({ message: '请先选择成本类别' });
return;
}
this.showItemSelector = !this.showItemSelector;
})
if (this.showItemSelector && this.selectedCategory) {
Column() {
ForEach(this.getItemOptions(), (itemOption: string) => {
Row() {
Text(itemOption)
.layoutWeight(1)
if (this.item === itemOption) {
Text('✓')
}
}
.onClick(() => {
this.item = itemOption;
this.showItemSelector = false;
})
})
}
}
}
}
表单提交前的验证逻辑:
typescript复制private validateForm(): boolean {
if (!this.selectedFieldId) {
promptAction.showToast({ message: '请选择地块' });
return false;
}
if (!this.selectedCategory) {
promptAction.showToast({ message: '请选择成本类别' });
return false;
}
if (!this.item) {
promptAction.showToast({ message: '请选择项目名称' });
return false;
}
if (!this.quantity || isNaN(parseFloat(this.quantity))) {
promptAction.showToast({ message: '请输入有效的数量' });
return false;
}
if (!this.unitPrice || isNaN(parseFloat(this.unitPrice))) {
promptAction.showToast({ message: '请输入有效的单价' });
return false;
}
return true;
}
数据加载优化:
渲染性能优化:
数据不同步问题:
表单交互问题:
成本预算功能:
移动端适配优化:
数据导出功能:
在实际开发过程中,有几个特别值得注意的技术点: