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

atomgit仓库地址: https://atomgit.com/m0_66062719/dingdanguanli

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

一、项目概述

订单管理系统是企业数字化转型的核心组成部分,它帮助企业高效地管理销售订单、跟踪处理进度、统计分析业务数据。本篇文章将详细介绍如何使用HTML5、CSS3和JavaScript实现一个功能完整的订单管理系统,并探讨如何在HarmonyOS 6.1.0 + Electron混合架构下实现跨平台运行。

1.1 项目背景

在传统的订单管理方式中,企业通常面临以下挑战:

挑战 描述 影响
信息孤岛 订单数据分散在不同系统 查找困难、容易出错
效率低下 手动处理订单流程 耗时、易出错
数据丢失 纸质单据易丢失损坏 无法追溯
统计困难 难以实时了解业务状况 决策缺乏数据支持

本项目旨在提供一个轻量级、易部署的订单管理解决方案,解决以上问题。

1.2 技术选型理由

技术 选择理由 优势
HTML5 页面结构标准 语义化、跨平台
CSS3 样式设计 动画丰富、性能好
JavaScript ES6+ 核心逻辑 面向对象、异步处理
LocalStorage 数据持久化 无需后端、快速上手
HarmonyOS + Electron 跨平台运行 一套代码、多端运行

二、系统架构设计

2.1 整体架构

┌─────────────────────────────────────────────────────────┐
│                      表现层                            │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐  │
│  │   统计面板   │ │   订单列表   │ │   筛选面板   │  │
│  └──────────────┘ └──────────────┘ └──────────────┘  │
├─────────────────────────────────────────────────────────┤
│                      业务逻辑层                         │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐  │
│  │   订单管理   │ │   数据筛选   │ │   统计计算   │  │
│  └──────────────┘ └──────────────┘ └──────────────┘  │
├─────────────────────────────────────────────────────────┤
│                      数据访问层                         │
│  ┌──────────────────────┐                            │
│  │   LocalStorage 持久化  │                            │
│  └──────────────────────┘                            │
└─────────────────────────────────────────────────────────┘

2.2 核心类设计

class OrderManagementSystem {
    constructor() {
        this.orders = [];              // 订单数据列表
        this.editingId = null;         // 当前编辑的订单ID
        this.filteredOrders = [];      // 筛选后的订单列表
        
        this.init();                    // 初始化系统
    }
    
    init() {
        this.loadFromStorage();         // 加载数据
        this.renderOrders();            // 渲染订单列表
        this.updateStats();             // 更新统计数据
    }
}

三、数据库设计

3.1 订单数据模型

const orderSchema = {
    id: String,              // 订单编号(唯一标识)
    customerName: String,     // 客户姓名
    customerPhone: String,    // 联系电话
    amount: Number,           // 订单金额
    status: String,          // 订单状态
    note: String,            // 订单备注
    createdAt: String,        // 创建时间(ISO格式)
    updatedAt: String         // 更新时间(ISO格式)
};

3.2 订单状态枚举

状态值 显示名称 颜色编码 业务含义
pending 待处理 #f59e0b 新订单等待处理
processing 处理中 #3b82f6 正在处理中
completed 已完成 #22c55e 处理完成
cancelled 已取消 #ef4444 已取消的订单

3.3 示例数据结构

const sampleOrder = {
    id: "ORD${timestamp}${random}",
    customerName: "张三",
    customerPhone: "13800138001",
    amount: 2580.00,
    status: "pending",
    note: "加急订单,当天发货",
    createdAt: new Date().toISOString(),
    updatedAt: null
};

四、核心功能实现

4.1 订单编号生成

订单编号是订单的唯一标识,本系统采用时间戳+随机数的生成策略:

generateOrderId() {
    // 获取当前时间戳的后8位
    const date = new Date();
    const timestamp = date.getTime().toString().slice(-8);
    
    // 生成4位随机数
    const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
    
    // 组合订单编号:ORD + 时间戳 + 随机数
    return `ORD${timestamp}${random}`;
}

订单编号格式ORD1234567890

  • ORD:订单前缀,便于识别
  • 12345678:时间戳后8位
  • 90AB:4位随机数

4.2 数据持久化

使用LocalStorage实现数据的本地持久化存储:

