❤Node-商品模块
【摘要】 ❤Node-商品模块
❤Node-商品模块
1、商品表的创建
接下来我们新建一个商品表 Products,实现商品模块部分的功能
创建一个对应的 SQL 数据表
该表使用InnoDB引擎,字符集为utf8mb4,排序规则为utf8mb4_0900_ai_ci
CREATE TABLE Products (
product_id INT AUTO_INCREMENT PRIMARY KEY, -- 商品ID,主键,自增
name VARCHAR(255) NOT NULL, -- 商品名称
description TEXT, -- 商品描述
category_id INT, -- 商品类别ID(外键,关联Categories表)
price DECIMAL(10, 2) NOT NULL, -- 商品价格
stock INT DEFAULT 0, -- 商品库存
sku VARCHAR(255), -- 商品SKU(库存单位)
brand VARCHAR(255), -- 商品品牌
weight DECIMAL(10, 2), -- 商品重量
dimensions VARCHAR(255), -- 商品尺寸(长、宽、高)
color VARCHAR(255), -- 商品颜色
size VARCHAR(255), -- 商品尺码
status VARCHAR(50) DEFAULT 'available', -- 商品状态(如:available, out_of_stock等)
is_active BOOLEAN DEFAULT TRUE, -- 是否激活(是否对外展示销售)
is_featured BOOLEAN DEFAULT FALSE, -- 是否为特色商品(如首页推荐商品)
is_on_sale BOOLEAN DEFAULT FALSE, -- 是否参与促销活动
image_url VARCHAR(255), -- 商品主图URL
additional_images TEXT, -- 商品附加图像URL(可多图)
video_url VARCHAR(255), -- 商品视频URL
created_at DATETIME DEFAULT CURRENT_TIMESTAMP, -- 商品创建时间
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 商品最后更新时间
deleted_at DATETIME, -- 商品删除时间(软删除用)
tags TEXT, -- 商品标签,逗号分隔的字符串(如"新品,限时折扣")
promotion_price DECIMAL(10, 2), -- 促销价格
rating DECIMAL(3, 2), -- 商品评分(可选,平均分)
review_count INT DEFAULT 0, -- 商品评论数
shipping_fee DECIMAL(10, 2), -- 商品的运费
supplier_id INT, -- 供应商ID(外键,关联供应商表)
-- 外键约束
FOREIGN KEY (category_id) REFERENCES Categories(id), -- 外键:商品类别ID关联Categories表
FOREIGN KEY (supplier_id) REFERENCES Suppliers(id) -- 外键:供应商ID关联Suppliers表
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
👉 去掉外键约束
//去掉外键约束
CREATE TABLE Products (
product_id INT AUTO_INCREMENT PRIMARY KEY, -- 商品ID,主键,自增
name VARCHAR(255) NOT NULL, -- 商品名称
description TEXT, -- 商品描述
category_id INT, -- 商品类别ID
price DECIMAL(10, 2) NOT NULL, -- 商品价格
stock INT DEFAULT 0, -- 商品库存
sku VARCHAR(255), -- 商品SKU(库存单位)
brand VARCHAR(255), -- 商品品牌
weight DECIMAL(10, 2), -- 商品重量
dimensions VARCHAR(255), -- 商品尺寸(长、宽、高)
color VARCHAR(255), -- 商品颜色
size VARCHAR(255), -- 商品尺码
status VARCHAR(50) DEFAULT 'available', -- 商品状态(如:available, out_of_stock等)
is_active BOOLEAN DEFAULT TRUE, -- 是否激活(是否对外展示销售)
is_featured BOOLEAN DEFAULT FALSE, -- 是否为特色商品(如首页推荐商品)
is_on_sale BOOLEAN DEFAULT FALSE, -- 是否参与促销活动
image_url VARCHAR(255), -- 商品主图URL
additional_images TEXT, -- 商品附加图像URL(可多图)
video_url VARCHAR(255), -- 商品视频URL
created_at DATETIME DEFAULT CURRENT_TIMESTAMP, -- 商品创建时间
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 商品最后更新时间
deleted_at DATETIME, -- 商品删除时间(软删除用)
tags TEXT, -- 商品标签,逗号分隔的字符串(如"新品,限时折扣")
promotion_price DECIMAL(10, 2), -- 促销价格
rating DECIMAL(3, 2), -- 商品评分(可选,平均分)
review_count INT DEFAULT 0, -- 商品评论数
shipping_fee DECIMAL(10, 2), -- 商品的运费
supplier_id INT -- 供应商ID
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2、搜索接口
SELECT * FROM Products
接下来为商品模块写一个搜索接口,根据商品名称、商品描述、商品标签进行模糊搜索
👉 productsRoutes.js
引入封装方法
const express = require('express');
const router = express.Router();
const connectionPool = require('../db'); // 引入数据库连接池模块
const {addCondition,addDateRangeCondition,addPagination,convertKeysToSnakeCase} = require('../methods.js'); // 引入封装方法
const {listApi,getApi,addApi,updateApi,delApi,changeStatusApi} = require('../apimethods.js');
查询列表
// 查询列表
router.get('/',(req, res) => {
// 查询数据库列表
let querySql = `SELECT * FROM Products WHERE deleted_time IS NULL`;
// 查询数据库总数
let querysqltotal = `SELECT COUNT(*) AS total FROM Products`
// 查询数据库并返回数据
const { name, description, category_id, price, stock, sku, brand,
weight, dimensions, color, size, status, is_active, is_featured,
is_on_sale, image_url, additional_images, video_url, tags, promotion_price,
rating, review_count, shipping_fee, supplier_id,page_num, page_size } = convertKeysToSnakeCase(req.query);
listApi(querySql,querysqltotal,req,res,{ name,page_num, page_size});
});
验证一下我们的查询接口 ,查询没问题
3、增加接口
添加功能
先来试试我们的数据库插入语言,看是否正确
-- 插入第一条数据
INSERT INTO Products (name, description, category_id, price, stock, sku, brand, weight, dimensions, color, size, status, is_active, is_featured, is_on_sale, image_url, additional_images, video_url, tags, promotion_price, rating, review_count, shipping_fee, supplier_id)
VALUES
('智能手机 A1', '这是一款高性能智能手机,支持5G网络', 1, 2999.99, 150, 'A1-1234', '品牌A', 0.2, '150x70x8mm', '黑色', '6.1英寸', 'available', TRUE, TRUE, FALSE, 'http://example.com/image_a1.jpg', 'http://example.com/image_a1_2.jpg', 'http://example.com/video_a1.mp4', '新品,热销', 2799.99, 4.5, 100, 10.00, 1);
-- 插入第二条数据
INSERT INTO Products (name, description, category_id, price, stock, sku, brand, weight, dimensions, color, size, status, is_active, is_featured, is_on_sale, image_url, additional_images, video_url, tags, promotion_price, rating, review_count, shipping_fee, supplier_id)
VALUES
('无线耳机 B2', '超长待机的无线耳机,支持蓝牙5.0', 2, 599.99, 300, 'B2-5678', '品牌B', 0.1, '50x50x20mm', '白色', '均码', 'available', TRUE, FALSE, TRUE, 'http://example.com/image_b2.jpg', 'http://example.com/image_b2_2.jpg', 'http://example.com/video_b2.mp4', '热销,促销', 549.99, 4.7, 150, 5.00, 2);
-- 插入第三条数据
INSERT INTO Products (name, description, category_id, price, stock, sku, brand, weight, dimensions, color, size, status, is_active, is_featured, is_on_sale, image_url, additional_images, video_url, tags, promotion_price, rating, review_count, shipping_fee, supplier_id)
VALUES
('4K电视 C3', '大屏幕4K超高清电视,支持HDR10', 3, 4999.99, 50, 'C3-9101', '品牌C', 15.0, '1200x800x100mm', '银色', '55英寸', 'available', TRUE, TRUE, FALSE, 'http://example.com/image_c3.jpg', 'http://example.com/image_c3_2.jpg', 'http://example.com/video_c3.mp4', '新品,大屏', 4599.99, 4.8, 200, 50.00, 3);
查看数据库部分,数据库之中的数据已经进行了相应的更改,接下来我们将数据库语言放入我们的语句之中
// 新增 POST
router.post('/', (req, res) => {
const insertSql = 'INSERT INTO Products SET ?'; // 准备 SQL 插入语句
const { name, description, category_id, price, stock, sku, brand,
weight, dimensions, color, size, status, is_active, is_featured,
is_on_sale, image_url, additional_images, video_url, tags, promotion_price,
rating, review_count, shipping_fee, supplier_id,} = convertKeysToSnakeCase(req.body);
const postData = { name, description, category_id, price, stock, sku, brand,
weight, dimensions, color, size, status, is_active, is_featured,
is_on_sale, image_url, additional_images, video_url, tags, promotion_price,
rating, review_count, shipping_fee, supplier_id,};
addApi(insertSql,res,postData);
});
尝试一下我们的新增接口
// 新增数据
{
"name": "智能手机",
"description": "最新款智能手机,支持5G网络。",
"category_id": 1,
"price": 3999.99,
"stock": 50,
"sku": "SM-123456",
"brand": "品牌A",
"weight": 0.45,
"dimensions": "15.5x7.5x0.8 cm",
"color": "黑色",
"size": "标准",
"status": "available",
"is_active": true,
"is_featured": false,
"is_on_sale": true,
"image_url": "https://example.com/product_image.jpg",
"additional_images": "https://example.com/product_image1.jpg,https://example.com/product_image2.jpg",
"video_url": "https://example.com/product_video.mp4",
"created_at": "2025-04-08T10:00:00",
"updated_at": "2025-04-08T10:00:00",
"deleted_at": null,
"tags": "新品,限时折扣",
"promotion_price": 2999.99,
"rating": 4.5,
"review_count": 120,
"shipping_fee": 30.00,
"supplier_id": 10
};
增加功能ok,并且能正确返回我们想要的东西
4、详情接口
详情,通过id然后查到对应的内容
接下来我们简单写一个详情
// 获取详情
// 获取详情 3
router.get('/:id', (req, res) => {
// console.log(req.params,'req.params');
const { id } = req.params;
const values = [id];
let querySql = 'SELECT * FROM Products WHERE product_id = ?';
getApi(querySql,values,res);
});
简单测试一下,详情接口没问题,采用ID的方式进行获取的
5、修改接口
接下来我们完善一下我们的修改接口:
// 更新sql语句
UPDATE Products
SET
name = '无线耳机 B2',
description = '超长待机的无线耳机,支持蓝牙5.0',
category_id = 2,
price = 599.99,
stock = 300,
brand = '品牌B',
weight = 0.1,
dimensions = '50x50x20mm',
color = '白色',
size = '均码',
status = 'available',
is_active = TRUE,
is_featured = FALSE,
is_on_sale = TRUE,
image_url = 'http://example.com/image_b2.jpg',
additional_images = 'http://example.com/image_b2_2.jpg',
video_url = 'http://example.com/video_b2.mp4',
tags = '热销,促销',
promotion_price = 549.99,
rating = 4.7,
review_count = 150,
shipping_fee = 5.00,
supplier_id = 2
WHERE sku = 'B2-5678';
写一下修改接口的更改
// 更新接口 PUT请求处理程序
router.put('/', (req, res) => {
const { name, description, category_id, price, stock, sku, brand,
weight, dimensions, color, size, status, is_active, is_featured,
is_on_sale, image_url, additional_images, video_url, tags, promotion_price,
rating, review_count, shipping_fee, supplier_id,product_id} = convertKeysToSnakeCase(req.body);
const updatevalues = {name, description, category_id, price, stock, sku, brand,
weight, dimensions, color, size, status, is_active, is_featured,
is_on_sale, image_url, additional_images, video_url, tags, promotion_price,
rating, review_count, shipping_fee, supplier_id,product_id};
let updateSql='UPDATE Products SET ? WHERE product_id = ?';
updateApi(updateSql,[updatevalues, product_id],res);
});
测试一下修改接口,修改接口没问题
6、删除接口
删除部分我们写一个API
// 删除数据 DELETE请求处理程序
router.delete('/:id', (req, res) => {
// const {id} = req.body; // 从请求体中获取数据
const id = req.params.id;
const delsql = "DELETE FROM Products WHERE product_id = ?";
delApi(delsql,[id],res);
});
点击删除按钮测试一下我们的接口,删除功能ok!
7、更改状态
接下来我们写一个更改状态部分的接口,我们写一个API
//禁用和使用,用于更改状态
router.put('/status/:id', (req, res) => {
// console.log(req.params,'req.params');
// console.log(req.body,'req.body');
const id = parseInt(req.params.id);
const newState = req.body.isActive ?req.body.isActive :0;
const query = 'UPDATE Products SET is_active = ? WHERE product_id = ?';
changeStatusApi(query,[newState, id],res);
});
测试一下我们的状态接口,更改状态功能ok!
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)