欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/

atomgit仓库地址: https://atomgit.com/feng8403000/cms


在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

一、引言

1.1 数据管理的重要性

在桌面应用中,数据管理是核心功能之一。一个可靠的数据管理系统需要:

  • 数据持久化:确保数据在应用关闭后不丢失
  • 数据完整性:保证数据的准确性和一致性
  • 数据安全性:保护敏感数据不被泄露
  • 数据可访问性:提供高效的数据查询和操作接口

1.2 Electron中的数据存储方案

在Electron应用中,常用的数据存储方案包括:

方案适用场景优点缺点
LocalStorage轻量级配置数据简单易用,无需额外依赖容量有限(约5MB),仅支持字符串
IndexedDB结构化数据存储支持复杂查询,容量大API复杂,异步操作
SQLite关系型数据存储强大的查询能力,事务支持需要native依赖,部署复杂
文件系统大量数据或二进制文件灵活,容量不受限需要手动管理文件结构

1.3 本章概述

本章将详细介绍如何在鸿蒙PC Electron应用中设计和实现一个完整的数据管理系统,包括:

  • 数据模型设计
  • 存储方案选择
  • 数据操作API
  • 数据同步策略
  • 性能优化方案

二、数据模型设计

2.1 核心数据模型

// 文章模型
class Article {
    constructor(data) {
        this.id = data.id || `art-${Date.now()}`;
        this.title = data.title || '';
        this.excerpt = data.excerpt || '';
        this.content = data.content || '';
        this.categoryId = data.categoryId || null;
        this.tagIds = data.tagIds || [];
        this.status = data.status || 'draft'; // draft, published, archived
        this.createdAt = data.createdAt || new Date().toISOString();
        this.updatedAt = data.updatedAt || new Date().toISOString();
        this.readCount = data.readCount || 0;
        this.likeCount = data.likeCount || 0;
        this.author = data.author || 'Anonymous';
        this.metadata = data.metadata || {};
    }

    validate() {
        const errors = [];
        
        if (!this.title.trim()) {
            errors.push('文章标题不能为空');
        }
        
        if (!this.content.trim()) {
            errors.push('文章内容不能为空');
        }
        
        if (!['draft', 'published', 'archived'].includes(this.status)) {
            errors.push('无效的文章状态');
        }
        
        return errors;
    }

    toJSON() {
        return {
            id: this.id,
            title: this.title,
            excerpt: this.excerpt,
            content: this.content,
            categoryId: this.categoryId,
            tagIds: this.tagIds,
            status: this.status,
            createdAt: this.createdAt,
            updatedAt: this.updatedAt,
            readCount: this.readCount,
            likeCount: this.likeCount,
            author: this.author,
            metadata: this.metadata
        };
    }

    static fromJSON(json) {
        return new Article(json);
    }
}

// 分类模型
class Category {
    constructor(data) {
        this.id = data.id || `cat-${Date.now()}`;
        this.name = data.name || '';
        this.description = data.description || '';
        this.icon = data.icon || 'folder';
        this.parentId = data.parentId || null;
        this.order = data.order || 0;
        this.createdAt = data.createdAt || new Date().toISOString();
        this.updatedAt = data.updatedAt || new Date().toISOString();
    }

    validate() {
        const errors = [];
        
        if (!this.name.trim()) {
            errors.push('分类名称不能为空');
        }
        
        return errors;
    }

    toJSON() {
        return {
            id: this.id,
            name: this.name,
            description: this.description,
            icon: this.icon,
            parentId: this.parentId,
            order: this.order,
            createdAt: this.createdAt,
            updatedAt: this.updatedAt
        };
    }

    static fromJSON(json) {
        return new Category(json);
    }
}

// 标签模型
class Tag {
    constructor(data) {
        this.id = data.id || `tag-${Date.now()}`;
        this.name = data.name || '';
        this.color = data.color || '#4caf50';
        this.description = data.description || '';
        this.createdAt = data.createdAt || new Date().toISOString();
    }