loadFromStorage() {
    try {
        // 从LocalStorage读取订单数据
        const savedOrders = localStorage.getItem('orders');
        
        if (savedOrders) {
            // 如果有保存的数据,加载它
            this.orders = JSON.parse(savedOrders);
        } else {
            // 如果没有数据,创建示例数据
            this.createSampleData();
        }
    } catch (error) {
        console.warn('加载订单数据失败:', error);
        this.createSampleData();
    }
}

saveToStorage() {
    try {
        // 将订单数据转换为JSON字符串并保存
        localStorage.setItem('orders', JSON.stringify(this.orders));
    } catch (error) {
        console.warn('保存订单数据失败:', error);
    }
}

4.3 示例数据生成

首次使用时自动创建示例数据,方便用户快速了解系统功能:

createSampleData() {
    const sampleOrders = [
        {
            id: this.generateOrderId(),
            customerName: '张三',
            customerPhone: '13800138001',
            amount: 2580.00,
            status: 'pending',
            note: '加急订单,当天发货',
            createdAt: new Date(Date.now() - 86400000).toISOString()
        },
        {
            id: this.generateOrderId(),
            customerName: '李四',
            customerPhone: '13800138002',
            amount: 1899.50,
            status: 'processing',
            note: '需要发票',
            createdAt: new Date(Date.now() - 172800000).toISOString()
        },
        {
            id: this.generateOrderId(),
            customerName: '王五',
            customerPhone: '13800138003',
            amount: 5200.00,
            status: 'completed',
            note: '老客户,已付款',
            createdAt: new Date(Date.now() - 604800000).toISOString()
        }
    ];
    
    this.orders = sampleOrders;
    this.saveToStorage();
}

五、订单CRUD操作

5.1 创建订单

showAddModal() {
    // 重置编辑ID
    this.editingId = null;
    
    // 设置弹窗标题
    document.getElementById('modalTitle').textContent = '新建订单';
    
    // 清空表单
    document.getElementById('customerName').value = '';
    document.getElementById('customerPhone').value = '';
    document.getElementById('orderAmount').value = '';
    document.getElementById('orderStatus').value = 'pending';
    document.getElementById('orderNote').value = '';
    
    // 显示弹窗
    document.getElementById('orderModal').classList.add('active');
}

saveOrder() {
    // 获取表单数据
    const customerName = document.getElementById('customerName').value.trim();
    const customerPhone = document.getElementById('customerPhone').value.trim();
    const amount = parseFloat(document.getElementById('orderAmount').value);
    const status = document.getElementById('orderStatus').value;
    const note = document.getElementById('orderNote').value.trim();
    
    // 表单验证
    if (!customerName || !customerPhone || isNaN(amount)) {
        alert('请填写完整的订单信息!');
        return;
    }
    
    // 判断是新建还是编辑
    if (this.editingId) {
        // 编辑模式:更新现有订单
        const index = this.orders.findIndex(o => o.id === this.editingId);
        if (index !== -1) {
            this.orders[index] = {
                ...this.orders[index],
                customerName,
                customerPhone,
                amount,
                status,
                note,
                updatedAt: new Date().toISOString()
            };
        }
    } else {
        // 新建模式:创建新订单
        const newOrder = {
            id: this.generateOrderId(),
            customerName,
            customerPhone,
            amount,
            status,
            note,
            createdAt: new Date().toISOString()
        };
        
        // 添加到列表开头
        this.orders.unshift(newOrder);
    }
    
    // 保存并更新界面
    this.saveToStorage();
    this.renderOrders();
    this.updateStats();
    this.closeModal();
}

5.2 编辑订单

showEditModal(id) {
    // 查找要编辑的订单
    const order = this.orders.find(o => o.id === id);
    if (!order) return;
    
    // 设置编辑ID
    this.editingId = id;
    
    // 设置弹窗标题
    document.getElementById('modalTitle').textContent = '编辑订单';
    
    // 填充表单数据
    document.getElementById('customerName').value = order.customerName;
    document.getElementById('customerPhone').value = order.customerPhone;
    document.getElementById('orderAmount').value = order.amount;
    document.getElementById('orderStatus').value = order.status;
    document.getElementById('orderNote').value = order.note;
    
    // 显示弹窗
    document.getElementById('orderModal').classList.add('active');
}

5.3 删除订单

deleteOrder(id) {
    // 确认删除操作
    if (!confirm('确定要删除这个订单吗?')) return;
    
    // 查找订单索引
    const index = this.orders.findIndex(o => o.id === id);
    if (index !== -1) {
        // 从数组中移除
        this.orders.splice(index, 1);
        
        // 保存并更新
        this.saveToStorage();
        this.renderOrders();
        this.updateStats();
    }
}

