当前位置:网站首页 >  攻略

电商达人必备:从零搭建高转化商品详情页实战指南

时间:2026年06月02日 20:28:37 来源:易频IT社区

一、环境准备与项目初始化

1.1 开发环境配置

安装Node.js 18.0+版本,访问https://nodejs.org下载安装包。安装完成后验证版本:

``` node --version npm --version ```

创建项目目录并初始化:

``` mkdir ecommerce-product-page cd ecommerce-product-page npm init -y ```

1.2 核心依赖安装

安装项目所需依赖包:

``` npm install express@4.18.2 npm install ejs@3.1.9 npm install axios@1.4.0 npm install multer@1.4.5-lts.1 npm install mysql2@3.5.0 npm install dotenv@16.3.1 ```

二、数据库设计与搭建

2.1 数据库表结构

创建MySQL数据库和商品表:

``` CREATE DATABASE ecommerce_db; USE ecommerce_db; CREATE TABLE products ( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(200) NOT NULL, description TEXT NOT NULL, price DECIMAL(10,2) NOT NULL, original_price DECIMAL(10,2), stock INT DEFAULT 0, sku VARCHAR(50) UNIQUE, main_image VARCHAR(255), gallery_images JSON, specifications JSON, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_sku (sku) ); ```

2.2 环境配置文件

在项目根目录创建.env文件:

``` DB_HOST=localhost DB_USER=root DB_PASSWORD=your_password DB_NAME=ecommerce_db PORT=3000 UPLOAD_PATH=./public/uploads ```

三、商品详情页核心功能实现

3.1 项目结构搭建

创建项目目录结构:

``` ecommerce-product-page/ ├── public/ │ ├── css/ │ ├── js/ │ └── uploads/ ├── views/ │ └── product.ejs ├── routes/ │ └── products.js ├── config/ │ └── database.js ├── app.js └── package.json ```

3.2 数据库连接配置

创建config/database.js:

``` const mysql = require('mysql2/promise'); require('dotenv').config(); const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, waitForConnections: true, connectionLimit: 10, queueLimit: 0 }); module.exports = pool; ```

四、商品管理后台开发

4.1 商品上传接口

创建routes/products.js路由文件:

``` const express = require('express'); const router = express.Router(); const pool = require('../config/database'); const multer = require('multer'); const path = require('path'); const storage = multer.diskStorage({ destination: function(req, file, cb) { cb(null, process.env.UPLOAD_PATH); }, filename: function(req, file, cb) { const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() 1E9); cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname)); } }); const upload = multer({ storage: storage }); router.post('/upload', upload.array('images', 10), async (req, res) => { try { const { title, description, price, original_price, stock, sku, specifications } = req.body; const mainImage = req.files[0] ? `/uploads/${req.files[0].filename}` : null; const galleryImages = req.files.slice(1).map(file => `/uploads/${file.filename}`); const [result] = await pool.execute( `INSERT INTO products (title, description, price, original_price, stock, sku, main_image, gallery_images, specifications) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [title, description, price, original_price || null, stock, sku, mainImage, JSON.stringify(galleryImages), JSON.stringify(JSON.parse(specifications))] ); res.json({ success: true, productId: result.insertId }); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }); ```

4.2 商品详情查询接口

在products.js中添加:

``` router.get('/:id', async (req, res) => { try { const [rows] = await pool.execute( `SELECT , CASE WHEN original_price IS NOT NULL AND original_price > price THEN ROUND((1 - price/original_price) 100, 0) ELSE NULL END as discount_percentage FROM products WHERE id = ?`, [req.params.id] ); if (rows.length === 0) { return res.status(404).json({ error: 'Product not found' }); } const product = rows[0]; product.gallery_images = JSON.parse(product.gallery_images || '[]'); product.specifications = JSON.parse(product.specifications || '{}'); res.json(product); } catch (error) { res.status(500).json({ error: error.message }); } }); ```

五、前端页面实现

5.1 商品详情页模板

创建views/product.ejs:

``` <%= product.title %>
<%= product.title %>
<% if (product.discount_percentage) { %> ¥<%= product.original_price %> <%= product.discount_percentage %>% OFF <% } %>
¥<%= product.price %>
商品编号:<%= product.sku %>
<%= product.stock > 0 ? '有货' : '缺货' %>

商品规格

    <% Object.keys(product.specifications).forEach(key => { %>
  • <%= key %>:<%= product.specifications[key] %>
  • <% }); %>

商品描述