    validate() {
        const errors = [];
        
        if (!this.name.trim()) {
            errors.push('标签名称不能为空');
        }
        
        // 验证颜色格式
        if (!/^#[0-9A-Fa-f]{6}$/.test(this.color)) {
            errors.push('无效的颜色格式');
        }
        
        return errors;
    }

    toJSON() {
        return {
            id: this.id,
            name: this.name,
            color: this.color,
            description: this.description,
            createdAt: this.createdAt
        };
    }

    static fromJSON(json) {
        return new Tag(json);
    }
}

// 用户设置模型
class UserSettings {
    constructor(data) {
        this.theme = data.theme || 'tech';
        this.language = data.language || 'zh-CN';
        this.editorFontSize = data.editorFontSize || 14;
        this.autoSaveInterval = data.autoSaveInterval || 30;
        this.showPreview = data.showPreview || true;
        this.notificationsEnabled = data.notificationsEnabled || true;
        this.createdAt = data.createdAt || new Date().toISOString();
        this.updatedAt = data.updatedAt || new Date().toISOString();
    }

    toJSON() {
        return {
            theme: this.theme,
            language: this.language,
            editorFontSize: this.editorFontSize,
            autoSaveInterval: this.autoSaveInterval,
            showPreview: this.showPreview,
            notificationsEnabled: this.notificationsEnabled,
            createdAt: this.createdAt,
            updatedAt: this.updatedAt
        };
    }

    static fromJSON(json) {
        return new UserSettings(json);
    }
}

2.2 数据关系设计

┌─────────────────────────────────────────────────────────────────┐
│                        数据关系图                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   Article (文章)                                                │
│   ├─ id (主键)                                                 │
│   ├─ categoryId → Category.id (外键)                           │
│   ├─ tagIds[] → Tag.id (多对多)                                │
│   └─ 其他字段...                                                │
│                                                                 │
│   Category (分类)                                               │
│   ├─ id (主键)                                                 │
│   ├─ parentId → Category.id (自引用,支持层级)                  │
│   └─ 其他字段...                                                │
│                                                                 │
│   Tag (标签)                                                   │
│   ├─ id (主键)                                                 │
│   └─ 其他字段...                                                │
│                                                                 │
│   UserSettings (用户设置)                                       │
│   └─ 无外键关联                                                 │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

三、存储方案实现

3.1 LocalStorage适配器

class LocalStorageAdapter {
    constructor(prefix = 'article-manager') {
        this.prefix = prefix;
    }

    getKey(key) {
        return `${this.prefix}:${key}`;
    }

    getItem(key) {
        try {
            const item = localStorage.getItem(this.getKey(key));
            return item ? JSON.parse(item) : null;
        } catch (error) {
            console.error(`读取 ${key} 失败:`, error);
            return null;
        }
    }

    setItem(key, value) {
        try {
            localStorage.setItem(this.getKey(key), JSON.stringify(value));
            return true;
        } catch (error) {
            console.error(`写入 ${key} 失败:`, error);
            return false;
        }
    }

    removeItem(key) {
        try {
            localStorage.removeItem(this.getKey(key));
            return true;
        } catch (error) {
            console.error(`删除 ${key} 失败:`, error);
            return false;
        }
    }

    clear() {
        try {
            const keys = Object.keys(localStorage).filter(key => 
                key.startsWith(`${this.prefix}:`)
            );
            keys.forEach(key => localStorage.removeItem(key));
            return true;
        } catch (error) {
            console.error('清空存储失败:', error);
            return false;
        }
    }

    getAllKeys() {
        try {
            return Object.keys(localStorage).filter(key => 
                key.startsWith(`${this.prefix}:`)
            );
        } catch (error) {
            console.error('获取所有键失败:', error);
            return [];
        }
    }
}

3.2 数据存储管理器

class DataStorageManager {
    constructor() {
        this.adapter = new LocalStorageAdapter();
        this.cache = new Map();
        this.autoSaveInterval = null;
        this.pendingChanges = new Set();
        
        this.initAutoSave();
    }

