You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+Express保存React订餐表单数据并生成唯一订单号方案

基于Express的订单持久化实现方案

不需要改动现有React表单组件的核心逻辑,仅新增后端服务、替换前端提交动作的触发逻辑即可落地需求,具体实现如下:

依赖选型

  • express:核心Web服务框架
  • cors:处理前后端跨域请求
  • uuid:生成全局唯一订单标识,避免自增ID在分布式场景下的冲突问题
  • lowdb:轻量JSON文件存储,开发阶段无需额外搭建数据库服务即可实现持久化,后续可无缝替换为MySQL/MongoDB等生产级数据库

原有React组件代码、技术术语完全保留,localStorage暂存表单草稿的逻辑可以留作断网兜底,不需要删除。

服务端核心实现

新建server.js作为服务端入口,代码如下:

const express = require('express');
const cors = require('cors');
const { v4: uuidv4 } = require('uuid');
const { Low, JSONFile } = require('lowdb');
const path = require('path');

const app = express();
// 基础中间件配置
app.use(cors());
app.use(express.json());

// 初始化持久化存储,数据写入本地orders.json文件
const adapter = new JSONFile(path.join(__dirname, 'orders.json'));
const db = new Low(adapter);
// 初始化存储结构
async function initStorage() {
  await db.read();
  db.data ||= { orders: [] };
  await db.write();
}
initStorage();

// 订单提交接口
app.post('/api/orders', async (req, res) => {
  try {
    const orderFormData = req.body;
    // 基础必填字段校验,可根据业务规则扩展
    if (!orderFormData.contact || !orderFormData.deliveryAddress || !orderFormData.goodsList?.length) {
      return res.status(400).json({ code: 400, msg: '订单必填信息缺失' });
    }
    // 生成全局唯一订单号,带UE前缀(对应Uber Eats标识),12位随机字符串无冲突
    const orderId = `UE${uuidv4().replace(/-/g, '').slice(0, 12).toUpperCase()}`;
    // 组装完整订单数据
    const completeOrder = {
      orderId,
      ...orderFormData,
      createAt: new Date().toISOString(),
      orderStatus: 'unpaid' // 初始状态,支撑后续订单流、配送流等全业务流程调用
    };
    // 写入持久化存储
    db.data.orders.push(completeOrder);
    await db.write();
    // 返回订单号给前端
    return res.status(200).json({ code: 200, msg: '订单提交成功', data: { orderId } });
  } catch (err) {
    return res.status(500).json({ code: 500, msg: '服务异常,请稍后重试' });
  }
});

// 预留订单查询接口,供后续订单详情、状态流转等业务使用
app.get('/api/orders/:orderId', async (req, res) => {
  await db.read();
  const targetOrder = db.data.orders.find(item => item.orderId === req.params.orderId);
  if (!targetOrder) {
    return res.status(404).json({ code: 404, msg: '对应订单不存在' });
  }
  return res.status(200).json({ code: 200, data: targetOrder });
});

// 启动服务,监听3001端口
const SERVER_PORT = 3001;
app.listen(SERVER_PORT, () => {
  console.log(`订单服务已启动,运行端口:${SERVER_PORT}`);
});

前端适配改动

原有表单校验、localStorage草稿暂存逻辑全部不动,仅修改提交按钮触发的逻辑,把原来的弹窗确认替换为接口调用即可,示例代码如下:

// 原表单提交方法,其他逻辑保持不变
const handleOrderSubmit = async (formValues) => {
  // 原有前端表单校验逻辑不变
  try {
    const response = await fetch('http://localhost:3001/api/orders', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(formValues)
    }).then(res => res.json());

    if (response.code === 200) {
      alert(`订单提交成功,您的订单编号为:${response.data.orderId}`);
      // 提交成功后清空本地暂存的表单草稿
      localStorage.removeItem('orderFormDraft');
      // 可追加跳转订单详情页等逻辑
    }
  } catch (err) {
    alert('订单提交失败,请检查网络后重试');
  }
}

补充说明

  • 如果前端项目是Vite/Create React App搭建的,也可以不用配置cors,直接在前端配置开发代理把/api开头的请求转发到3001端口即可
  • 生产环境替换存储层时,只需要修改订单读写的相关代码,接口入参出参、订单号生成逻辑完全不需要调整
  • 生成的订单号全局唯一,后续所有业务流程(支付、配送、售后、订单查询)都可以用这个字段做数据关联

内容的提问来源于stack exchange,提问作者yacine tamindjoute

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.09 16:15:44