<%= product.description %>
```

5.2 前端交互脚本

创建public/js/product.js:

``` function changeMainImage(imageUrl) { document.getElementById('mainImage').src = imageUrl; } async function addToCart(productId) { try { const response = await fetch('/api/cart/add', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ productId: productId, quantity: 1 }) }); const result = await response.json(); if (result.success) { alert('商品已加入购物车'); } else { alert('加入购物车失败:' + result.error); } } catch (error) { alert('网络错误,请重试'); } } function buyNow(productId) { window.location.href = `/checkout?product=${productId}&quantity=1`; } document.addEventListener('DOMContentLoaded', function() { const stockElement = document.querySelector('.stock-status'); if (stockElement.classList.contains('out-of-stock')) { document.querySelector('.btn-add-cart').disabled = true; document.querySelector('.btn-buy-now').disabled = true; } }); ```

5.3 样式文件

创建public/css/product.css:

``` .product-container { display: flex; max-width: 1200px; margin: 0 auto; padding: 20px; gap: 40px; } .product-gallery { flex: 1; } .main-image img { width: 100%; height: auto; border: 1px solid ddd; border-radius: 8px; } .thumbnail-list { display: flex; gap: 10px; margin-top: 15px; overflow-x: auto; } .thumbnail { width: 80px; height: 80px; object-fit: cover; border: 2px solid transparent; border-radius: 4px; cursor: pointer; } .thumbnail:hover { border-color: ff6b6b; } .product-info { flex: 1; } .price-section { margin: 20px 0; } .original-price { text-decoration: line-through; color: 999; margin-right: 10px; } .discount-tag { background-color: ff6b6b; color: white; padding: 2px 8px; border-radius: 4px; font-size: 14px; } .current-price { font-size: 28px; color: e4393c; font-weight: bold; margin-top: 5px; } .sku-section { background-color: f5f5f5; padding: 15px; border-radius: 4px; margin: 20px 0; } .stock-status { display: inline-block; margin-left: 20px; padding: 4px 8px; border-radius: 4px; font-size: 14px; } .in-stock { background-color: d4edda; color: 155724; } .out-of-stock { background-color: f8d7da; color: 721c24; } .specifications ul { list-style: none; padding: 0; } .specifications li { padding: 8px 0; border-bottom: 1px solid eee; } .action-buttons { margin-top: 30px; display: flex; gap: 15px; } .btn-add-cart, .btn-buy-now { padding: 12px 30px; border: none; border-radius: 4px; font-size: 16px; cursor: pointer; flex: 1; } .btn-add-cart { background-color: ff6b6b; color: white; } .btn-buy-now { background-color: e4393c; color: white; } .product-description { max-width: 1200px; margin: 40px auto; padding: 0 20px; } .description-content { line-height: 1.8; color: 333; } ```

六、主应用文件配置

6.1 应用入口文件

创建app.js:

``` const express = require('express'); const path = require('path'); require('dotenv').config(); const app = express(); const productRoutes = require('./routes/products'); app.set('view engine', 'ejs'); app.set('views', path.join(__dirname, 'views')); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(express.static(path.join(__dirname, 'public'))); app.use('/api/products', productRoutes); app.get('/product/:id', async (req, res) => { try { const response = await fetch(`http://localhost:${process.env.PORT}/api/products/${req.params.id}`); const product = await response.json(); if (product.error) { return res.status(404).send('商品不存在'); } res.render('product', { product: product }); } catch (error) { res.status(500).send('服务器错误'); } }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`服务器运行在 http://localhost:${PORT}`); }); ```

七、部署与测试

7.1 启动应用

在项目根目录执行:

``` node app.js ```

访问 http://localhost:3000/product/1 查看商品详情页。

7.2 添加测试商品

使用Postman或curl添加测试商品:

``` curl -X POST http://localhost:3000/api/products/upload \ -F "title=测试商品" \ -F "description=这是商品详细描述内容" \ -F "price=99.99" \ -F "original_price=199.99" \ -F "stock=100" \ -F "sku=TEST001" \ -F "specifications={\"颜色\":\"红色\",\"尺寸\":\"M\",\"材质\":\"纯棉\"}" \ -F "images=@/path/to/image1.jpg" \ -F "images=@/path/to/image2.jpg" ```
标签 电商达人

相关推荐

最新

热门

推荐

精选

标签

易频IT社区是综合性互联网IT技术门户网站,专注分享网络技术、服务器运维、网络安全、编程开发、系统架构、云计算、大数据等行业干货,实时更新IT行业资讯、零基础教程、实战案例,为IT从业者、技术爱好者提供专业的学习交流平台。

Copyright © 2021-2026 易频IT社区. All Rights Reserved. 备案号:闽ICP备2023013482号 网站地图