操作历史 - Cordova 与 OpenHarmony 混合开发实战

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

📌 模块概述

操作历史模块是MovieTracker应用中用于记录用户操作的功能。系统会记录用户的所有操作,如添加影片、编辑影片、删除影片等。用户可以查看操作历史,了解自己的操作记录,同时可以撤销或重做某些操作。

该模块的主要功能包括:记录操作、查看历史、撤销操作、重做操作、清空历史等。通过Cordova框架与OpenHarmony原生能力的结合,实现了完整的操作历史管理。

操作历史需要处理大量的操作记录,同时需要支持撤销和重做功能。

🔗 完整流程

第一步:操作记录

系统在用户执行操作时自动记录操作信息,包括操作类型、操作对象、操作时间等。记录过程需要异步进行,避免影响用户体验。

操作记录需要存储在数据库中,支持后续的查询和分析。

第二步:历史查看

用户可以查看所有的操作历史,按时间倒序排列。历史列表需要显示操作的类型、对象、时间等信息。

用户可以搜索和筛选历史记录,快速找到特定的操作。

第三步:撤销与重做

用户可以撤销最近的操作,系统会恢复到操作前的状态。同时支持重做操作,用户可以重新执行撤销的操作。

撤销和重做需要维护一个操作栈,记录所有的操作和状态变化。

🔧 Web代码实现

操作历史HTML结构

html 复制代码
<div id="history-page" class="page">
    <div class="page-header">
        <h2>操作历史</h2>
        <div class="history-actions">
            <button class="btn btn-secondary" onclick="undoLastOperation()" id="undo-btn">↶ 撤销</button>
            <button class="btn btn-secondary" onclick="redoLastOperation()" id="redo-btn">↷ 重做</button>
            <button class="btn btn-danger" onclick="clearHistory()">🗑️ 清空历史</button>
        </div>
    </div>
    
    <div class="history-list" id="history-list"></div>
</div>

操作历史实现

javascript 复制代码
let operationHistory = [];
let historyIndex = -1;

async function recordOperation(type, object, details) {
    const operation = {
        type: type,
        object: object,
        details: details,
        timestamp: Date.now(),
        id: Date.now()
    };
    
    // 移除重做栈中的操作
    operationHistory = operationHistory.slice(0, historyIndex + 1);
    operationHistory.push(operation);
    historyIndex++;
    
    // 保存到数据库
    await db.addHistory(operation);
    
    updateHistoryButtons();
}

async function undoLastOperation() {
    if (historyIndex < 0) return;
    
    const operation = operationHistory[historyIndex];
    historyIndex--;
    
    // 执行撤销操作
    await performUndo(operation);
    updateHistoryButtons();
    loadHistoryList();
}

async function redoLastOperation() {
    if (historyIndex >= operationHistory.length - 1) return;
    
    historyIndex++;
    const operation = operationHistory[historyIndex];
    
    // 执行重做操作
    await performRedo(operation);
    updateHistoryButtons();
    loadHistoryList();
}

async function performUndo(operation) {
    // 根据操作类型执行撤销
    switch(operation.type) {
        case 'add':
            await db.deleteMovie(operation.object);
            break;
        case 'delete':
            await db.addMovie(operation.details);
            break;
        case 'update':
            await db.updateMovie(operation.object, operation.details.oldData);
            break;
    }
}

async function performRedo(operation) {
    // 根据操作类型执行重做
    switch(operation.type) {
        case 'add':
            await db.addMovie(operation.details);
            break;
        case 'delete':
            await db.deleteMovie(operation.object);
            break;
        case 'update':
            await db.updateMovie(operation.object, operation.details.newData);
            break;
    }
}

function updateHistoryButtons() {
    document.getElementById('undo-btn').disabled = historyIndex < 0;
    document.getElementById('redo-btn').disabled = historyIndex >= operationHistory.length - 1;
}

async function loadHistoryList() {
    try {
        const history = await db.getHistory();
        renderHistoryList(history);
    } catch (error) {
        console.error('加载历史失败:', error);
    }
}