5.4 查看详情

showDetailModal(id) {
    const order = this.orders.find(o => o.id === id);
    if (!order) return;
    
    const statusNames = {
        pending: '待处理',
        processing: '处理中',
        completed: '已完成',
        cancelled: '已取消'
    };
    
    const detailContent = document.getElementById('detailContent');
    detailContent.innerHTML = `
        <div class="detail-section">
            <h4>基本信息</h4>
            <div class="detail-row">
                <span class="detail-label">订单编号</span>
                <span class="detail-value">${order.id}</span>
            </div>
            <div class="detail-row">
                <span class="detail-label">创建时间</span>
                <span class="detail-value">${new Date(order.createdAt).toLocaleString('zh-CN')}</span>
            </div>
            <div class="detail-row">
                <span class="detail-label">订单状态</span>
                <span class="detail-value">${statusNames[order.status]}</span>
            </div>
        </div>
        <div class="detail-section">
            <h4>客户信息</h4>
            <div class="detail-row">
                <span class="detail-label">客户姓名</span>
                <span class="detail-value">${order.customerName}</span>
            </div>
            <div class="detail-row">
                <span class="detail-label">联系电话</span>
                <span class="detail-value">${order.customerPhone}</span>
            </div>
        </div>
        <div class="detail-section">
            <h4>订单信息</h4>
            <div class="detail-row">
                <span class="detail-label">订单金额</span>
                <span class="detail-value">¥${order.amount.toFixed(2)}</span>
            </div>
            <div class="detail-row">
                <span class="detail-label">订单备注</span>
                <span class="detail-value">${order.note || '无'}</span>
            </div>
        </div>
    `;
    
    document.getElementById('detailModal').classList.add('active');
}

六、筛选与搜索功能

6.1 双重筛选实现

filterOrders() {
    // 获取筛选条件
    const statusFilter = document.getElementById('statusFilter').value;
    const searchInput = document.getElementById('searchInput').value.toLowerCase();
    
    // 执行筛选
    this.filteredOrders = this.orders.filter(order => {
        // 状态匹配
        const matchStatus = statusFilter === 'all' || order.status === statusFilter;
        
        // 关键词匹配(订单号、客户姓名、电话)
        const matchSearch = !searchInput || 
            order.id.toLowerCase().includes(searchInput) ||
            order.customerName.toLowerCase().includes(searchInput) ||
            order.customerPhone.includes(searchInput);
        
        // 两个条件都满足
        return matchStatus && matchSearch;
    });
    
    // 重新渲染列表
    this.renderOrders();
}

6.2 筛选逻辑图解

输入筛选条件
    ↓
┌─────────────────────────────────┐
│  statusFilter = "pending"      │
│  searchInput = "张三"          │
└─────────────────────────────────┘
    ↓
筛选订单列表
    ↓
┌─────────────────────────────────┐
│  所有订单 →                     │
│    ↓                           │
│  过滤状态 = pending             │
│    ↓                           │
│  过滤关键词 = "张三"           │
└─────────────────────────────────┘
    ↓
显示筛选结果

七、订单列表渲染

7.1 动态HTML生成

renderOrders() {
    const orderList = document.getElementById('orderList');
    
    // 优先显示筛选结果,否则显示全部订单
    const ordersToRender = this.filteredOrders.length > 0 
        ? this.filteredOrders 
        : this.orders;
    
    // 空状态处理
    if (ordersToRender.length === 0) {
        orderList.innerHTML = `
            <div class="empty-state">
                <div class="empty-state-icon">📋</div>
                <div class="empty-state-text">暂无订单记录</div>
            </div>
        `;
        return;
    }
    
    // 状态名称映射
    const statusNames = {
        pending: '待处理',
        processing: '处理中',
        completed: '已完成',
        cancelled: '已取消'
    };
    
    // 生成订单卡片HTML
    orderList.innerHTML = ordersToRender.map(order => `
        <div class="order-card">
            <div class="order-header">
                <div class="order-id">${order.id}</div>
                <div class="order-status status-${order.status}">
                    ${statusNames[order.status]}
                </div>
            </div>
            <div class="order-body">
                <div class="order-item">
                    <div class="order-item-label">客户姓名</div>
                    <div class="order-item-value">${order.customerName}</div>
                </div>
                <div class="order-item">
                    <div class="order-item-label">联系电话</div>
                    <div class="order-item-value">${order.customerPhone}</div>
                </div>
                <div class="order-item">
                    <div class="order-item-label">订单金额</div>
                    <div class="order-item-value">¥${order.amount.toFixed(2)}</div>
                </div>
                <div class="order-item">
                    <div class="order-item-label">创建时间</div>
                    <div class="order-item-value">
                        ${new Date(order.createdAt).toLocaleDateString('zh-CN')}
                    </div>
                </div>
            </div>
            <div class="order-actions">
                <button class="order-btn btn-view" onclick="app.showDetailModal('${order.id}')">
                    查看
                </button>
                <button class="order-btn btn-edit" onclick="app.showEditModal('${order.id}')">
                    编辑
                </button>
                <button class="order-btn btn-delete" onclick="app.deleteOrder('${order.id}')">
                    删除
                </button>
            </div>
        </div>
    `).join('');
}

