Files
services/config/schema.sql
T

377 lines
22 KiB
SQL
Raw Normal View History

2026-05-23 14:15:45 +08:00
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '分类名称',
`icon` varchar(50) DEFAULT NULL COMMENT '分类图标',
2026-05-26 13:37:55 +08:00
`color` varchar(20) DEFAULT '#1890ff' COMMENT '分类颜色',
2026-05-23 14:15:45 +08:00
`is_show` tinyint(1) DEFAULT 1 COMMENT '是否显示',
`sort_order` int(11) DEFAULT 0 COMMENT '排序顺序',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='商品分类表';
2026-06-05 17:12:06 +08:00
-- 兼容 MySQL < 8.0.29:基于 information_schema 判断后再 ALTER
SET @col_exists = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'categories' AND COLUMN_NAME = 'color');
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `categories` ADD COLUMN `color` varchar(20) DEFAULT ''#1890ff'' COMMENT ''分类颜色''', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2026-05-26 13:37:55 +08:00
2026-05-23 14:15:45 +08:00
CREATE TABLE IF NOT EXISTS `goods` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL COMMENT '商品名称',
`price` decimal(10,2) NOT NULL COMMENT '售价',
`original_price` decimal(10,2) DEFAULT NULL COMMENT '原价',
2026-06-05 17:12:06 +08:00
`cost_price` decimal(10,2) DEFAULT 0 COMMENT '成本价',
2026-05-23 14:15:45 +08:00
`unit` varchar(20) DEFAULT '' COMMENT '单位',
`category_id` int(11) DEFAULT NULL COMMENT '分类ID',
`images` text COMMENT '图片JSON',
`stock` int(11) DEFAULT 0 COMMENT '库存',
`sales` int(11) DEFAULT 0 COMMENT '销量',
`is_hot` tinyint(1) DEFAULT 0 COMMENT '是否热销',
`is_new` tinyint(1) DEFAULT 0 COMMENT '是否新品',
`pricing_type` tinyint(1) DEFAULT 1 COMMENT '定价类型 1-按件 2-按重量',
2026-06-05 17:12:06 +08:00
`goods_no` varchar(64) DEFAULT '' COMMENT '商品货号',
`barcode` varchar(64) DEFAULT '' COMMENT '商品条码',
`is_on_sale` tinyint(1) DEFAULT 1 COMMENT '是否上架 1-上架 0-下架',
2026-05-23 14:15:45 +08:00
`description` text COMMENT '商品描述',
2026-06-05 17:12:06 +08:00
`remark` varchar(500) DEFAULT '' COMMENT '备注',
2026-05-23 14:15:45 +08:00
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `category_id` (`category_id`),
2026-06-05 17:12:06 +08:00
KEY `idx_barcode` (`barcode`),
KEY `idx_goods_no` (`goods_no`),
2026-05-23 14:15:45 +08:00
CONSTRAINT `goods_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='商品表';
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`phone` varchar(20) NOT NULL COMMENT '手机号',
2026-06-04 10:33:58 +08:00
`password` varchar(255) NOT NULL COMMENT '密码(scrypt)',
2026-05-23 14:15:45 +08:00
`name` varchar(100) DEFAULT NULL COMMENT '用户名',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像',
`points` int(11) DEFAULT 0 COMMENT '积分',
2026-06-03 14:15:55 +08:00
`role` tinyint(1) DEFAULT 0 COMMENT '角色 0-普通用户 1-店员 2-管理员',
2026-05-23 14:15:45 +08:00
`status` tinyint(1) DEFAULT 1 COMMENT '状态 1-正常 0-禁用',
2026-05-26 13:37:55 +08:00
`openid` varchar(100) DEFAULT NULL COMMENT '微信openid',
`token` varchar(100) DEFAULT NULL COMMENT '登录token',
2026-05-23 14:15:45 +08:00
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
2026-05-26 13:37:55 +08:00
UNIQUE KEY `phone` (`phone`),
KEY `openid` (`openid`)
2026-05-23 14:15:45 +08:00
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
CREATE TABLE IF NOT EXISTS `orders` (
`id` varchar(50) NOT NULL COMMENT '订单号',
`user_id` int(11) DEFAULT NULL COMMENT '用户ID',
`status` varchar(20) DEFAULT 'pending' COMMENT '状态 pending-待支付 paid-已支付 completed-已完成 cancelled-已取消',
`total_price` decimal(10,2) NOT NULL COMMENT '总价',
`cart` text COMMENT '购物车数据JSON',
`user_info` text COMMENT '用户信息JSON',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单表';
2026-05-26 13:37:55 +08:00
CREATE TABLE IF NOT EXISTS `order_items` (
`id` int NOT NULL AUTO_INCREMENT,
`order_id` varchar(64) NOT NULL COMMENT '订单ID',
`goods_id` int NOT NULL COMMENT '商品ID',
`goods_name` varchar(255) NOT NULL COMMENT '商品名称',
`price` decimal(10,2) NOT NULL COMMENT '单价',
`quantity` int NOT NULL DEFAULT 1 COMMENT '数量',
`weight` decimal(10,2) DEFAULT NULL COMMENT '称重(kg)',
`subtotal` decimal(10,2) NOT NULL COMMENT '小计',
`unit` varchar(20) DEFAULT '' COMMENT '单位',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `order_id` (`order_id`),
KEY `goods_id` (`goods_id`),
CONSTRAINT `order_items_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单商品明细表';
2026-05-23 14:15:45 +08:00
CREATE TABLE IF NOT EXISTS `points_logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '用户ID',
`type` varchar(20) COMMENT '类型 earn-获得 spend-消费',
`amount` int(11) NOT NULL COMMENT '积分数量',
`description` varchar(200) DEFAULT NULL COMMENT '描述',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `points_logs_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='积分记录表';
CREATE TABLE IF NOT EXISTS `stock` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`goods_id` int(11) NOT NULL COMMENT '商品ID',
`quantity` int(11) DEFAULT 0 COMMENT '库存数量',
`warehouse` varchar(50) DEFAULT '默认仓库' COMMENT '仓库',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `goods_id` (`goods_id`),
CONSTRAINT `stock_ibfk_1` FOREIGN KEY (`goods_id`) REFERENCES `goods` (`id`)
2026-05-26 09:18:48 +08:00
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='库存表';
CREATE TABLE IF NOT EXISTS `suppliers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL COMMENT '供应商名称',
`contact` varchar(100) DEFAULT '' COMMENT '联系人',
`phone` varchar(20) DEFAULT '' COMMENT '联系电话',
`address` varchar(500) DEFAULT '' COMMENT '地址',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='供应商表';
CREATE TABLE IF NOT EXISTS `purchases` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`supplier_id` int(11) DEFAULT NULL COMMENT '供应商ID',
`supplier_name` varchar(200) DEFAULT '' COMMENT '供应商名称(冗余)',
`total` decimal(10,2) DEFAULT 0.00 COMMENT '采购总金额',
`status` tinyint(4) DEFAULT 0 COMMENT '状态 0-待入库 1-已入库',
`remarks` text COMMENT '备注',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `supplier_id` (`supplier_id`),
CONSTRAINT `purchases_ibfk_1` FOREIGN KEY (`supplier_id`) REFERENCES `suppliers` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='采购单表';
CREATE TABLE IF NOT EXISTS `purchase_items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`purchase_id` int(11) NOT NULL COMMENT '采购单ID',
`goods_id` int(11) NOT NULL COMMENT '商品ID',
`goods_name` varchar(200) DEFAULT '' COMMENT '商品名称(冗余)',
`quantity` int(11) DEFAULT 0 COMMENT '采购数量',
`purchase_price` decimal(10,2) DEFAULT 0.00 COMMENT '采购单价',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `purchase_id` (`purchase_id`),
KEY `goods_id` (`goods_id`),
CONSTRAINT `purchase_items_ibfk_1` FOREIGN KEY (`purchase_id`) REFERENCES `purchases` (`id`) ON DELETE CASCADE,
CONSTRAINT `purchase_items_ibfk_2` FOREIGN KEY (`goods_id`) REFERENCES `goods` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='采购单明细表';
2026-05-26 13:37:55 +08:00
CREATE TABLE IF NOT EXISTS `goods_specs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`goods_id` int(11) NOT NULL COMMENT '商品ID',
`spec_name` varchar(100) NOT NULL COMMENT '规格名称(如 330ml/500ml/1L',
`price` decimal(10,2) NOT NULL COMMENT '规格售价',
`stock` int(11) DEFAULT 0 COMMENT '规格库存',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `goods_id` (`goods_id`),
CONSTRAINT `goods_specs_ibfk_1` FOREIGN KEY (`goods_id`) REFERENCES `goods` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='商品规格表';
CREATE TABLE IF NOT EXISTS `addresses` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '用户ID',
`name` varchar(100) NOT NULL COMMENT '收货人姓名',
`phone` varchar(20) NOT NULL COMMENT '联系电话',
`region` varchar(200) DEFAULT '' COMMENT '地区',
`detail` varchar(500) NOT NULL COMMENT '详细地址',
`is_default` tinyint(1) DEFAULT 0 COMMENT '是否默认',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `addresses_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='收货地址表';
2026-05-26 09:18:48 +08:00
CREATE TABLE IF NOT EXISTS `points_goods` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL COMMENT '商品名称',
`points` int(11) DEFAULT 0 COMMENT '所需积分',
`stock` int(11) DEFAULT 0 COMMENT '库存',
`image` varchar(500) DEFAULT '' COMMENT '图片',
`description` text COMMENT '描述',
`is_show` tinyint(4) DEFAULT 1 COMMENT '是否显示',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
2026-05-26 13:37:55 +08:00
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='积分商品表';
-- 订单表索引:按状态筛选、按时间排序
2026-06-05 17:12:06 +08:00
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'orders' AND INDEX_NAME = 'idx_orders_status');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `orders` ADD INDEX `idx_orders_status` (`status`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'orders' AND INDEX_NAME = 'idx_orders_created_at');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `orders` ADD INDEX `idx_orders_created_at` (`created_at`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2026-05-26 13:37:55 +08:00
-- 商品表索引:热销/新品筛选、名称搜索
2026-06-05 17:12:06 +08:00
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'goods' AND INDEX_NAME = 'idx_goods_is_hot');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `goods` ADD INDEX `idx_goods_is_hot` (`is_hot`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'goods' AND INDEX_NAME = 'idx_goods_is_new');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `goods` ADD INDEX `idx_goods_is_new` (`is_new`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'goods' AND INDEX_NAME = 'idx_goods_name');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `goods` ADD INDEX `idx_goods_name` (`name`(100))', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2026-05-26 13:37:55 +08:00
2026-06-03 14:15:55 +08:00
-- 商品表新增上下架字段
2026-06-05 17:12:06 +08:00
SET @col_exists = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'goods' AND COLUMN_NAME = 'is_on_sale');
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `goods` ADD COLUMN `is_on_sale` tinyint(1) DEFAULT 1 COMMENT ''是否上架 1-上架 0-下架''', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @col_exists = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'goods' AND COLUMN_NAME = 'cost_price');
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `goods` ADD COLUMN `cost_price` decimal(10,2) DEFAULT 0.00 COMMENT ''进价''', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2026-06-03 14:15:55 +08:00
-- 商品表全文索引:关键词搜索加速 (MySQL 5.7+/8.0)
-- 注意:FULLTEXT 需 MyISAM 或 InnoDB 5.6+;若不支持会被忽略
2026-06-05 17:12:06 +08:00
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'goods' AND INDEX_NAME = 'ft_goods_name_desc');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `goods` ADD FULLTEXT INDEX `ft_goods_name_desc` (`name`, `description`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2026-06-03 14:15:55 +08:00
2026-05-26 13:37:55 +08:00
-- 分类表索引:按排序字段排序
2026-06-05 17:12:06 +08:00
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'categories' AND INDEX_NAME = 'idx_categories_sort_order');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `categories` ADD INDEX `idx_categories_sort_order` (`sort_order`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2026-05-26 13:37:55 +08:00
-- 积分记录表索引:按类型筛选
2026-06-05 17:12:06 +08:00
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'points_logs' AND INDEX_NAME = 'idx_points_logs_type');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `points_logs` ADD INDEX `idx_points_logs_type` (`type`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2026-05-26 13:37:55 +08:00
-- 采购单表索引:按状态筛选、按时间排序
2026-06-05 17:12:06 +08:00
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'purchases' AND INDEX_NAME = 'idx_purchases_status');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `purchases` ADD INDEX `idx_purchases_status` (`status`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'purchases' AND INDEX_NAME = 'idx_purchases_created_at');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `purchases` ADD INDEX `idx_purchases_created_at` (`created_at`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2026-06-03 14:15:55 +08:00
-- 购物车表
CREATE TABLE IF NOT EXISTS `carts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '用户ID',
`goods_id` int(11) NOT NULL COMMENT '商品ID',
`quantity` int(11) NOT NULL DEFAULT 1 COMMENT '数量',
`weight` decimal(10,2) DEFAULT NULL COMMENT '称重(kg)',
`selected` tinyint(1) DEFAULT 1 COMMENT '是否选中',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `user_goods` (`user_id`, `goods_id`),
KEY `user_id` (`user_id`),
KEY `goods_id` (`goods_id`),
CONSTRAINT `carts_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
CONSTRAINT `carts_ibfk_2` FOREIGN KEY (`goods_id`) REFERENCES `goods` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='购物车表';
-- 购物车表索引
2026-06-05 17:12:06 +08:00
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'carts' AND INDEX_NAME = 'idx_carts_user_id');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `carts` ADD INDEX `idx_carts_user_id` (`user_id`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'carts' AND INDEX_NAME = 'idx_carts_selected');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `carts` ADD INDEX `idx_carts_selected` (`selected`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2026-06-03 14:15:55 +08:00
-- 退款表
CREATE TABLE IF NOT EXISTS `refunds` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` varchar(50) NOT NULL COMMENT '订单ID',
`user_id` int(11) NOT NULL COMMENT '用户ID',
`type` tinyint(1) DEFAULT 1 COMMENT '退款类型 1-仅退款 2-退货退款',
`reason` varchar(500) NOT NULL COMMENT '退款原因',
`amount` decimal(10,2) NOT NULL COMMENT '退款金额',
`status` tinyint(1) DEFAULT 0 COMMENT '状态 0-待处理 1-已通过 2-已拒绝',
`admin_remark` varchar(500) DEFAULT NULL COMMENT '管理员备注',
`processed_at` datetime DEFAULT NULL COMMENT '处理时间',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `order_id` (`order_id`),
KEY `user_id` (`user_id`),
KEY `status` (`status`),
CONSTRAINT `refunds_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`),
CONSTRAINT `refunds_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='退款申请表';
-- 退款表索引
2026-06-05 17:12:06 +08:00
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'refunds' AND INDEX_NAME = 'idx_refunds_status');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `refunds` ADD INDEX `idx_refunds_status` (`status`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'refunds' AND INDEX_NAME = 'idx_refunds_created_at');
SET @sql = IF(@idx_exists = 0, 'ALTER TABLE `refunds` ADD INDEX `idx_refunds_created_at` (`created_at`)', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2026-06-03 14:15:55 +08:00
-- 首页分类配置表
CREATE TABLE IF NOT EXISTS `home_categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`category_id` int(11) NOT NULL COMMENT '分类ID',
`sort_order` int(11) DEFAULT 0 COMMENT '排序顺序',
`is_enabled` tinyint(1) DEFAULT 1 COMMENT '是否启用',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `category_id` (`category_id`),
KEY `is_enabled` (`is_enabled`),
KEY `sort_order` (`sort_order`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='首页分类配置表';
-- 首页分类默认数据
INSERT INTO `home_categories` (`category_id`, `sort_order`, `is_enabled`) VALUES
(1, 1, 1),
(10, 2, 1),
(42, 3, 1),
(49, 4, 1),
(37, 5, 1),
(13, 6, 1),
(2, 7, 1),
(5, 8, 1);
-- 库存调整流水表 (P1-D2)
CREATE TABLE IF NOT EXISTS `stock_logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`goods_id` int(11) NOT NULL COMMENT '商品ID',
`change_qty` int(11) NOT NULL COMMENT '变更量 (正=入库/负=出库)',
`before_qty` int(11) NOT NULL COMMENT '变更前库存',
`after_qty` int(11) NOT NULL COMMENT '变更后库存',
`reason` varchar(50) NOT NULL COMMENT '原因: purchase/sale/manual/refund',
`ref_id` varchar(64) DEFAULT NULL COMMENT '关联单据ID(采购单/订单号)',
`operator_id` int(11) DEFAULT NULL COMMENT '操作员ID',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `goods_id` (`goods_id`),
KEY `reason` (`reason`),
KEY `created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='库存流水表';
-- token 黑名单 (服务端 logout 强制失效)
CREATE TABLE IF NOT EXISTS `token_blacklist` (
`jti` varchar(64) NOT NULL COMMENT 'JWT ID',
`user_id` int(11) NOT NULL COMMENT '用户ID',
`expired_at` datetime NOT NULL COMMENT '原 token 过期时间',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`jti`),
KEY `user_id` (`user_id`),
KEY `expired_at` (`expired_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='JWT 黑名单';
-- AI 调用限流与缓存
CREATE TABLE IF NOT EXISTS `ai_cache` (
`key_hash` char(64) NOT NULL COMMENT '请求 hash',
`response` text NOT NULL COMMENT '响应体',
`hits` int(11) DEFAULT 1,
`expires_at` datetime NOT NULL,
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`key_hash`),
KEY `expires_at` (`expires_at`)
2026-06-05 16:24:40 +08:00
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='AI 响应缓存';
-- 迁移:order_items.order_id 从 int 改为 varchar(64),与 orders.id (varchar(50)) 保持一致
2026-06-05 17:12:06 +08:00
SET @fk_exists = (SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = DATABASE() AND TABLE_NAME = 'order_items' AND CONSTRAINT_NAME = 'order_items_ibfk_1');
SET @sql = IF(@fk_exists > 0, 'ALTER TABLE `order_items` DROP FOREIGN KEY `order_items_ibfk_1`', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2026-06-05 16:24:40 +08:00
ALTER TABLE `order_items` MODIFY COLUMN `order_id` varchar(64) NOT NULL COMMENT '订单ID';
2026-06-05 17:12:06 +08:00
SET @fk_exists = (SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = DATABASE() AND TABLE_NAME = 'order_items' AND CONSTRAINT_NAME = 'order_items_ibfk_1');
SET @sql = IF(@fk_exists = 0, 'ALTER TABLE `order_items` ADD CONSTRAINT `order_items_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE', 'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;