目标列表模块 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

相关推荐
rchmin3 分钟前
向量数据库Milvus安装及使用实战经验分享
数据库·milvus
ego.iblacat8 分钟前
Python 连接 MySQL 数据库
数据库·python·mysql
祖传F8719 分钟前
quickbi数据集数据查询时间字段显示正确,仪表板不显示
数据库·sql·阿里云
程序猿编码33 分钟前
一个授予普通进程ROOT权限的Linux内核级后门:原理与实现深度解析
linux·运维·服务器·内核·root权限
小夏子_riotous37 分钟前
openstack的使用——9. 密钥管理服务Barbican
linux·运维·服务器·系统架构·centos·云计算·openstack
Leon-Ning Liu39 分钟前
Oracle 26ai新特性:时区、表空间、审计方面的新特性
数据库·oracle
humors2211 小时前
各厂商工具包网址
java·数据库·python·华为·sdk·苹果·工具包
Yushan Bai1 小时前
ORACLE数据库在进行DROP TABLE时失败报错ORA-00604问题的分析处理
数据库·oracle
77美式2 小时前
Node + Express + MongoDB 后端部署全解析:新手零踩坑
数据库·mongodb·express
城数派2 小时前
2000-2025年我国省市县三级逐8天日间地表温度数据(Shp/Excel格式)
数据库·arcgis·信息可视化·数据分析·excel