八、统计面板实现

8.1 实时统计数据计算

updateStats() {
    // 总订单数
    const totalOrders = this.orders.length;
    
    // 各状态订单数
    const pendingOrders = this.orders.filter(o => o.status === 'pending').length;
    const processingOrders = this.orders.filter(o => o.status === 'processing').length;
    const completedOrders = this.orders.filter(o => o.status === 'completed').length;
    
    // 总金额(排除已取消)
    const totalAmount = this.orders
        .filter(o => o.status !== 'cancelled')
        .reduce((sum, o) => sum + o.amount, 0);
    
    // 更新DOM
    document.getElementById('totalOrders').textContent = totalOrders;
    document.getElementById('pendingOrders').textContent = pendingOrders;
    document.getElementById('processingOrders').textContent = processingOrders;
    document.getElementById('completedOrders').textContent = completedOrders;
    document.getElementById('totalAmount').textContent = `¥${totalAmount.toFixed(2)}`;
}

8.2 统计计算流程

更新统计数据
    ↓
┌─────────────────────────────────┐
│  totalOrders = orders.length    │
│  pendingOrders = filter(status='pending')  │
│  processingOrders = filter(status='processing')  │
│  completedOrders = filter(status='completed')  │
└─────────────────────────────────┘
    ↓
计算总金额
    ↓
┌─────────────────────────────────┐
│  过滤: status !== 'cancelled'  │
│  汇总: reduce((sum, o) => sum + o.amount)  │
└─────────────────────────────────┘
    ↓
更新界面显示

九、UI设计与样式

9.1 深色主题设计

采用现代深色主题,减少视觉疲劳:

body {
    background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
    color: #e2e8f0;
}
颜色变量 色值 用途
#0f172a 深蓝黑 背景色
#1e293b 深灰蓝 卡片背景
#e2e8f0 浅灰白 主要文字
#3b82f6 亮蓝色 强调色/主按钮

9.2 状态颜色编码

.status-pending {
    background: rgba(245, 158, 11, 0.2);  /* 橙黄 */
    color: #f59e0b;
}

.status-processing {
    background: rgba(59, 130, 246, 0.2);  /* 蓝色 */
    color: #3b82f6;
}

.status-completed {
    background: rgba(34, 197, 94, 0.2);   /* 绿色 */
    color: #22c55e;
}

.status-cancelled {
    background: rgba(239, 68, 68, 0.2);  /* 红色 */
    color: #ef4444;
}

9.3 响应式布局

/* 桌面端:侧边栏 + 内容区 */
.main-content {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 24px;
}

/* 平板端:垂直堆叠 */
@media (max-width: 900px) {
    .main-content {
        grid-template-columns: 1fr;
    }
}

/* 移动端:自适应 */
@media (max-width: 600px) {
    .stats {
        grid-template-columns: repeat(2, 1fr);
    }
}

十、弹窗组件实现

10.1 弹窗结构

<div class="modal" id="orderModal">
    <div class="modal-content">
        <div class="modal-header">
            <h2 id="modalTitle">新建订单</h2>
            <button class="close-btn" onclick="app.closeModal()">&times;</button>
        </div>
        <div class="modal-body">
            <!-- 表单内容 -->
        </div>
        <div class="modal-footer">
            <button class="btn-secondary" onclick="app.closeModal()">取消</button>
            <button class="btn-primary" onclick="app.saveOrder()">保存</button>
        </div>
    </div>
</div>