    initAutoSave() {
        this.autoSaveInterval = setInterval(() => {
            this.flushPendingChanges();
        }, 30000); // 每30秒自动保存
    }

    stopAutoSave() {
        if (this.autoSaveInterval) {
            clearInterval(this.autoSaveInterval);
        }
    }

    // 文章操作
    saveArticle(article) {
        const key = `articles:${article.id}`;
        this.adapter.setItem(key, article.toJSON());
        this.cache.set(key, article);
        this.pendingChanges.add(key);
        return article;
    }

    getArticle(id) {
        const key = `articles:${id}`;
        
        // 先从缓存获取
        if (this.cache.has(key)) {
            return this.cache.get(key);
        }
        
        // 从存储获取
        const data = this.adapter.getItem(key);
        if (data) {
            const article = Article.fromJSON(data);
            this.cache.set(key, article);
            return article;
        }
        
        return null;
    }

    getAllArticles() {
        const keys = this.adapter.getAllKeys().filter(k => k.startsWith('article-manager:articles:'));
        const articles = [];
        
        keys.forEach(key => {
            const data = this.adapter.getItem(key.replace('article-manager:', ''));
            if (data) {
                articles.push(Article.fromJSON(data));
            }
        });
        
        return articles.sort((a, b) => 
            new Date(b.createdAt) - new Date(a.createdAt)
        );
    }

    deleteArticle(id) {
        const key = `articles:${id}`;
        this.adapter.removeItem(key);
        this.cache.delete(key);
        this.pendingChanges.delete(key);
    }

    // 分类操作
    saveCategory(category) {
        const key = `categories:${category.id}`;
        this.adapter.setItem(key, category.toJSON());
        this.cache.set(key, category);
        this.pendingChanges.add(key);
        return category;
    }

    getCategory(id) {
        const key = `categories:${id}`;
        
        if (this.cache.has(key)) {
            return this.cache.get(key);
        }
        
        const data = this.adapter.getItem(key);
        if (data) {
            const category = Category.fromJSON(data);
            this.cache.set(key, category);
            return category;
        }
        
        return null;
    }

    getAllCategories() {
        const keys = this.adapter.getAllKeys().filter(k => k.startsWith('article-manager:categories:'));
        const categories = [];
        
        keys.forEach(key => {
            const data = this.adapter.getItem(key.replace('article-manager:', ''));
            if (data) {
                categories.push(Category.fromJSON(data));
            }
        });
        
        return categories.sort((a, b) => a.order - b.order);
    }

    deleteCategory(id) {
        const key = `categories:${id}`;
        this.adapter.removeItem(key);
        this.cache.delete(key);
        this.pendingChanges.delete(key);
        
        // 删除关联的文章或更新文章的categoryId
        const articles = this.getAllArticles();
        articles.forEach(article => {
            if (article.categoryId === id) {
                article.categoryId = null;
                this.saveArticle(article);
            }
        });
    }

    // 标签操作
    saveTag(tag) {
        const key = `tags:${tag.id}`;
        this.adapter.setItem(key, tag.toJSON());
        this.cache.set(key, tag);
        this.pendingChanges.add(key);
        return tag;
    }

    getTag(id) {
        const key = `tags:${id}`;
        
        if (this.cache.has(key)) {
            return this.cache.get(key);
        }
        
        const data = this.adapter.getItem(key);
        if (data) {
            const tag = Tag.fromJSON(data);
            this.cache.set(key, tag);
            return tag;
        }
        
        return null;
    }

    getAllTags() {
        const keys = this.adapter.getAllKeys().filter(k => k.startsWith('article-manager:tags:'));
        const tags = [];
        
        keys.forEach(key => {
            const data = this.adapter.getItem(key.replace('article-manager:', ''));
            if (data) {
                tags.push(Tag.fromJSON(data));
            }
        });
        
        return tags.sort((a, b) => a.name.localeCompare(b.name));
    }

