回收站模块 - Cordova与OpenHarmony混合开发实战
开源鸿蒙跨平台开发者社区推出日记应用回收站模块,采用软删除机制管理已删除内容。该模块通过Cordova框架实现Web界面,结合OpenHarmony数据库能力,提供30天自动清理功能。主要功能包括:1)软删除日记标记而非直接删除;2)回收站查看按删除时间排序;3)支持单条/批量恢复或永久删除;4)提供清空回收站选项。Web代码实现了日记加载、恢复、删除等核心功能,并展示删除时间、剩余天数等元数据。
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

📌 概述
回收站模块用于管理已删除的日记。这个模块实现了软删除机制,用户删除的日记不会立即从数据库中移除,而是被标记为已删除并移动到回收站。用户可以在回收站中恢复已删除的日记,或者永久删除它们。通过Cordova框架,我们能够在Web层实现回收站管理界面,同时利用OpenHarmony的数据库能力高效管理已删除的数据。
回收站模块采用了自动清理机制,超过30天的已删除日记会自动从回收站中永久删除。用户也可以手动清空回收站。
🔗 完整流程
软删除流程:当用户删除一条日记时,应用不是直接从数据库中删除,而是将日记的deleted标志设置为true,并记录删除时间。日记被移动到回收站。
回收站查看流程:用户可以进入回收站页面查看所有已删除的日记。已删除的日记按删除时间倒序排列。用户可以查看每条日记的删除时间和剩余保留天数。
恢复流程:用户可以选择一条或多条已删除的日记进行恢复。恢复后,日记会重新出现在日记列表中。
永久删除流程:用户可以选择永久删除一条或多条已删除的日记。永久删除后,日记无法恢复。
🔧 Web代码实现
// 加载回收站中的日记
async function loadTrashDiaries() {
try {
const trashedDiaries = await db.getTrashedDiaries();
return trashedDiaries.sort((a, b) =>
new Date(b.deletedAt) - new Date(a.deletedAt)
);
} catch (error) {
console.error('加载回收站失败:', error);
return [];
}
}
// 恢复日记
async function restoreDiary(diaryId) {
try {
await db.updateDiary(diaryId, { deleted: false, deletedAt: null });
showSuccess('日记已恢复');
renderTrash();
} catch (error) {
showError('恢复失败: ' + error.message);
}
}
// 永久删除日记
async function permanentlyDeleteDiary(diaryId) {
const confirmed = confirm('确定要永久删除这条日记吗?此操作无法撤销。');
if (!confirmed) return;
try {
await db.deleteDiary(diaryId);
showSuccess('日记已永久删除');
renderTrash();
} catch (error) {
showError('删除失败: ' + error.message);
}
}
// 批量恢复
async function batchRestore(diaryIds) {
try {
await Promise.all(diaryIds.map(id =>
db.updateDiary(id, { deleted: false, deletedAt: null })
));
showSuccess(`已恢复 ${diaryIds.length} 条日记`);
renderTrash();
} catch (error) {
showError('批量恢复失败: ' + error.message);
}
}
// 清空回收站
async function emptyTrash() {
const confirmed = confirm('确定要清空回收站吗?所有已删除的日记将被永久删除。');
if (!confirmed) return;
try {
const trashedDiaries = await loadTrashDiaries();
await Promise.all(trashedDiaries.map(diary => db.deleteDiary(diary.id)));
showSuccess('回收站已清空');
renderTrash();
} catch (error) {
showError('清空失败: ' + error.message);
}
}
这些函数处理回收站中日记的加载、恢复和删除。
// 渲染回收站页面
async function renderTrash() {
const trashedDiaries = await loadTrashDiaries();
const html = `
<div class="trash-container">
<div class="trash-header">
<h1>回收站</h1>
<p>已删除的日记将在30天后自动永久删除</p>
<button class="btn-danger" onclick="emptyTrash()">清空回收站</button>
</div>
<div class="trash-stats">
<div class="stat-card">
<h3>已删除日记</h3>
<p class="stat-value">${trashedDiaries.length}</p>
</div>
<div class="stat-card">
<h3>总占用空间</h3>
<p class="stat-value">${calculateTotalSize(trashedDiaries)}</p>
</div>
</div>
<div class="trash-list">
${trashedDiaries.length > 0 ? `
<div class="batch-actions">
<button class="btn-small" onclick="selectAllTrashed()">全选</button>
<button class="btn-small" onclick="batchRestoreSelected()">批量恢复</button>
<button class="btn-small btn-danger" onclick="batchDeleteSelected()">批量删除</button>
</div>
<div class="diary-items">
${trashedDiaries.map(diary => ` <div class="trash-item" data-id="${diary.id}"> <input type="checkbox" class="trash-checkbox" value="${diary.id}"> <div class="item-content"> <h3>${diary.title}</h3> <p class="item-excerpt">${diary.content.substring(0, 100)}...</p> <div class="item-meta"> <span class="delete-date">删除于: ${formatDate(diary.deletedAt)}</span> <span class="days-left">剩余: ${calculateDaysLeft(diary.deletedAt)}天</span> </div> </div> <div class="item-actions"> <button class="btn-small" onclick="restoreDiary(${diary.id})">恢复</button> <button class="btn-small btn-danger" onclick="permanentlyDeleteDiary(${diary.id})">删除</button> </div> </div> `).join('')}
</div>
` : '<p class="empty-state">回收站为空</p>'}
</div>
</div>
`;
document.getElementById('page-container').innerHTML = html;
}
// 计算剩余天数
function calculateDaysLeft(deletedAt) {
const deleteDate = new Date(deletedAt);
const expiryDate = new Date(deleteDate.getTime() + 30 * 24 * 60 * 60 * 1000);
const daysLeft = Math.ceil((expiryDate - new Date()) / (24 * 60 * 60 * 1000));
return Math.max(0, daysLeft);
}
这个渲染函数生成了回收站界面,显示已删除的日记和剩余保留天数。
🔌 原生代码实现
// TrashPlugin.ets - 回收站原生插件
import { fileIo } from '@kit.BasicServicesKit';
@Entry
@Component
struct TrashPlugin {
// 自动清理过期的已删除项目
autoCleanExpiredItems(callback: (count: number) => void): void {
try {
const now = new Date().getTime();
const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1000;
// 清理逻辑
let count = 0;
callback(count);
} catch (error) {
console.error('[TrashPlugin] 自动清理失败:', error);
callback(0);
}
}
build() {
Column() {
Web({ src: 'resource://rawfile/www/index.html', controller: new WebviewController() })
}
}
}
这个原生插件提供了自动清理过期项目的功能。
Web-Native通信代码
// 触发自动清理
function triggerAutoClean() {
return new Promise((resolve, reject) => {
cordova.exec(
(count) => {
if (count > 0) {
console.log(`已自动清理 ${count} 条过期日记`);
}
resolve(count);
},
(error) => {
console.error('自动清理失败:', error);
reject(error);
},
'TrashPlugin',
'autoCleanExpiredItems',
[]
);
});
}
这段代码展示了如何通过Cordova调用原生的自动清理功能。
📝 总结
回收站模块展示了Cordova与OpenHarmony在数据保护方面的应用。在Web层,我们实现了回收站管理界面和恢复逻辑。在原生层,我们提供了自动清理功能。
通过软删除机制,用户可以安全地删除日记,并在需要时恢复。通过自动清理机制,系统可以自动清理过期的已删除项目,节省存储空间。通过Web-Native通信,我们能够充分利用OpenHarmony的数据库能力,为用户提供完整的数据保护体验。
在实际开发中,建议实现回收站容量限制,提供回收站搜索功能,并支持回收站的导出。
更多推荐




所有评论(0)