欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

在这里插入图片描述

📌 模块概述

回收站模块是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原生能力实现自动清空和统计功能。

在实现这个模块时,需要注意数据的安全性、用户体验的流畅性、以及自动清空策略的合理性。通过合理的架构设计,可以构建出安全、易用的数据管理功能。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