    deleteTag(id) {
        const key = `tags:${id}`;
        this.adapter.removeItem(key);
        this.cache.delete(key);
        this.pendingChanges.delete(key);
        
        // 从所有文章中移除该标签
        const articles = this.getAllArticles();
        articles.forEach(article => {
            const index = article.tagIds.indexOf(id);
            if (index !== -1) {
                article.tagIds.splice(index, 1);
                this.saveArticle(article);
            }
        });
    }

    // 用户设置操作
    saveUserSettings(settings) {
        const key = 'user-settings';
        this.adapter.setItem(key, settings.toJSON());
        this.cache.set(key, settings);
        this.pendingChanges.add(key);
        return settings;
    }

    getUserSettings() {
        const key = 'user-settings';
        
        if (this.cache.has(key)) {
            return this.cache.get(key);
        }
        
        const data = this.adapter.getItem(key);
        if (data) {
            const settings = UserSettings.fromJSON(data);
            this.cache.set(key, settings);
            return settings;
        }
        
        // 返回默认设置
        return new UserSettings({});
    }

    // 统计信息
    getStats() {
        const articles = this.getAllArticles();
        const categories = this.getAllCategories();
        const tags = this.getAllTags();
        
        const published = articles.filter(a => a.status === 'published').length;
        const drafts = articles.filter(a => a.status === 'draft').length;
        const totalReads = articles.reduce((sum, a) => sum + a.readCount, 0);
        const totalLikes = articles.reduce((sum, a) => sum + a.likeCount, 0);
        
        return {
            totalArticles: articles.length,
            published,
            drafts,
            totalReads,
            totalLikes,
            totalCategories: categories.length,
            totalTags: tags.length
        };
    }

    // 刷新缓存
    refreshCache() {
        this.cache.clear();
    }

    // 刷新特定类型的缓存
    refreshCacheByType(type) {
        this.cache.forEach((value, key) => {
            if (key.startsWith(`${type}:`)) {
                this.cache.delete(key);
            }
        });
    }

    // 手动触发保存
    flushPendingChanges() {
        if (this.pendingChanges.size === 0) return;
        
        console.log(`正在保存 ${this.pendingChanges.size} 个更改...`);
        
        this.pendingChanges.forEach(key => {
            const item = this.cache.get(key);
            if (item) {
                this.adapter.setItem(key, item.toJSON ? item.toJSON() : item);
            }
        });
        
        this.pendingChanges.clear();
        console.log('保存完成');
    }

    // 导出数据
    exportData() {
        const data = {
            articles: this.getAllArticles().map(a => a.toJSON()),
            categories: this.getAllCategories().map(c => c.toJSON()),
            tags: this.getAllTags().map(t => t.toJSON()),
            userSettings: this.getUserSettings().toJSON(),
            exportTime: new Date().toISOString(),
            version: '1.0.0'
        };
        
        return JSON.stringify(data, null, 2);
    }

    // 导入数据
    importData(jsonString) {
        try {
            const data = JSON.parse(jsonString);
            
            // 清空现有数据
            this.adapter.clear();
            this.cache.clear();
            this.pendingChanges.clear();
            
            // 导入分类
            if (data.categories) {
                data.categories.forEach(catData => {
                    const category = Category.fromJSON(catData);
                    this.saveCategory(category);
                });
            }
            
            // 导入标签
            if (data.tags) {
                data.tags.forEach(tagData => {
                    const tag = Tag.fromJSON(tagData);
                    this.saveTag(tag);
                });
            }
            
            // 导入文章
            if (data.articles) {
                data.articles.forEach(artData => {
                    const article = Article.fromJSON(artData);
                    this.saveArticle(article);
                });
            }
            
            // 导入用户设置
            if (data.userSettings) {
                const settings = UserSettings.fromJSON(data.userSettings);
                this.saveUserSettings(settings);
            }
            
            this.flushPendingChanges();
            return { success: true, message: '数据导入成功' };
        } catch (error) {
            console.error('数据导入失败:', error);
            return { success: false, message: `导入失败: ${error.message}` };
        }
    }
}