function renderHistoryList(history) {
    const container = document.getElementById('history-list');
    container.innerHTML = '';
    
    if (history.length === 0) {
        container.innerHTML = '<p class="empty-message">暂无操作历史</p>';
        return;
    }
    
    history.reverse().forEach(op => {
        const item = document.createElement('div');
        item.className = 'history-item';
        
        const date = new Date(op.timestamp).toLocaleString('zh-CN');
        const typeText = {
            'add': '添加',
            'delete': '删除',
            'update': '修改'
        }[op.type] || op.type;
        
        item.innerHTML = `
            <span class="operation-type">${typeText}</span>
            <span class="operation-object">${op.object}</span>
            <span class="operation-time">${date}</span>
        `;
        
        container.appendChild(item);
    });
}

async function clearHistory() {
    if (confirm('确定要清空操作历史吗?')) {
        try {
            await db.clearHistory();
            operationHistory = [];
            historyIndex = -1;
            loadHistoryList();
            updateHistoryButtons();
            showSuccess('历史已清空');
        } catch (error) {
            console.error('清空历史失败:', error);
            showError('清空历史失败');
        }
    }
}

🔌 OpenHarmony原生代码

操作历史插件

typescript 复制代码
// HistoryPlugin.ets
import { webview } from '@kit.ArkWeb';
import { common } from '@kit.AbilityKit';

export class HistoryPlugin {
    private context: common.UIAbilityContext;
    
    constructor(context: common.UIAbilityContext) {
        this.context = context;
    }
    
    public registerHistory(controller: webview.WebviewController): void {
        controller.registerJavaScriptProxy({
            object: new HistoryBridge(),
            name: 'historyNative',
            methodList: ['recordOperation', 'getOperationStats']
        });
    }
}

export class HistoryBridge {
    public recordOperation(operationJson: string): string {
        try {
            const operation = JSON.parse(operationJson);
            
            return JSON.stringify({
                success: true,
                operationId: operation.id,
                timestamp: operation.timestamp
            });
        } catch (error) {
            return JSON.stringify({
                success: false,
                error: error.message
            });
        }
    }
    
    public getOperationStats(historyJson: string): string {
        try {
            const history = JSON.parse(historyJson);
            
            const stats = {
                totalCount: history.length,
                addCount: history.filter((h: any) => h.type === 'add').length,
                deleteCount: history.filter((h: any) => h.type === 'delete').length,
                updateCount: history.filter((h: any) => h.type === 'update').length
            };
            
            return JSON.stringify(stats);
        } catch (error) {
            return JSON.stringify({
                error: error.message
            });
        }
    }
}

📝 总结

操作历史模块展示了Cordova与OpenHarmony混合开发中的操作记录和撤销重做功能。通过Web层提供历史查看界面,同时利用OpenHarmony原生能力进行操作统计。

在实现这个模块时,需要注意操作记录的完整性、撤销重做的准确性、以及性能的优化。通过合理的架构设计,可以构建出高效、易用的操作历史功能。

相关推荐
写代码的【黑咖啡】1 小时前
Python中的JSON处理(标准库)
开发语言·python·json
梨子串桃子_9 小时前
推荐系统学习笔记 | PyTorch学习笔记
pytorch·笔记·python·学习·算法
文言一心10 小时前
LINUX离线升级 Python 至 3.11.9 操作手册
linux·运维·python
诗词在线10 小时前
中国古代诗词名句按主题分类有哪些?(爱国 / 思乡 / 送别)
人工智能·python·分类·数据挖掘
高锰酸钾_10 小时前
机器学习-L1正则化和L2正则化解决过拟合问题
人工智能·python·机器学习
天天睡大觉11 小时前
Python学习11
网络·python·学习
智航GIS11 小时前
11.11 Pandas性能革命:向量化操作与内存优化实战指南
python·pandas
写代码的【黑咖啡】12 小时前
Python中的Selenium:强大的浏览器自动化工具
python·selenium·自动化
抠头专注python环境配置12 小时前
解决Windows安装PythonOCC报错:从“No module named ‘OCC’ ”到一键成功
人工智能·windows·python·3d·cad·pythonocc