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 '分类图标', `color` varchar(20) DEFAULT '#1890ff' COMMENT '分类颜色', `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='商品分类表'; ALTER TABLE `categories` ADD COLUMN IF NOT EXISTS `color` varchar(20) DEFAULT '#1890ff' COMMENT '分类颜色'; 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 '原价', `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-按重量', `description` text 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`), 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 '手机号', `password` varchar(255) NOT NULL COMMENT '密码(scrypt)', `name` varchar(100) DEFAULT NULL COMMENT '用户名', `avatar` varchar(255) DEFAULT NULL COMMENT '头像', `points` int(11) DEFAULT 0 COMMENT '积分', `role` tinyint(1) DEFAULT 0 COMMENT '角色 0-普通用户 1-店员 2-管理员', `status` tinyint(1) DEFAULT 1 COMMENT '状态 1-正常 0-禁用', `openid` varchar(100) DEFAULT NULL COMMENT '微信openid', `token` varchar(100) DEFAULT NULL COMMENT '登录token', `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `phone` (`phone`), KEY `openid` (`openid`) ) 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='订单表'; 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='订单商品明细表'; 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`) ) 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='采购单明细表'; 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='收货地址表'; 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`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='积分商品表'; -- 订单表索引:按状态筛选、按时间排序 ALTER TABLE `orders` ADD INDEX IF NOT EXISTS `idx_orders_status` (`status`); ALTER TABLE `orders` ADD INDEX IF NOT EXISTS `idx_orders_created_at` (`created_at`); -- 商品表索引:热销/新品筛选、名称搜索 ALTER TABLE `goods` ADD INDEX IF NOT EXISTS `idx_goods_is_hot` (`is_hot`); ALTER TABLE `goods` ADD INDEX IF NOT EXISTS `idx_goods_is_new` (`is_new`); ALTER TABLE `goods` ADD INDEX IF NOT EXISTS `idx_goods_name` (`name`(100)); -- 商品表新增上下架字段 ALTER TABLE `goods` ADD COLUMN IF NOT EXISTS `is_on_sale` tinyint(1) DEFAULT 1 COMMENT '是否上架 1-上架 0-下架'; ALTER TABLE `goods` ADD COLUMN IF NOT EXISTS `cost_price` decimal(10,2) DEFAULT 0.00 COMMENT '进价'; -- 商品表全文索引:关键词搜索加速 (MySQL 5.7+/8.0) -- 注意:FULLTEXT 需 MyISAM 或 InnoDB 5.6+;若不支持会被忽略 ALTER TABLE `goods` ADD FULLTEXT INDEX IF NOT EXISTS `ft_goods_name_desc` (`name`, `description`); -- 分类表索引:按排序字段排序 ALTER TABLE `categories` ADD INDEX IF NOT EXISTS `idx_categories_sort_order` (`sort_order`); -- 积分记录表索引:按类型筛选 ALTER TABLE `points_logs` ADD INDEX IF NOT EXISTS `idx_points_logs_type` (`type`); -- 采购单表索引:按状态筛选、按时间排序 ALTER TABLE `purchases` ADD INDEX IF NOT EXISTS `idx_purchases_status` (`status`); ALTER TABLE `purchases` ADD INDEX IF NOT EXISTS `idx_purchases_created_at` (`created_at`); -- 购物车表 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='购物车表'; -- 购物车表索引 ALTER TABLE `carts` ADD INDEX IF NOT EXISTS `idx_carts_user_id` (`user_id`); ALTER TABLE `carts` ADD INDEX IF NOT EXISTS `idx_carts_selected` (`selected`); -- 退款表 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='退款申请表'; -- 退款表索引 ALTER TABLE `refunds` ADD INDEX IF NOT EXISTS `idx_refunds_status` (`status`); ALTER TABLE `refunds` ADD INDEX IF NOT EXISTS `idx_refunds_created_at` (`created_at`); -- 首页分类配置表 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`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='AI 响应缓存';