四、数据操作API

4.1 统一数据访问层

class DataAccessLayer {
    constructor() {
        this.storage = new DataStorageManager();
        this.observers = new Map();
    }

    // 文章API
    async createArticle(data) {
        const article = new Article(data);
        const errors = article.validate();
        
        if (errors.length > 0) {
            throw new Error(errors.join('; '));
        }
        
        return this.storage.saveArticle(article);
    }

    async updateArticle(id, data) {
        const article = this.storage.getArticle(id);
        
        if (!article) {
            throw new Error('文章不存在');
        }
        
        // 更新字段
        Object.assign(article, data);
        article.updatedAt = new Date().toISOString();
        
        const errors = article.validate();
        
        if (errors.length > 0) {
            throw new Error(errors.join('; '));
        }
        
        return this.storage.saveArticle(article);
    }

    async getArticle(id) {
        const article = this.storage.getArticle(id);
        
        if (!article) {
            throw new Error('文章不存在');
        }
        
        return article;
    }

    async getAllArticles(filters = {}) {
        let articles = this.storage.getAllArticles();
        
        // 状态过滤
        if (filters.status) {
            articles = articles.filter(a => a.status === filters.status);
        }
        
        // 分类过滤
        if (filters.categoryId) {
            articles = articles.filter(a => a.categoryId === filters.categoryId);
        }
        
        // 标签过滤
        if (filters.tagId) {
            articles = articles.filter(a => a.tagIds.includes(filters.tagId));
        }
        
        // 搜索过滤
        if (filters.search) {
            const searchLower = filters.search.toLowerCase();
            articles = articles.filter(a => 
                a.title.toLowerCase().includes(searchLower) ||
                a.excerpt.toLowerCase().includes(searchLower) ||
                a.content.toLowerCase().includes(searchLower)
            );
        }
        
        // 排序
        if (filters.sortBy) {
            articles.sort((a, b) => {
                if (filters.sortOrder === 'desc') {
                    return new Date(b[filters.sortBy]) - new Date(a[filters.sortBy]);
                }
                return new Date(a[filters.sortBy]) - new Date(b[filters.sortBy]);
            });
        }
        
        // 分页
        if (filters.page && filters.pageSize) {
            const start = (filters.page - 1) * filters.pageSize;
            const end = start + filters.pageSize;
            articles = articles.slice(start, end);
        }
        
        return articles;
    }

    async deleteArticle(id) {
        const article = this.storage.getArticle(id);
        
        if (!article) {
            throw new Error('文章不存在');
        }
        
        this.storage.deleteArticle(id);
        this.notifyObservers('articleDeleted', { id });
    }

    // 分类API
    async createCategory(data) {
        const category = new Category(data);
        const errors = category.validate();
        
        if (errors.length > 0) {
            throw new Error(errors.join('; '));
        }
        
        const saved = this.storage.saveCategory(category);
        this.notifyObservers('categoryCreated', saved);
        return saved;
    }

    async updateCategory(id, data) {
        const category = this.storage.getCategory(id);
        
        if (!category) {
            throw new Error('分类不存在');
        }
        
        Object.assign(category, data);
        category.updatedAt = new Date().toISOString();
        
        const errors = category.validate();
        
        if (errors.length > 0) {
            throw new Error(errors.join('; '));
        }
        
        const saved = this.storage.saveCategory(category);
        this.notifyObservers('categoryUpdated', saved);
        return saved;
    }

    async getCategory(id) {
        const category = this.storage.getCategory(id);
        
        if (!category) {
            throw new Error('分类不存在');
        }
        
        return category;
    }

    async getAllCategories() {
        return this.storage.getAllCategories();
    }

    async deleteCategory(id) {
        const category = this.storage.getCategory(id);
        
        if (!category) {
            throw new Error('分类不存在');
        }
        
        this.storage.deleteCategory(id);
        this.notifyObservers('categoryDeleted', { id });
    }

