回收站 - Cordova 与 OpenHarmony 混合开发实战
开源鸿蒙跨平台开发者社区推出MovieTracker应用的回收站模块,该模块采用安全删除机制保护用户数据。主要功能包括:显示已删除影片、按时间排序、恢复/永久删除记录、批量操作和自动清空策略。通过Cordova框架与OpenHarmony原生能力结合实现数据管理,提供HTML页面结构和JavaScript交互逻辑,支持单条/批量恢复与删除操作,并配有确认对话框防止误操作。代码示例展示了回收站数据加
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

📌 模块概述
回收站模块是MovieTracker应用中的数据保护功能,用于存放用户删除的影片记录。这个模块允许用户恢复误删的影片,或者永久删除不需要的记录。回收站提供了一个安全的删除机制,防止用户意外丢失重要数据。
该模块的主要功能包括:显示所有已删除的影片、按删除时间排序、恢复影片、永久删除、清空回收站等。通过Cordova框架与OpenHarmony原生能力的结合,实现了安全的数据管理和恢复机制。
回收站模块需要处理删除时间的管理,可以设置自动清空策略(如30天后自动删除)。同时需要提供详细的删除历史记录,帮助用户追踪数据变化。
🔗 完整流程
第一步:删除数据管理
当用户删除影片时,系统不是直接从数据库中移除,而是将其标记为已删除,并记录删除时间。这样用户可以在回收站中找到已删除的影片,并选择恢复或永久删除。
删除过程包括:获取要删除的影片、将其状态改为已删除、记录删除时间、更新UI显示。我们需要建立一个完整的删除流程,确保数据的安全性和可恢复性。
第二步:回收站列表展示
完成数据管理后,需要在回收站页面展示所有已删除的影片。可以按删除时间排序,显示删除时间、影片信息等。用户可以查看已删除影片的详细信息,决定是否恢复或永久删除。
列表展示需要考虑用户体验,提供清晰的视觉反馈。同时需要支持批量操作,用户可以一次性恢复或删除多个影片。
第三步:恢复与清空机制
回收站的核心功能是恢复和清空。用户可以选择恢复单个或多个影片,将其恢复到原来的状态。同时支持永久删除,彻底移除影片数据。还可以清空整个回收站,删除所有已删除的影片。
这些操作需要提供确认对话框,防止用户误操作。同时需要记录操作历史,便于追踪数据变化。
🔧 Web代码实现
回收站HTML结构
<div id="trash-page" class="page">
<div class="page-header">
<h2>回收站</h2>
<div class="trash-stats">
<span>已删除: <strong id="trash-count">0</strong></span>
<span>最早删除: <strong id="oldest-delete">-</strong></span>
</div>
</div>
<div class="trash-actions">
<button class="btn btn-primary" onclick="restoreSelected()">恢复选中</button>
<button class="btn btn-danger" onclick="deleteSelected()">永久删除</button>
<button class="btn btn-danger" onclick="emptyTrash()">清空回收站</button>
</div>
<div class="trash-list" id="trash-items"></div>
</div>
这个HTML结构定义了回收站页面的布局。页面头部显示回收站统计信息。操作按钮支持恢复、删除、清空等操作。trash-items容器用于展示已删除的影片列表。
回收站数据加载
async function loadTrash() {
try {
const trashedMovies = await db.getDeletedMovies();
// 按删除时间排序
trashedMovies.sort((a, b) =>
new Date(b.deletedDate) - new Date(a.deletedDate)
);
document.getElementById('trash-count').textContent = trashedMovies.length;
if (trashedMovies.length > 0) {
const oldestDate = new Date(trashedMovies[trashedMovies.length - 1].deletedDate);
document.getElementById('oldest-delete').textContent = oldestDate.toLocaleDateString('zh-CN');
}
renderTrashItems(trashedMovies);
} catch (error) {
console.error('加载回收站失败:', error);
showError('加载回收站失败');
}
}
function renderTrashItems(movies) {
const container = document.getElementById('trash-items');
container.innerHTML = '';
if (movies.length === 0) {
container.innerHTML = '<p class="empty-message">回收站为空</p>';
return;
}
movies.forEach(movie => {
const item = document.createElement('div');
item.className = 'trash-item';
item.innerHTML = `
<input type="checkbox" class="item-checkbox" data-movie-id="${movie.id}">
<div class="item-info">
<h4>${movie.title}</h4>
<p class="item-meta">${movie.year} · ${movie.category}</p>
<p class="delete-time">删除于: ${new Date(movie.deletedDate).toLocaleString('zh-CN')}</p>
</div>
<div class="item-actions">
<button onclick="restoreMovie(${movie.id})" class="btn btn-small btn-success">恢复</button>
<button onclick="deleteMoviePermanently(${movie.id})" class="btn btn-small btn-danger">永久删除</button>
</div>
`;
container.appendChild(item);
});
}
这个函数实现了回收站的数据加载和渲染。首先从数据库获取所有已删除的影片,然后按删除时间排序。为每个影片项添加恢复和永久删除按钮。
恢复和删除操作
async function restoreMovie(movieId) {
try {
await db.updateMovie(movieId, { status: 'active', deletedDate: null });
loadTrash();
showSuccess('影片已恢复');
} catch (error) {
console.error('恢复影片失败:', error);
showError('恢复影片失败');
}
}
async function deleteMoviePermanently(movieId) {
if (confirm('确定要永久删除该影片吗?此操作无法撤销。')) {
try {
await db.deleteMovie(movieId);
loadTrash();
showSuccess('影片已永久删除');
} catch (error) {
console.error('删除影片失败:', error);
showError('删除影片失败');
}
}
}
async function restoreSelected() {
const checkboxes = document.querySelectorAll('.item-checkbox:checked');
if (checkboxes.length === 0) {
showError('请先选择要恢复的影片');
return;
}
try {
for (const checkbox of checkboxes) {
const movieId = parseInt(checkbox.dataset.movieId);
await db.updateMovie(movieId, { status: 'active', deletedDate: null });
}
loadTrash();
showSuccess(`已恢复 ${checkboxes.length} 部影片`);
} catch (error) {
console.error('批量恢复失败:', error);
showError('批量恢复失败');
}
}
async function emptyTrash() {
if (confirm('确定要清空回收站吗?所有已删除的影片将被永久删除,此操作无法撤销。')) {
try {
const trashedMovies = await db.getDeletedMovies();
for (const movie of trashedMovies) {
await db.deleteMovie(movie.id);
}
loadTrash();
showSuccess('回收站已清空');
} catch (error) {
console.error('清空回收站失败:', error);
showError('清空回收站失败');
}
}
}
这个函数实现了恢复和删除操作。restoreMovie()恢复单个影片,deleteMoviePermanently()永久删除影片。restoreSelected()和emptyTrash()支持批量操作。
🔌 OpenHarmony原生代码
回收站插件
// TrashPlugin.ets
import { webview } from '@kit.ArkWeb';
import { common } from '@kit.AbilityKit';
export class TrashPlugin {
private context: common.UIAbilityContext;
constructor(context: common.UIAbilityContext) {
this.context = context;
}
public registerTrash(controller: webview.WebviewController): void {
controller.registerJavaScriptProxy({
object: new TrashBridge(),
name: 'trashNative',
methodList: ['autoCleanTrash', 'getTrashStats']
});
}
}
这个OpenHarmony原生插件为回收站提供了自动清空和统计功能。
自动清空实现
export class TrashBridge {
public autoCleanTrash(retentionDays: number): string {
try {
const now = Date.now();
const retentionMs = retentionDays * 24 * 60 * 60 * 1000;
const cleanupInfo = {
retentionDays: retentionDays,
retentionMs: retentionMs,
currentTime: now,
nextCleanupTime: now + retentionMs,
message: `将在 ${retentionDays} 天后自动清空回收站`
};
return JSON.stringify(cleanupInfo);
} catch (error) {
return JSON.stringify({
error: error.message
});
}
}
public getTrashStats(trashedMoviesJson: string): string {
try {
const movies = JSON.parse(trashedMoviesJson);
const stats = {
totalCount: movies.length,
totalSize: this.calculateTotalSize(movies),
oldestDeleteDate: this.getOldestDate(movies),
newestDeleteDate: this.getNewestDate(movies)
};
return JSON.stringify(stats);
} catch (error) {
return JSON.stringify({
error: error.message
});
}
}
private calculateTotalSize(movies: any[]): number {
return movies.reduce((sum, m) => sum + (m.size || 0), 0);
}
private getOldestDate(movies: any[]): string {
if (movies.length === 0) return '-';
return movies.reduce((oldest, m) =>
new Date(m.deletedDate) < new Date(oldest.deletedDate) ? m : oldest
).deletedDate;
}
private getNewestDate(movies: any[]): string {
if (movies.length === 0) return '-';
return movies.reduce((newest, m) =>
new Date(m.deletedDate) > new Date(newest.deletedDate) ? m : newest
).deletedDate;
}
}
这个类实现了自动清空和统计功能。autoCleanTrash()方法设置自动清空策略。getTrashStats()方法计算回收站的统计信息。
Web-Native通信
调用原生清空功能
async function setupAutoCleanup() {
try {
if (window.trashNative) {
const cleanupResult = window.trashNative.autoCleanTrash(30); // 30天后自动清空
const result = JSON.parse(cleanupResult);
console.log('自动清空已设置:', result.message);
}
} catch (error) {
console.error('设置自动清空失败:', error);
}
}
async function displayTrashStats() {
try {
const trashedMovies = await db.getDeletedMovies();
if (window.trashNative) {
const statsJson = window.trashNative.getTrashStats(JSON.stringify(trashedMovies));
const stats = JSON.parse(statsJson);
console.log('回收站统计:', stats);
// 更新UI显示统计信息
}
} catch (error) {
console.error('获取统计信息失败:', error);
}
}
这个函数展示了如何调用OpenHarmony原生的回收站功能。setupAutoCleanup()设置自动清空策略,displayTrashStats()获取和显示统计信息。
📝 总结
回收站模块展示了Cordova与OpenHarmony混合开发中的数据保护和恢复机制。通过Web层提供用户友好的界面,同时利用OpenHarmony原生能力实现自动清空和统计功能。
在实现这个模块时,需要注意数据的安全性、用户体验的流畅性、以及自动清空策略的合理性。通过合理的架构设计,可以构建出安全、易用的数据管理功能。
更多推荐
所有评论(0)