目标列表模块 Cordova 与 OpenHarmony 混合开发实战

📌 概述

目标列表模块允许用户查看和管理喝茶目标。该模块集成了 Cordova 框架与 OpenHarmony 原生能力,提供了完整的目标管理功能。用户可以查看所有目标、已完成目标和进行中的目标。模块支持目标的编辑、删除和标记完成。

🔗 完整流程

第一步:目标数据加载

当用户进入目标列表页面时,应用会从数据库中加载所有目标。应用会按目标状态(进行中、已完成、已过期)进行分类显示。

第二步:目标展示与交互

数据加载完成后,应用会将目标显示为列表或卡片形式。每个目标显示目标名称、描述、截止日期和完成进度。用户可以点击目标查看详细信息、编辑或删除。

第三步:目标状态更新

当用户标记目标为完成或修改目标时,应用会立即更新 IndexedDB 数据库。同时,应用会通过 Cordova 调用原生插件,将数据同步到应用的关系型数据库中。

🔧 Web 代码实现

HTML 目标列表

html 复制代码
<div id="goal-list-page" class="page">
    <div class="page-header">
        <h1>目标列表</h1>
        <button class="btn btn-primary" onclick="navigateTo('create-goal')">+ 创建目标</button>
    </div>
    
    <div class="goal-tabs">
        <button class="tab-btn active" onclick="filterGoalsByStatus('active')">进行中</button>
        <button class="tab-btn" onclick="filterGoalsByStatus('completed')">已完成</button>
        <button class="tab-btn" onclick="filterGoalsByStatus('expired')">已过期</button>
    </div>
    
    <div id="goals-list" class="goals-list">
        <!-- 目标项动态生成 -->
    </div>
</div>

目标列表页面包含标签页用于筛选不同状态的目标。

目标列表逻辑

javascript 复制代码
let allGoals = [];
let currentStatusFilter = 'active';

async function renderGoalList() {
    try {
        // 加载目标数据
        allGoals = await db.getGoals();
        
        // 按状态分类
        const now = new Date();
        allGoals.forEach(goal => {
            const deadline = new Date(goal.deadline);
            if (goal.completed) {
                goal.status = 'completed';
            } else if (deadline < now) {
                goal.status = 'expired';
            } else {
                goal.status = 'active';
            }
        });
        
        // 显示当前筛选的目标
        filterGoalsByStatus(currentStatusFilter);
        
    } catch (error) {
        console.error('Failed to render goals:', error);
        showToast('加载目标失败', 'error');
    }
}

function filterGoalsByStatus(status) {
    currentStatusFilter = status;
    
    const filtered = allGoals.filter(g => g.status === status);
    const listContainer = document.getElementById('goals-list');
    listContainer.innerHTML = '';
    
    if (filtered.length === 0) {
        listContainer.innerHTML = '<div class="no-data"><p>暂无目标</p></div>';
        return;
    }
    
    filtered.forEach(goal => {
        const goalEl = createGoalElement(goal);
        listContainer.appendChild(goalEl);
    });
}

function createGoalElement(goal) {
    const div = document.createElement('div');
    div.className = 'goal-item';
    div.dataset.goalId = goal.id;
    
    const deadline = new Date(goal.deadline).toLocaleDateString('zh-CN');
    const progress = goal.targetValue > 0 ? (goal.currentValue / goal.targetValue * 100).toFixed(0) : 0;
    
    div.innerHTML = `
        <div class="goal-header">
            <div class="goal-title">${goal.name}</div>
            <div class="goal-deadline">${deadline}</div>
        </div>
        
        <div class="goal-progress">
            <div class="progress-bar">
                <div class="progress-fill" style="width: ${progress}%"></div>
            </div>
            <div class="progress-text">${goal.currentValue} / ${goal.targetValue}</div>
        </div>
        
        <div class="goal-actions">
            <button class="btn-icon" onclick="editGoal(${goal.id})" title="编辑">✏️</button>
            <button class="btn-icon" onclick="completeGoal(${goal.id})" title="完成">✓</button>
            <button class="btn-icon" onclick="deleteGoal(${goal.id})" title="删除">🗑️</button>
        </div>
    `;
    
    return div;
}

async function completeGoal(goalId) {
    try {
        await db.updateGoal(goalId, { completed: true });
        
        if (window.cordova) {
            cordova.exec(
                null, null,
                'TeaLogger',
                'logEvent',
                ['goal_completed', { goalId: goalId }]
            );
        }
        
        showToast('目标已完成', 'success');
        renderGoalList();
    } catch (error) {
        console.error('Failed to complete goal:', error);
        showToast('操作失败', 'error');
    }
}