    // 标签API
    async createTag(data) {
        const tag = new Tag(data);
        const errors = tag.validate();
        
        if (errors.length > 0) {
            throw new Error(errors.join('; '));
        }
        
        const saved = this.storage.saveTag(tag);
        this.notifyObservers('tagCreated', saved);
        return saved;
    }

    async updateTag(id, data) {
        const tag = this.storage.getTag(id);
        
        if (!tag) {
            throw new Error('标签不存在');
        }
        
        Object.assign(tag, data);
        
        const errors = tag.validate();
        
        if (errors.length > 0) {
            throw new Error(errors.join('; '));
        }
        
        const saved = this.storage.saveTag(tag);
        this.notifyObservers('tagUpdated', saved);
        return saved;
    }

    async getTag(id) {
        const tag = this.storage.getTag(id);
        
        if (!tag) {
            throw new Error('标签不存在');
        }
        
        return tag;
    }

    async getAllTags() {
        return this.storage.getAllTags();
    }

    async deleteTag(id) {
        const tag = this.storage.getTag(id);
        
        if (!tag) {
            throw new Error('标签不存在');
        }
        
        this.storage.deleteTag(id);
        this.notifyObservers('tagDeleted', { id });
    }

    // 用户设置API
    async getUserSettings() {
        return this.storage.getUserSettings();
    }

    async updateUserSettings(data) {
        const settings = this.storage.getUserSettings();
        Object.assign(settings, data);
        settings.updatedAt = new Date().toISOString();
        
        const saved = this.storage.saveUserSettings(settings);
        this.notifyObservers('settingsUpdated', saved);
        return saved;
    }

    // 统计API
    async getStats() {
        return this.storage.getStats();
    }

    // 导出/导入API
    async exportData() {
        return this.storage.exportData();
    }

    async importData(jsonString) {
        const result = this.storage.importData(jsonString);
        
        if (result.success) {
            this.notifyObservers('dataImported', {});
        }
        
        return result;
    }

    // 观察者模式
    subscribe(eventType, callback) {
        if (!this.observers.has(eventType)) {
            this.observers.set(eventType, []);
        }
        
        this.observers.get(eventType).push(callback);
    }

    unsubscribe(eventType, callback) {
        const callbacks = this.observers.get(eventType);
        
        if (callbacks) {
            const index = callbacks.indexOf(callback);
            if (index !== -1) {
                callbacks.splice(index, 1);
            }
        }
    }

    notifyObservers(eventType, data) {
        const callbacks = this.observers.get(eventType);
        
        if (callbacks) {
            callbacks.forEach(callback => {
                try {
                    callback(data);
                } catch (error) {
                    console.error(`观察者回调失败:`, error);
                }
            });
        }
    }
}

五、数据同步策略

5.1 本地缓存策略

class CacheStrategy {
    constructor() {
        this.cache = new Map();
        this.maxAge = 300000; // 5分钟过期
        this.maxSize = 100; // 最大缓存数量
    }

    get(key) {
        const item = this.cache.get(key);
        
        if (!item) {
            return null;
        }
        
        // 检查是否过期
        if (Date.now() - item.timestamp > this.maxAge) {
            this.cache.delete(key);
            return null;
        }
        
        return item.value;
    }

    set(key, value) {
        // 如果缓存已满,删除最旧的条目
        if (this.cache.size >= this.maxSize) {
            let oldestKey = null;
            let oldestTime = Date.now();
            
            this.cache.forEach((item, k) => {
                if (item.timestamp < oldestTime) {
                    oldestTime = item.timestamp;
                    oldestKey = k;
                }
            });
            
            if (oldestKey) {
                this.cache.delete(oldestKey);
            }
        }
        
        this.cache.set(key, {
            value,
            timestamp: Date.now()
        });
    }

    delete(key) {
        this.cache.delete(key);
    }

    clear() {
        this.cache.clear();
    }

    has(key) {
        return this.cache.has(key);
    }

    getSize() {
        return this.cache.size;
    }

