修改商城逻辑
This commit is contained in:
@@ -84,6 +84,7 @@ async function createTables() {
|
||||
description TEXT,
|
||||
price INT NOT NULL,
|
||||
points_price INT NOT NULL,
|
||||
rongdou_price INT NOT NULL DEFAULT 0,
|
||||
original_price INT,
|
||||
stock INT DEFAULT 0,
|
||||
sales INT DEFAULT 0,
|
||||
@@ -91,7 +92,11 @@ async function createTables() {
|
||||
category VARCHAR(100),
|
||||
image_url VARCHAR(500),
|
||||
images JSON,
|
||||
videos JSON,
|
||||
details TEXT,
|
||||
shop_name VARCHAR(255),
|
||||
shop_avatar VARCHAR(500),
|
||||
payment_methods JSON,
|
||||
status ENUM('active', 'inactive') DEFAULT 'active',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
@@ -208,6 +213,106 @@ async function createTables() {
|
||||
)
|
||||
`);
|
||||
|
||||
// 商品规格表
|
||||
await getDB().execute(`
|
||||
CREATE TABLE IF NOT EXISTS product_specifications (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
product_id INT NOT NULL,
|
||||
spec_name VARCHAR(100) NOT NULL,
|
||||
spec_value VARCHAR(100) NOT NULL,
|
||||
price_adjustment INT DEFAULT 0,
|
||||
points_adjustment INT DEFAULT 0,
|
||||
rongdou_adjustment INT DEFAULT 0,
|
||||
stock INT DEFAULT 0,
|
||||
sku_code VARCHAR(100),
|
||||
status ENUM('active', 'inactive') DEFAULT 'active',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
|
||||
// 商品属性表
|
||||
await getDB().execute(`
|
||||
CREATE TABLE IF NOT EXISTS product_attributes (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
product_id INT NOT NULL,
|
||||
attribute_key VARCHAR(100) NOT NULL,
|
||||
attribute_value TEXT NOT NULL,
|
||||
sort_order INT DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
|
||||
// 商品收藏表
|
||||
await getDB().execute(`
|
||||
CREATE TABLE IF NOT EXISTS product_favorites (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
product_id INT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE,
|
||||
UNIQUE KEY unique_user_product (user_id, product_id)
|
||||
)
|
||||
`);
|
||||
|
||||
// 用户收货地址表
|
||||
await getDB().execute(`
|
||||
CREATE TABLE IF NOT EXISTS user_addresses (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
recipient_name VARCHAR(100) NOT NULL,
|
||||
phone VARCHAR(20) NOT NULL,
|
||||
province_code VARCHAR(20),
|
||||
province_name VARCHAR(50) NOT NULL,
|
||||
city_code VARCHAR(20),
|
||||
city_name VARCHAR(50) NOT NULL,
|
||||
district_code VARCHAR(20),
|
||||
district_name VARCHAR(50) NOT NULL,
|
||||
detailed_address TEXT NOT NULL,
|
||||
postal_code VARCHAR(10),
|
||||
label_id INT,
|
||||
is_default BOOLEAN DEFAULT FALSE,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (label_id) REFERENCES address_labels(id) ON DELETE SET NULL
|
||||
)
|
||||
`);
|
||||
|
||||
// 地址标签表
|
||||
await getDB().execute(`
|
||||
CREATE TABLE IF NOT EXISTS address_labels (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
color VARCHAR(20) DEFAULT '#1890ff',
|
||||
user_id INT NULL COMMENT '用户ID,NULL表示系统标签',
|
||||
is_system BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
|
||||
// 全国省市区表
|
||||
await getDB().execute(`
|
||||
CREATE TABLE IF NOT EXISTS china_regions (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
code VARCHAR(20) NOT NULL UNIQUE,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
parent_code VARCHAR(20),
|
||||
level TINYINT NOT NULL COMMENT '1:省 2:市 3:区',
|
||||
sort_order INT DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_parent_code (parent_code),
|
||||
INDEX idx_level (level)
|
||||
)
|
||||
`);
|
||||
|
||||
// 匹配订单表
|
||||
await getDB().execute(`
|
||||
CREATE TABLE IF NOT EXISTS matching_orders (
|
||||
@@ -436,8 +541,14 @@ async function addMissingFields() {
|
||||
// 为现有的products表添加字段
|
||||
const productFields = [
|
||||
{ name: 'points_price', sql: 'ALTER TABLE products ADD COLUMN points_price INT NOT NULL DEFAULT 0' },
|
||||
{ name: 'rongdou_price', sql: 'ALTER TABLE products ADD COLUMN rongdou_price INT NOT NULL DEFAULT 0' },
|
||||
{ name: 'image_url', sql: 'ALTER TABLE products ADD COLUMN image_url VARCHAR(500)' },
|
||||
{ name: 'details', sql: 'ALTER TABLE products ADD COLUMN details TEXT' }
|
||||
{ name: 'images', sql: 'ALTER TABLE products ADD COLUMN images JSON' },
|
||||
{ name: 'videos', sql: 'ALTER TABLE products ADD COLUMN videos JSON' },
|
||||
{ name: 'details', sql: 'ALTER TABLE products ADD COLUMN details TEXT' },
|
||||
{ name: 'shop_name', sql: 'ALTER TABLE products ADD COLUMN shop_name VARCHAR(255)' },
|
||||
{ name: 'shop_avatar', sql: 'ALTER TABLE products ADD COLUMN shop_avatar VARCHAR(500)' },
|
||||
{ name: 'payment_methods', sql: 'ALTER TABLE products ADD COLUMN payment_methods JSON' }
|
||||
];
|
||||
|
||||
for (const field of productFields) {
|
||||
@@ -659,6 +770,12 @@ async function createDefaultData() {
|
||||
|
||||
// 初始化浙江省区域数据
|
||||
await initializeZhejiangRegions();
|
||||
|
||||
// 初始化默认地址标签
|
||||
await initializeDefaultAddressLabels();
|
||||
|
||||
// 初始化全国省市区数据
|
||||
await initializeChinaRegions();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -781,10 +898,115 @@ async function initializeZhejiangRegions() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化默认地址标签
|
||||
*/
|
||||
async function initializeDefaultAddressLabels() {
|
||||
const defaultLabels = [
|
||||
{ name: '家', color: '#52c41a' },
|
||||
{ name: '公司', color: '#1890ff' },
|
||||
{ name: '学校', color: '#722ed1' }
|
||||
];
|
||||
|
||||
for (const label of defaultLabels) {
|
||||
try {
|
||||
await getDB().execute(`
|
||||
INSERT IGNORE INTO address_labels (name, color, user_id, is_system)
|
||||
VALUES (?, ?, NULL, TRUE)
|
||||
`, [label.name, label.color]);
|
||||
} catch (error) {
|
||||
console.log(`默认标签${label.name}创建失败:`, error.message);
|
||||
}
|
||||
}
|
||||
console.log('默认地址标签初始化完成');
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化全国省市区数据
|
||||
*/
|
||||
async function initializeChinaRegions() {
|
||||
const regions = [
|
||||
// 省级
|
||||
{ code: '110000', name: '北京市', parent_code: null, level: 1 },
|
||||
{ code: '120000', name: '天津市', parent_code: null, level: 1 },
|
||||
{ code: '130000', name: '河北省', parent_code: null, level: 1 },
|
||||
{ code: '140000', name: '山西省', parent_code: null, level: 1 },
|
||||
{ code: '150000', name: '内蒙古自治区', parent_code: null, level: 1 },
|
||||
{ code: '210000', name: '辽宁省', parent_code: null, level: 1 },
|
||||
{ code: '220000', name: '吉林省', parent_code: null, level: 1 },
|
||||
{ code: '230000', name: '黑龙江省', parent_code: null, level: 1 },
|
||||
{ code: '310000', name: '上海市', parent_code: null, level: 1 },
|
||||
{ code: '320000', name: '江苏省', parent_code: null, level: 1 },
|
||||
{ code: '330000', name: '浙江省', parent_code: null, level: 1 },
|
||||
{ code: '340000', name: '安徽省', parent_code: null, level: 1 },
|
||||
{ code: '350000', name: '福建省', parent_code: null, level: 1 },
|
||||
{ code: '360000', name: '江西省', parent_code: null, level: 1 },
|
||||
{ code: '370000', name: '山东省', parent_code: null, level: 1 },
|
||||
{ code: '410000', name: '河南省', parent_code: null, level: 1 },
|
||||
{ code: '420000', name: '湖北省', parent_code: null, level: 1 },
|
||||
{ code: '430000', name: '湖南省', parent_code: null, level: 1 },
|
||||
{ code: '440000', name: '广东省', parent_code: null, level: 1 },
|
||||
{ code: '450000', name: '广西壮族自治区', parent_code: null, level: 1 },
|
||||
{ code: '460000', name: '海南省', parent_code: null, level: 1 },
|
||||
{ code: '500000', name: '重庆市', parent_code: null, level: 1 },
|
||||
{ code: '510000', name: '四川省', parent_code: null, level: 1 },
|
||||
{ code: '520000', name: '贵州省', parent_code: null, level: 1 },
|
||||
{ code: '530000', name: '云南省', parent_code: null, level: 1 },
|
||||
{ code: '540000', name: '西藏自治区', parent_code: null, level: 1 },
|
||||
{ code: '610000', name: '陕西省', parent_code: null, level: 1 },
|
||||
{ code: '620000', name: '甘肃省', parent_code: null, level: 1 },
|
||||
{ code: '630000', name: '青海省', parent_code: null, level: 1 },
|
||||
{ code: '640000', name: '宁夏回族自治区', parent_code: null, level: 1 },
|
||||
{ code: '650000', name: '新疆维吾尔自治区', parent_code: null, level: 1 },
|
||||
|
||||
// 浙江省市级
|
||||
{ code: '330100', name: '杭州市', parent_code: '330000', level: 2 },
|
||||
{ code: '330200', name: '宁波市', parent_code: '330000', level: 2 },
|
||||
{ code: '330300', name: '温州市', parent_code: '330000', level: 2 },
|
||||
{ code: '330400', name: '嘉兴市', parent_code: '330000', level: 2 },
|
||||
{ code: '330500', name: '湖州市', parent_code: '330000', level: 2 },
|
||||
{ code: '330600', name: '绍兴市', parent_code: '330000', level: 2 },
|
||||
{ code: '330700', name: '金华市', parent_code: '330000', level: 2 },
|
||||
{ code: '330800', name: '衢州市', parent_code: '330000', level: 2 },
|
||||
{ code: '330900', name: '舟山市', parent_code: '330000', level: 2 },
|
||||
{ code: '331000', name: '台州市', parent_code: '330000', level: 2 },
|
||||
{ code: '331100', name: '丽水市', parent_code: '330000', level: 2 },
|
||||
|
||||
// 杭州市区级
|
||||
{ code: '330102', name: '上城区', parent_code: '330100', level: 3 },
|
||||
{ code: '330105', name: '拱墅区', parent_code: '330100', level: 3 },
|
||||
{ code: '330106', name: '西湖区', parent_code: '330100', level: 3 },
|
||||
{ code: '330108', name: '滨江区', parent_code: '330100', level: 3 },
|
||||
{ code: '330109', name: '萧山区', parent_code: '330100', level: 3 },
|
||||
{ code: '330110', name: '余杭区', parent_code: '330100', level: 3 },
|
||||
{ code: '330111', name: '富阳区', parent_code: '330100', level: 3 },
|
||||
{ code: '330112', name: '临安区', parent_code: '330100', level: 3 },
|
||||
{ code: '330113', name: '临平区', parent_code: '330100', level: 3 },
|
||||
{ code: '330114', name: '钱塘区', parent_code: '330100', level: 3 },
|
||||
{ code: '330122', name: '桐庐县', parent_code: '330100', level: 3 },
|
||||
{ code: '330127', name: '淳安县', parent_code: '330100', level: 3 },
|
||||
{ code: '330182', name: '建德市', parent_code: '330100', level: 3 }
|
||||
];
|
||||
|
||||
for (const region of regions) {
|
||||
try {
|
||||
await getDB().execute(`
|
||||
INSERT IGNORE INTO china_regions (code, name, parent_code, level)
|
||||
VALUES (?, ?, ?, ?)
|
||||
`, [region.code, region.name, region.parent_code, region.level]);
|
||||
} catch (error) {
|
||||
console.log(`区域${region.name}创建失败:`, error.message);
|
||||
}
|
||||
}
|
||||
console.log('全国省市区数据初始化完成');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
initDatabase,
|
||||
createTables,
|
||||
addMissingFields,
|
||||
createDefaultData,
|
||||
initializeZhejiangRegions
|
||||
initializeZhejiangRegions,
|
||||
initializeDefaultAddressLabels,
|
||||
initializeChinaRegions
|
||||
};
|
||||
Reference in New Issue
Block a user