10.2 弹窗动画

.modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.7);
    z-index: 1000;
    align-items: center;
    justify-content: center;
}

.modal.active {
    display: flex;
    animation: fadeIn 0.3s ease;
}

.modal-content {
    animation: slideUp 0.3s ease;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes slideUp {
    from {
        transform: translateY(30px);
        opacity: 0;
    }
    to {
        transform: translateY(0);
        opacity: 1;
    }
}

十一、跨平台架构实现

11.1 HarmonyOS WebEngine

在鸿蒙PC上,应用通过WebEngine组件加载:

应用启动
    ↓
WebEngine 初始化
    ↓
加载 index.html
    ↓
解析 HTML、CSS、JavaScript
    ↓
初始化订单管理系统
    ↓
显示界面

11.2 Electron桌面封装

// main.js - Electron主进程
const { app, BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
    const win = new BrowserWindow({
        width: 1400,
        height: 900,
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true
        }
    });
    
    const htmlPath = path.join(
        __dirname,
        'ohos_hap/web_engine/src/main/resources/resfile/resources/app/index.html'
    );
    win.loadFile(htmlPath);
    
    win.setMenu(null);  // 隐藏菜单栏
}

app.whenReady().then(createWindow);

十二、数据安全与错误处理

12.1 LocalStorage容量限制

LocalStorage通常有5-10MB的容量限制,大数据量时需要考虑:

方案 说明 适用场景
数据压缩 使用JSON.stringify压缩 数据量中等
分页加载 按需加载数据 数据量大
IndexedDB 更大的存储空间 数据量很大
后端API 服务器存储 企业级应用

12.2 错误处理策略

loadFromStorage() {
    try {
        const savedOrders = localStorage.getItem('orders');
        if (savedOrders) {
            this.orders = JSON.parse(savedOrders);
        } else {
            this.createSampleData();
        }
    } catch (error) {
        console.warn('加载失败:', error);
        this.createSampleData();  // 降级处理
    }
}

十三、性能优化建议

13.1 DOM操作优化

// ❌ 低效:频繁操作DOM
function renderOrdersBad(orders) {
    const orderList = document.getElementById('orderList');
    orderList.innerHTML = '';
    
    orders.forEach(order => {
        const div = document.createElement('div');
        div.innerHTML = generateOrderHTML(order);
        orderList.appendChild(div);  // 频繁添加
    });
}

// ✅ 高效:批量操作
function renderOrdersGood(orders) {
    const orderList = document.getElementById('orderList');
    orderList.innerHTML = orders.map(order => 
        generateOrderHTML(order)
    ).join('');  // 一次性更新
}

13.2 防抖处理

// 搜索框输入防抖
let debounceTimer;

function handleSearch() {
    clearTimeout(debounceTimer);
    debounceTimer = setTimeout(() => {
        app.filterOrders();
    }, 300);  // 300ms后执行
}

十四、扩展功能方向

14.1 功能扩展路线图

功能 优先级 难度 说明
导出Excel ⭐⭐ 数据导出功能
订单打印 ⭐⭐ 打印模板设计
数据备份 ⭐⭐ JSON导入导出
多用户 ⭐⭐⭐⭐ 用户权限系统
云同步 ⭐⭐⭐ 后端API对接

14.2 技术升级建议

升级项 当前方案 建议方案 理由
数据存储 LocalStorage IndexedDB 更大容量
状态管理 原生JavaScript Vue/React 更好维护
样式方案 纯CSS Tailwind CSS 开发效率
构建工具 Vite 更好的开发体验

十五、总结

15.1 项目成果

本项目成功实现了一个功能完整的订单管理系统:

模块 完成度 说明
订单CRUD ✅ 100% 增删改查完整实现
数据统计 ✅ 100% 实时统计面板
筛选搜索 ✅ 100% 状态+关键词筛选
UI设计 ✅ 100% 深色主题、响应式
数据持久化 ✅ 100% LocalStorage
跨平台 ✅ 100% HarmonyOS + Electron

15.3 学习收获

通过这个项目,我们深入学习了:

  • 面向对象设计:类的封装、方法的职责分离
  • CRUD操作:数据的创建、读取、更新、删除
  • 数据持久化:LocalStorage的使用和错误处理
  • DOM操作:模板字符串生成HTML、事件委托
  • 响应式设计:媒体查询、弹性布局
  • 跨平台开发:HarmonyOS WebEngine、Electron
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