    // 缓存预热
    preload(keys, fetchFunction) {
        keys.forEach(key => {
            if (!this.has(key)) {
                const value = fetchFunction(key);
                if (value) {
                    this.set(key, value);
                }
            }
        });
    }
}

5.2 离线数据同步

class OfflineSyncManager {
    constructor() {
        this.queue = [];
        this.isSyncing = false;
        this.syncInterval = null;
        this.lastSyncTime = null;
    }

    addOperation(operation) {
        this.queue.push({
            ...operation,
            timestamp: Date.now(),
            id: `op-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
        });
        
        // 如果队列超过一定数量,触发同步
        if (this.queue.length >= 10) {
            this.triggerSync();
        }
    }

    async triggerSync() {
        if (this.isSyncing) {
            return;
        }
        
        this.isSyncing = true;
        
        try {
            const operationsToSync = [...this.queue];
            this.queue = [];
            
            for (const operation of operationsToSync) {
                await this.executeOperation(operation);
            }
            
            this.lastSyncTime = Date.now();
            console.log('同步完成');
        } catch (error) {
            console.error('同步失败:', error);
            // 将失败的操作放回队列
            this.queue = [...operationsToSync, ...this.queue];
        } finally {
            this.isSyncing = false;
        }
    }

    async executeOperation(operation) {
        switch (operation.type) {
            case 'create':
                await this.createItem(operation);
                break;
            case 'update':
                await this.updateItem(operation);
                break;
            case 'delete':
                await this.deleteItem(operation);
                break;
            default:
                console.warn(`未知操作类型: ${operation.type}`);
        }
    }

    async createItem(operation) {
        // 实际的创建逻辑
        console.log(`创建 ${operation.collection}:`, operation.data);
    }

    async updateItem(operation) {
        // 实际的更新逻辑
        console.log(`更新 ${operation.collection} ${operation.id}:`, operation.data);
    }

    async deleteItem(operation) {
        // 实际的删除逻辑
        console.log(`删除 ${operation.collection} ${operation.id}`);
    }

    startAutoSync(interval = 60000) {
        this.syncInterval = setInterval(() => {
            if (this.queue.length > 0 && !this.isSyncing) {
                this.triggerSync();
            }
        }, interval);
    }

    stopAutoSync() {
        if (this.syncInterval) {
            clearInterval(this.syncInterval);
        }
    }

    getQueueLength() {
        return this.queue.length;
    }

    getLastSyncTime() {
        return this.lastSyncTime;
    }

    clearQueue() {
        this.queue = [];
    }
}

六、性能优化方案

6.1 批量操作优化

class BatchOperationManager {
    constructor() {
        this.batches = new Map();
        this.batchTimeout = 500; // 500ms内的操作合并
    }

    scheduleOperation(collection, operation) {
        if (!this.batches.has(collection)) {
            this.batches.set(collection, []);
        }
        
        this.batches.get(collection).push(operation);
        
        // 设置延迟执行
        this.scheduleBatchExecution(collection);
    }

    scheduleBatchExecution(collection) {
        const key = `batch-${collection}`;
        
        // 如果已经有定时器,不重复设置
        if (this.timers && this.timers[key]) {
            return;
        }
        
        setTimeout(() => {
            this.executeBatch(collection);
            if (this.timers) {
                delete this.timers[key];
            }
        }, this.batchTimeout);
    }

    async executeBatch(collection) {
        const operations = this.batches.get(collection) || [];
        
        if (operations.length === 0) {
            return;
        }
        
        try {
            // 按操作类型分组
            const grouped = operations.reduce((acc, op) => {
                if (!acc[op.type]) {
                    acc[op.type] = [];
                }
                acc[op.type].push(op);
                return acc;
            }, {});
            
            // 批量执行
            for (const [type, ops] of Object.entries(grouped)) {
                await this.executeBatchByType(collection, type, ops);
            }
            
            console.log(`批量执行完成: ${collection} - ${operations.length} 个操作`);
        } catch (error) {
            console.error(`批量执行失败: ${collection}`, error);
        } finally {
            this.batches.set(collection, []);
        }
    }

    async executeBatchByType(collection, type, operations) {
        switch (type) {
            case 'create':
                await this.batchCreate(collection, operations);
                break;
            case 'update':
                await this.batchUpdate(collection, operations);
                break;
            case 'delete':
                await this.batchDelete(collection, operations);
                break;
        }
    }

    async batchCreate(collection, operations) {
        for (const op of operations) {
            // 创建操作
        }
    }

    async batchUpdate(collection, operations) {
        for (const op of operations) {
            // 更新操作
        }
    }

    async batchDelete(collection, operations) {
        for (const op of operations) {
            // 删除操作
        }
    }
}

6.2 索引优化

class DataIndexer {
    constructor() {
        this.indexes = new Map();
    }

    createIndex(collection, field) {
        const indexKey = `${collection}:${field}`;
        
        if (!this.indexes.has(indexKey)) {
            this.indexes.set(indexKey, new Map());
        }
        
        return this.indexes.get(indexKey);
    }

    updateIndex(collection, field, id, value) {
        const index = this.createIndex(collection, field);
        
        // 如果值是数组,为每个元素创建索引
        if (Array.isArray(value)) {
            value.forEach(v => {
                if (!index.has(v)) {
                    index.set(v, new Set());
                }
                index.get(v).add(id);
            });
        } else {
            if (!index.has(value)) {
                index.set(value, new Set());
            }
            index.get(value).add(id);
        }
    }

    queryByIndex(collection, field, value) {
        const index = this.indexes.get(`${collection}:${field}`);
        
        if (!index) {
            return [];
        }
        
        const ids = index.get(value);
        return ids ? Array.from(ids) : [];
    }

    removeFromIndex(collection, field, id, oldValue) {
        const index = this.indexes.get(`${collection}:${field}`);
        
        if (!index) {
            return;
        }
        
        if (Array.isArray(oldValue)) {
            oldValue.forEach(v => {
                const ids = index.get(v);
                if (ids) {
                    ids.delete(id);
                }
            });
        } else {
            const ids = index.get(oldValue);
            if (ids) {
                ids.delete(id);
            }
        }
    }

    clearIndex(collection, field) {
        const indexKey = `${collection}:${field}`;
        this.indexes.delete(indexKey);
    }

    rebuildIndex(collection, field, items) {
        this.clearIndex(collection, field);
        
        items.forEach(item => {
            this.updateIndex(collection, field, item.id, item[field]);
        });
    }

    getIndexStats() {
        const stats = {};
        
        this.indexes.forEach((index, key) => {
            stats[key] = {
                entries: index.size,
                totalIds: Array.from(index.values()).reduce((sum, ids) => sum + ids.size, 0)
            };
        });
        
        return stats;
    }
}

七、总结与展望

7.1 功能回顾

本章详细介绍了数据管理与持久化方案的设计与实现,包括:

  1. 数据模型设计:文章、分类、标签、用户设置的完整模型
  2. 存储方案:LocalStorage适配器和数据存储管理器
  3. 数据API:统一的数据访问层,支持CRUD操作和查询过滤
  4. 同步策略:缓存策略和离线同步机制
  5. 性能优化:批量操作和索引优化

7.2 技术亮点

  • 模块化设计:数据层与业务逻辑分离
  • 观察者模式:支持数据变更通知
  • 缓存机制:提高数据访问效率
  • 批量操作:减少存储操作次数
  • 索引优化:加速查询操作

7.3 未来扩展

未来可以考虑添加以下功能:

  • 云端同步:支持与云端服务同步数据
  • 版本控制:支持数据版本管理和回滚
  • 数据加密:保护敏感数据
  • 全文搜索:支持文章内容的全文检索
  • 数据迁移:支持不同存储方案之间的数据迁移

Logo

赋能鸿蒙PC开发者,共建全场景原生生态,共享一次开发多端部署创新价值。

更多推荐