async function deleteGoal(goalId) {
    if (!confirm('确定要删除这个目标吗?')) {
        return;
    }
    
    try {
        await db.deleteGoal(goalId);
        
        if (window.cordova) {
            cordova.exec(
                null, null,
                'TeaLogger',
                'logEvent',
                ['goal_deleted', { goalId: goalId }]
            );
        }
        
        showToast('目标已删除', 'success');
        renderGoalList();
    } catch (error) {
        console.error('Failed to delete goal:', error);
        showToast('删除失败', 'error');
    }
}

async function editGoal(goalId) {
    const goal = await db.getGoal(goalId);
    if (goal) {
        // 导航到编辑页面,传递目标 ID
        navigateTo('create-goal', goalId);
    }
}

这段代码实现了目标列表功能。renderGoalList() 加载并渲染目标列表。filterGoalsByStatus() 按状态筛选目标。createGoalElement() 创建目标卡片。completeGoal() 标记目标为完成。deleteGoal() 删除目标。

🔌 OpenHarmony 原生代码

目标数据库操作

typescript 复制代码
// entry/src/main/ets/plugins/GoalManager.ets
import { relationalStore } from '@kit.ArkData';

export class GoalManager {
    private store: relationalStore.RdbStore;
    
    async createGoalTable(): Promise<void> {
        const createTableSql = `
            CREATE TABLE IF NOT EXISTS goals (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT NOT NULL,
                description TEXT,
                target_value REAL NOT NULL,
                current_value REAL DEFAULT 0,
                deadline TIMESTAMP NOT NULL,
                completed BOOLEAN DEFAULT 0,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        `;
        
        await this.store.executeSql(createTableSql);
    }
    
    async addGoal(goal: Goal): Promise<number> {
        const values: relationalStore.ValuesBucket = {
            name: goal.name,
            description: goal.description,
            target_value: goal.targetValue,
            current_value: goal.currentValue || 0,
            deadline: goal.deadline,
            completed: 0,
            created_at: new Date().toISOString()
        };
        
        return await this.store.insert('goals', values);
    }
    
    async updateGoalProgress(goalId: number, currentValue: number): Promise<void> {
        const predicates = new relationalStore.RdbPredicates('goals');
        predicates.equalTo('id', goalId);
        
        const values: relationalStore.ValuesBucket = {
            current_value: currentValue
        };
        
        await this.store.update(values, predicates);
    }
    
    async completeGoal(goalId: number): Promise<void> {
        const predicates = new relationalStore.RdbPredicates('goals');
        predicates.equalTo('id', goalId);
        
        const values: relationalStore.ValuesBucket = {
            completed: 1
        };
        
        await this.store.update(values, predicates);
    }
}

interface Goal {
    id?: number;
    name: string;
    description?: string;
    targetValue: number;
    currentValue?: number;
    deadline: string;
    completed?: boolean;
}

这个类管理目标的数据库操作。createGoalTable() 创建目标表。addGoal() 添加新目标。updateGoalProgress() 更新目标进度。completeGoal() 标记目标为完成。

📝 总结

目标列表模块展示了如何在 Cordova 框架中实现目标管理功能。通过 Web 层的用户界面和交互,结合原生层的数据库操作,为用户提供了高效的目标管理体验。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

相关推荐
Aniugel2 小时前
前端服务端渲染 SSR
服务器·javascript
南山nash2 小时前
Linux 系统如何释放内存
linux·运维·服务器
思成不止于此2 小时前
【MySQL 零基础入门】事务精讲(三):隔离级别与实战总结
数据库·笔记·学习·mysql
阿钱真强道2 小时前
02-COAP ubuntu 下 coap 使用及测试
运维·服务器
找不到、了2 小时前
MySQL的FEDERATED存储引擎详解
数据库·mysql
小希smallxi2 小时前
Windows平台一键启动Redis脚本
数据库·windows·redis
写代码的小阿帆2 小时前
MySQL索引原理与性能优化
数据库·mysql·性能优化
小蒜学长2 小时前
python基于Python的医疗机构药品及耗材信息管理系统(代码+数据库+LW)
数据库·spring boot·后端·python
网安INF2 小时前
防火墙的分类与部署详解
服务器·安全·网络安全·防火墙