茶叶分类管理模块 Cordova 与 OpenHarmony 混合开发实战
摘要 茶叶分类管理模块提供完整的分类管理功能,支持添加、编辑、删除分类及查看分类下茶叶数量。系统采用Cordova框架与OpenHarmony原生能力集成,实现数据双向同步。核心流程包括:1)分类数据加载时显示加载动画;2)列表展示分类信息并支持编辑操作;3)通过IndexedDB和原生插件实现数据同步。前端代码采用动态渲染分类列表,通过模态框实现分类编辑功能,包含表单验证和异步数据操作。模块实现

📌 概述
茶叶分类管理模块允许用户自定义和管理茶叶分类。该模块集成了 Cordova 框架与 OpenHarmony 原生能力,提供了完整的分类管理功能。用户可以添加新分类、编辑分类名称、删除分类,以及查看每个分类下的茶叶数量。模块支持分类排序和搜索,帮助用户快速管理分类信息。
🔗 完整流程
第一步:分类数据加载
当用户进入分类管理页面时,应用会从数据库中加载所有分类信息。应用会显示每个分类的名称和该分类下的茶叶数量。应用会显示加载动画直到数据加载完成。
第二步:分类展示与编辑
数据加载完成后,应用会将分类显示为列表形式。用户可以点击分类项进行编辑或删除。编辑时,应用会打开模态框,允许用户修改分类名称。用户也可以添加新的分类。
第三步:数据同步与更新
当用户添加、编辑或删除分类时,应用会立即更新 IndexedDB 数据库。同时,应用会通过 Cordova 调用原生插件,将数据同步到应用的关系型数据库中。
🔧 Web 代码实现
HTML 分类列表
<div id="tea-categories-page" class="page">
<div class="page-header">
<h1>茶叶分类</h1>
<button class="btn btn-primary" onclick="openAddCategoryModal()">+ 添加分类</button>
</div>
<div id="categories-list" class="categories-list">
<!-- 分类项动态生成 -->
</div>
<!-- 添加/编辑分类模态框 -->
<div id="category-modal" class="modal" style="display: none;">
<div class="modal-content">
<div class="modal-header">
<h2 id="category-modal-title">添加分类</h2>
<button class="btn-close" onclick="closeCategoryModal()">×</button>
</div>
<form id="category-form" class="form">
<div class="form-group">
<label for="category-name">分类名称 *</label>
<input type="text" id="category-name" name="name" required>
</div>
<div class="form-group">
<label for="category-description">描述</label>
<textarea id="category-description" name="description" rows="3"></textarea>
</div>
<div class="modal-actions">
<button type="submit" class="btn btn-primary">保存</button>
<button type="button" class="btn btn-secondary" onclick="closeCategoryModal()">取消</button>
</div>
</form>
</div>
</div>
</div>
分类管理页面包含添加分类按钮和分类列表。模态框用于添加或编辑分类。
分类数据管理
let allCategories = [];
let currentEditingCategoryId = null;
async function renderCategories() {
try {
// 加载分类数据
allCategories = await db.getTeaCategories();
const listContainer = document.getElementById('categories-list');
listContainer.innerHTML = '';
if (allCategories.length === 0) {
listContainer.innerHTML = '<div class="no-data"><p>暂无分类</p></div>';
return;
}
for (const category of allCategories) {
// 获取该分类下的茶叶数量
const teaCount = await db.getTeaCountByCategory(category.id);
const categoryEl = document.createElement('div');
categoryEl.className = 'category-item';
categoryEl.dataset.categoryId = category.id;
categoryEl.innerHTML = `
<div class="category-info">
<div class="category-name">${category.name}</div>
<div class="category-count">茶叶数: ${teaCount}</div>
${category.description ? `<div class="category-description">${category.description}</div>` : ''}
</div>
<div class="category-actions">
<button class="btn-icon" onclick="editCategory(${category.id})" title="编辑">✏️</button>
<button class="btn-icon" onclick="deleteCategory(${category.id})" title="删除">🗑️</button>
</div>
`;
listContainer.appendChild(categoryEl);
}
// 绑定表单事件
document.getElementById('category-form').addEventListener('submit', handleSaveCategory);
} catch (error) {
console.error('Failed to render categories:', error);
showToast('加载分类失败', 'error');
}
}
function openAddCategoryModal() {
currentEditingCategoryId = null;
document.getElementById('category-modal-title').textContent = '添加分类';
document.getElementById('category-form').reset();
document.getElementById('category-modal').style.display = 'flex';
}
async function editCategory(categoryId) {
try {
const category = await db.getCategory(categoryId);
if (!category) {
showToast('分类不存在', 'error');
return;
}
currentEditingCategoryId = categoryId;
document.getElementById('category-modal-title').textContent = '编辑分类';
// 填充表单
document.getElementById('category-name').value = category.name;
document.getElementById('category-description').value = category.description || '';
document.getElementById('category-modal').style.display = 'flex';
} catch (error) {
console.error('Failed to edit category:', error);
showToast('加载分类信息失败', 'error');
}
}
async function handleSaveCategory(event) {
event.preventDefault();
const formData = new FormData(document.getElementById('category-form'));
const categoryData = {
name: formData.get('name'),
description: formData.get('description')
};
try {
if (currentEditingCategoryId) {
// 更新分类
await db.updateCategory(currentEditingCategoryId, categoryData);
if (window.cordova) {
cordova.exec(
null, null,
'TeaLogger',
'logEvent',
['category_updated', { categoryId: currentEditingCategoryId }]
);
}
showToast('分类已更新', 'success');
} else {
// 添加新分类
const categoryId = await db.addCategory(categoryData);
if (window.cordova) {
cordova.exec(
null, null,
'TeaLogger',
'logEvent',
['category_added', { categoryId: categoryId }]
);
}
showToast('分类已添加', 'success');
}
closeCategoryModal();
renderCategories();
} catch (error) {
console.error('Failed to save category:', error);
showToast('保存失败,请重试', 'error');
}
}
async function deleteCategory(categoryId) {
const teaCount = await db.getTeaCountByCategory(categoryId);
if (teaCount > 0) {
showToast(`该分类下有 ${teaCount} 种茶叶,无法删除`, 'warning');
return;
}
if (!confirm('确定要删除这个分类吗?')) {
return;
}
try {
await db.deleteCategory(categoryId);
if (window.cordova) {
cordova.exec(
null, null,
'TeaLogger',
'logEvent',
['category_deleted', { categoryId: categoryId }]
);
}
showToast('分类已删除', 'success');
renderCategories();
} catch (error) {
console.error('Failed to delete category:', error);
showToast('删除失败,请重试', 'error');
}
}
function closeCategoryModal() {
document.getElementById('category-modal').style.display = 'none';
currentEditingCategoryId = null;
}
这段代码实现了完整的分类管理功能。renderCategories() 加载并渲染分类列表。openAddCategoryModal() 打开添加分类的模态框。editCategory() 加载分类信息进行编辑。handleSaveCategory() 保存新增或修改的分类。deleteCategory() 删除分类,但会检查该分类下是否有茶叶。
🔌 OpenHarmony 原生代码
分类数据库操作
// entry/src/main/ets/plugins/CategoryManager.ets
import { relationalStore } from '@kit.ArkData';
export class CategoryManager {
private store: relationalStore.RdbStore;
async createCategoryTable(): Promise<void> {
const createTableSql = `
CREATE TABLE IF NOT EXISTS tea_categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`;
await this.store.executeSql(createTableSql);
}
async addCategory(category: Category): Promise<number> {
const values: relationalStore.ValuesBucket = {
name: category.name,
description: category.description,
created_at: new Date().toISOString()
};
return await this.store.insert('tea_categories', values);
}
async getTeaCountByCategory(categoryId: number): Promise<number> {
const predicates = new relationalStore.RdbPredicates('tea_library');
predicates.equalTo('type', categoryId);
const resultSet = await this.store.query(predicates);
const count = resultSet.getRowCount();
resultSet.close();
return count;
}
async deleteCategory(categoryId: number): Promise<void> {
const predicates = new relationalStore.RdbPredicates('tea_categories');
predicates.equalTo('id', categoryId);
await this.store.delete(predicates);
}
}
interface Category {
id?: number;
name: string;
description?: string;
}
这个类提供了分类的数据库操作。createCategoryTable() 创建分类表。addCategory() 添加新分类。getTeaCountByCategory() 获取该分类下的茶叶数量。deleteCategory() 删除分类。
📝 总结
茶叶分类管理模块展示了如何在 Cordova 框架中实现分类管理功能。通过 Web 层的用户界面和交互,结合原生层的数据库操作,为用户提供了高效的分类管理体验。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)