9099c4af99
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
573 lines
30 KiB
SQL
573 lines
30 KiB
SQL
-- ============================================================
|
||
-- 酒水仓库管理系统 数据库 Schema
|
||
-- MySQL 8.0+
|
||
-- 说明:所有业务表含 shop_id 实现多租户隔离
|
||
-- ============================================================
|
||
|
||
SET NAMES utf8mb4;
|
||
SET FOREIGN_KEY_CHECKS = 0;
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 门店(租户)
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `shops` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`name` VARCHAR(100) NOT NULL COMMENT '门店名称',
|
||
`code` VARCHAR(50) NOT NULL COMMENT '门店编号(唯一)',
|
||
`address` VARCHAR(255) DEFAULT NULL,
|
||
`phone` VARCHAR(30) DEFAULT NULL,
|
||
`manager_name` VARCHAR(50) DEFAULT NULL COMMENT '负责人',
|
||
`description` TEXT DEFAULT NULL COMMENT '店铺简介',
|
||
`logo_url` VARCHAR(500) DEFAULT '' COMMENT '门店 logo URL',
|
||
`business_license` VARCHAR(500) DEFAULT NULL COMMENT '营业执照照片URL',
|
||
`shop_photos` JSON DEFAULT NULL COMMENT '门店照片URL数组',
|
||
`custom_fields` JSON DEFAULT NULL COMMENT '扩展字段',
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_code` (`code`),
|
||
KEY `idx_deleted_at` (`deleted_at`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='门店(租户)';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 用户(操作人员)
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `users` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`username` VARCHAR(50) NOT NULL,
|
||
`password_hash` VARCHAR(255) NOT NULL COMMENT 'bcrypt',
|
||
`real_name` VARCHAR(50) DEFAULT NULL,
|
||
`phone` VARCHAR(30) DEFAULT NULL,
|
||
`role` ENUM('admin','operator','readonly','superadmin') NOT NULL DEFAULT 'operator',
|
||
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
||
`last_login_at` DATETIME DEFAULT NULL COMMENT '最近登录时间',
|
||
`custom_fields` JSON DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_shop_username` (`shop_id`, `username`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_deleted_at` (`deleted_at`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 登录会话(支持登出/踢人/在线状态监控;JWT 的 sid claim 指向此表)
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `user_sessions` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`user_id` BIGINT UNSIGNED NOT NULL,
|
||
`sid` VARCHAR(64) NOT NULL COMMENT '嵌入 JWT 的会话标识',
|
||
`device_id` VARCHAR(255) DEFAULT NULL,
|
||
`device_name` VARCHAR(255) DEFAULT NULL,
|
||
`platform` VARCHAR(50) DEFAULT NULL COMMENT 'windows|macos|linux|android|ios|web',
|
||
`platform_class` VARCHAR(20) DEFAULT NULL COMMENT 'desktop|mobile|web',
|
||
`ip` VARCHAR(64) DEFAULT NULL,
|
||
`user_agent` VARCHAR(512) DEFAULT NULL,
|
||
`refresh_jti` VARCHAR(64) DEFAULT NULL COMMENT '当前有效 refresh token 的 jti,用于轮换+重用检测',
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`last_seen_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`revoked_at` DATETIME DEFAULT NULL,
|
||
`revoked_reason` VARCHAR(30) DEFAULT NULL COMMENT 'kicked|logout|admin|disabled|reuse|pwd_reset',
|
||
`revoked_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '吊销操作人 user_id;系统/自助吊销为 NULL',
|
||
`refresh_exp_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_session_sid` (`sid`),
|
||
KEY `idx_session_shop_user` (`shop_id`, `user_id`),
|
||
KEY `idx_session_class` (`platform_class`),
|
||
KEY `idx_session_revoked` (`revoked_at`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='登录会话';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 登录尝试审计(当前只记失败尝试,用于风控/排查;由保留期清理任务定期删旧)
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `login_attempts` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_code` VARCHAR(64) DEFAULT NULL,
|
||
`username` VARCHAR(50) DEFAULT NULL,
|
||
`ip` VARCHAR(64) DEFAULT NULL,
|
||
`user_agent` VARCHAR(512) DEFAULT NULL,
|
||
`success` TINYINT(1) NOT NULL DEFAULT 0,
|
||
`reason` VARCHAR(40) DEFAULT NULL COMMENT 'invalid_shop|invalid_user|bad_password|locked|inactive|platform_not_allowed',
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_attempt_user` (`username`, `created_at`),
|
||
KEY `idx_attempt_ip` (`ip`, `created_at`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='登录尝试审计';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 许可证
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `licenses` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`license_key` VARCHAR(768) NOT NULL COMMENT 'Ed25519 signed token',
|
||
`device_id` VARCHAR(255) DEFAULT NULL COMMENT 'deprecated: use license_devices',
|
||
`type` ENUM('trial','monthly','annual','lifetime') NOT NULL DEFAULT 'trial',
|
||
`tier` VARCHAR(32) NOT NULL DEFAULT 'standard' COMMENT '权益档位钩子(pro/max-like),当前默认 standard',
|
||
`expires_at` DATETIME DEFAULT NULL COMMENT 'NULL=永久',
|
||
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
||
`max_devices` INT NOT NULL DEFAULT 3 COMMENT '最大绑定设备数',
|
||
`features` JSON DEFAULT NULL COMMENT '功能开关 {"finance":true}',
|
||
`activated_at` DATETIME DEFAULT NULL COMMENT 'deprecated',
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_license_key` (`license_key`),
|
||
KEY `idx_shop_id` (`shop_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许可证';
|
||
|
||
CREATE TABLE IF NOT EXISTS `license_devices` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`license_id` BIGINT UNSIGNED NOT NULL,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`device_id` VARCHAR(255) NOT NULL,
|
||
`device_name` VARCHAR(255) DEFAULT NULL,
|
||
`platform` VARCHAR(50) DEFAULT NULL COMMENT 'windows|macos|android|ios|web',
|
||
`activated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`last_seen_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_license_device` (`license_id`, `device_id`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_license_id` (`license_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许可证设备绑定';
|
||
|
||
-- 兑换券(激活码)码池:平台方批量生成,用户兑换后叠加时长到门店授权
|
||
CREATE TABLE IF NOT EXISTS `license_codes` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`code` VARCHAR(32) NOT NULL COMMENT '归一化大写无连字符',
|
||
`type` ENUM('trial','monthly','annual','lifetime') NOT NULL DEFAULT 'annual' COMMENT '计费/时长标签',
|
||
`tier` VARCHAR(32) NOT NULL DEFAULT 'standard' COMMENT '档位钩子(pro/max-like),当前默认 standard',
|
||
`duration_days` INT NOT NULL DEFAULT 0 COMMENT '授予时长;0=永久(lifetime)',
|
||
`max_devices` INT NOT NULL DEFAULT 0 COMMENT '授予设备上限;0=不改变现值',
|
||
`status` ENUM('unused','redeemed','void') NOT NULL DEFAULT 'unused',
|
||
`redeemed_shop_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '被哪个门店兑换',
|
||
`redeemed_at` DATETIME DEFAULT NULL,
|
||
`redeemed_device_id` VARCHAR(255) DEFAULT NULL COMMENT '兑换设备(审计)',
|
||
`batch` VARCHAR(64) DEFAULT NULL COMMENT '发放批次/活动名',
|
||
`note` VARCHAR(255) DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_code` (`code`),
|
||
KEY `idx_status` (`status`),
|
||
KEY `idx_redeemed_shop` (`redeemed_shop_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='兑换券码池';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 商品分类
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `product_categories` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`name` VARCHAR(100) NOT NULL,
|
||
`parent_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '父分类,支持二级',
|
||
`sort_order` INT NOT NULL DEFAULT 0,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_shop_id` (`shop_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品分类';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 商品
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `products` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`code` VARCHAR(50) DEFAULT NULL COMMENT '商品编号',
|
||
`barcode` VARCHAR(100) DEFAULT NULL COMMENT '条码',
|
||
`name` VARCHAR(200) NOT NULL COMMENT '商品名称',
|
||
`series` VARCHAR(100) DEFAULT NULL COMMENT '系列',
|
||
`spec` VARCHAR(100) DEFAULT NULL COMMENT '规格',
|
||
`unit` VARCHAR(20) DEFAULT NULL COMMENT '单位',
|
||
`category_id` BIGINT UNSIGNED DEFAULT NULL,
|
||
`brand` VARCHAR(100) DEFAULT NULL COMMENT '品牌',
|
||
`purchase_price` DECIMAL(16,2) DEFAULT NULL COMMENT '参考进价',
|
||
`sale_price` DECIMAL(16,2) DEFAULT NULL COMMENT '参考售价',
|
||
`public_id` CHAR(36) NOT NULL DEFAULT '' COMMENT 'UUID,公开URL使用',
|
||
`min_stock` INT DEFAULT 0 COMMENT '库存预警值',
|
||
`description` TEXT DEFAULT NULL COMMENT '商品描述',
|
||
`custom_fields` JSON DEFAULT NULL COMMENT '动态扩展字段',
|
||
`remark` VARCHAR(500) DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_category` (`category_id`),
|
||
KEY `idx_deleted_at` (`deleted_at`),
|
||
UNIQUE KEY `uk_product_code` (`shop_id`, `code`),
|
||
UNIQUE KEY `uk_public_id` (`public_id`),
|
||
FULLTEXT KEY `ft_name` (`name`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 商品图片
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `product_images` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`product_id` BIGINT UNSIGNED NOT NULL,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`url` VARCHAR(500) NOT NULL COMMENT '相对路径,如 /images/products/1/xxx.jpg',
|
||
`sort_order` INT NOT NULL DEFAULT 0,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_product_id` (`product_id`),
|
||
KEY `idx_shop_id` (`shop_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品图片';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 仓库
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `warehouses` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`name` VARCHAR(100) NOT NULL,
|
||
`location` VARCHAR(200) DEFAULT NULL,
|
||
`is_default` TINYINT(1) NOT NULL DEFAULT 0,
|
||
`custom_fields` JSON DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_shop_id` (`shop_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='仓库';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 往来单位(供应商/客户)
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `partners` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`code` VARCHAR(50) DEFAULT NULL,
|
||
`name` VARCHAR(200) NOT NULL,
|
||
`name_pinyin` VARCHAR(400) DEFAULT NULL COMMENT '名称全拼(搜索用,写入时自动生成)',
|
||
`name_initials` VARCHAR(100) DEFAULT NULL COMMENT '名称拼音首字母(搜索用)',
|
||
`type` SET('supplier','customer') NOT NULL DEFAULT 'supplier' COMMENT '可同时是供应商和客户',
|
||
`contact` VARCHAR(50) DEFAULT NULL COMMENT '联系人',
|
||
`phone` VARCHAR(30) DEFAULT NULL,
|
||
`address` VARCHAR(255) DEFAULT NULL,
|
||
`bank_account` VARCHAR(100) DEFAULT NULL COMMENT '银行账号',
|
||
`status` ENUM('enabled','disabled') NOT NULL DEFAULT 'enabled' COMMENT '正常/禁用',
|
||
`custom_fields` JSON DEFAULT NULL,
|
||
`remark` VARCHAR(500) DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_deleted_at` (`deleted_at`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='往来单位';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 入库单
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `stock_in_orders` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`order_no` VARCHAR(50) NOT NULL COMMENT '入库单号',
|
||
`type` VARCHAR(30) NOT NULL DEFAULT 'purchase' COMMENT '入库类型: purchase采购/return退货/other其他',
|
||
`warehouse_id` BIGINT UNSIGNED NOT NULL,
|
||
`partner_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '供应商',
|
||
`operator_id` BIGINT UNSIGNED NOT NULL COMMENT '经办人',
|
||
`creator_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '制单人',
|
||
`reviewer_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '审核人',
|
||
`status` ENUM('draft','pending','approved','rejected') NOT NULL DEFAULT 'draft',
|
||
`order_date` DATE NOT NULL,
|
||
`total_amount` DECIMAL(16,2) NOT NULL DEFAULT 0,
|
||
`reviewed_at` DATETIME DEFAULT NULL,
|
||
`custom_fields` JSON DEFAULT NULL,
|
||
`remark` VARCHAR(500) DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_order_no` (`shop_id`, `order_no`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_warehouse` (`warehouse_id`),
|
||
KEY `idx_order_date` (`order_date`),
|
||
KEY `idx_status` (`status`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='入库单';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 入库单明细
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `stock_in_items` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`order_id` BIGINT UNSIGNED NOT NULL,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`product_id` BIGINT UNSIGNED NOT NULL,
|
||
`product_code` VARCHAR(50) DEFAULT NULL COMMENT '商品编号(源流水号,历史导入)',
|
||
`product_name` VARCHAR(255) DEFAULT NULL COMMENT '商品名称(历史导入快照)',
|
||
`series` VARCHAR(100) DEFAULT NULL COMMENT '系列(历史导入快照)',
|
||
`spec` VARCHAR(100) DEFAULT NULL COMMENT '规格(历史导入快照)',
|
||
`quantity` DECIMAL(12,3) NOT NULL COMMENT '数量',
|
||
`unit_price` DECIMAL(16,2) NOT NULL DEFAULT 0 COMMENT '单价',
|
||
`total_price` DECIMAL(16,2) NOT NULL DEFAULT 0,
|
||
`batch_no` VARCHAR(50) DEFAULT NULL COMMENT '批次号',
|
||
`production_date` DATE DEFAULT NULL COMMENT '生产日期',
|
||
`expire_date` DATE DEFAULT NULL COMMENT '有效期',
|
||
`custom_fields` JSON DEFAULT NULL,
|
||
`remark` VARCHAR(255) DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_order_id` (`order_id`),
|
||
KEY `idx_shop_product` (`shop_id`, `product_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='入库单明细';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 出库单
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `stock_out_orders` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`order_no` VARCHAR(50) NOT NULL,
|
||
`type` VARCHAR(30) NOT NULL DEFAULT 'sale' COMMENT 'sale销售/return退货/other其他',
|
||
`warehouse_id` BIGINT UNSIGNED NOT NULL,
|
||
`partner_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '客户',
|
||
`operator_id` BIGINT UNSIGNED NOT NULL,
|
||
`creator_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '制单人',
|
||
`reviewer_id` BIGINT UNSIGNED DEFAULT NULL,
|
||
`status` ENUM('draft','pending','approved','rejected') NOT NULL DEFAULT 'draft',
|
||
`order_date` DATE NOT NULL,
|
||
`total_amount` DECIMAL(16,2) NOT NULL DEFAULT 0,
|
||
`reviewed_at` DATETIME DEFAULT NULL,
|
||
`custom_fields` JSON DEFAULT NULL,
|
||
`remark` VARCHAR(500) DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_order_no` (`shop_id`, `order_no`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_warehouse` (`warehouse_id`),
|
||
KEY `idx_order_date` (`order_date`),
|
||
KEY `idx_status` (`status`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='出库单';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 出库单明细
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `stock_out_items` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`order_id` BIGINT UNSIGNED NOT NULL,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`product_id` BIGINT UNSIGNED NOT NULL,
|
||
`product_code` VARCHAR(50) DEFAULT NULL COMMENT '商品编号(源流水号,历史导入)',
|
||
`product_name` VARCHAR(255) DEFAULT NULL COMMENT '商品名称(历史导入快照)',
|
||
`series` VARCHAR(100) DEFAULT NULL COMMENT '系列(历史导入快照)',
|
||
`spec` VARCHAR(100) DEFAULT NULL COMMENT '规格(历史导入快照)',
|
||
`quantity` DECIMAL(12,3) NOT NULL,
|
||
`unit_price` DECIMAL(16,2) NOT NULL DEFAULT 0 COMMENT '成本单价(入库成本快照)',
|
||
`sale_price` DECIMAL(16,2) NOT NULL DEFAULT 0 COMMENT '售价(出库实际销售单价,应收按售价×数量)',
|
||
`total_price` DECIMAL(16,2) NOT NULL DEFAULT 0 COMMENT '成本小计(unit_price×quantity)',
|
||
`batch_no` VARCHAR(50) DEFAULT NULL COMMENT '批次号',
|
||
`production_date` DATE DEFAULT NULL COMMENT '生产日期',
|
||
`custom_fields` JSON DEFAULT NULL,
|
||
`remark` VARCHAR(255) DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_order_id` (`order_id`),
|
||
KEY `idx_shop_product` (`shop_id`, `product_id`),
|
||
KEY `idx_so_items_shop_code` (`shop_id`, `product_code`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='出库单明细';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 库存(批次模式:每条记录代表一个批次/入库批)
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `inventories` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`warehouse_id` BIGINT UNSIGNED DEFAULT NULL,
|
||
`product_id` BIGINT UNSIGNED DEFAULT NULL,
|
||
`stock_in_item_id` BIGINT UNSIGNED DEFAULT NULL,
|
||
`inventory_check_id` BIGINT UNSIGNED DEFAULT NULL,
|
||
`quantity` DECIMAL(12,3) NOT NULL DEFAULT 0,
|
||
`product_code` VARCHAR(50) DEFAULT NULL,
|
||
`product_name` VARCHAR(200) DEFAULT NULL,
|
||
`series` VARCHAR(100) DEFAULT NULL,
|
||
`spec` VARCHAR(100) DEFAULT NULL,
|
||
`unit` VARCHAR(20) DEFAULT NULL,
|
||
`warehouse_name` VARCHAR(100) DEFAULT NULL,
|
||
`unit_price` DECIMAL(16,2) DEFAULT NULL,
|
||
`production_date` DATE DEFAULT NULL,
|
||
`batch_no` VARCHAR(50) DEFAULT NULL,
|
||
`supplier_name` VARCHAR(200) DEFAULT NULL,
|
||
`remark` VARCHAR(500) DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_fifo` (`shop_id`, `warehouse_id`, `product_id`, `created_at`),
|
||
KEY `idx_shop_wh_product` (`shop_id`, `warehouse_id`, `product_id`),
|
||
KEY `idx_stock_in_item` (`stock_in_item_id`),
|
||
KEY `idx_inventory_check` (`inventory_check_id`),
|
||
KEY `idx_deleted_at` (`deleted_at`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='库存批次记录';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 库存流水(出入库记录明细)
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `inventory_logs` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`warehouse_id` BIGINT UNSIGNED NOT NULL,
|
||
`product_id` BIGINT UNSIGNED NOT NULL,
|
||
`direction` ENUM('in','out') NOT NULL,
|
||
`quantity` DECIMAL(12,3) NOT NULL,
|
||
`qty_before` DECIMAL(12,3) NOT NULL COMMENT '变动前数量',
|
||
`qty_after` DECIMAL(12,3) NOT NULL COMMENT '变动后数量',
|
||
`ref_type` VARCHAR(30) NOT NULL COMMENT 'stock_in/stock_out/check',
|
||
`ref_id` BIGINT UNSIGNED NOT NULL COMMENT '关联单据ID',
|
||
`operator_id` BIGINT UNSIGNED DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_shop_product` (`shop_id`, `product_id`),
|
||
KEY `idx_ref` (`ref_type`, `ref_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='库存流水';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 库存盘点
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `inventory_checks` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`check_no` VARCHAR(50) NOT NULL,
|
||
`warehouse_id` BIGINT UNSIGNED NOT NULL,
|
||
`operator_id` BIGINT UNSIGNED NOT NULL,
|
||
`status` ENUM('draft','completed') NOT NULL DEFAULT 'draft',
|
||
`check_date` DATE NOT NULL,
|
||
`remark` VARCHAR(500) DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_check_no` (`shop_id`, `check_no`),
|
||
KEY `idx_shop_id` (`shop_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='库存盘点单';
|
||
|
||
CREATE TABLE IF NOT EXISTS `inventory_check_items` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`check_id` BIGINT UNSIGNED NOT NULL,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`product_id` BIGINT UNSIGNED NOT NULL,
|
||
`system_qty` DECIMAL(12,3) NOT NULL COMMENT '系统数量',
|
||
`actual_qty` DECIMAL(12,3) NOT NULL COMMENT '实际盘点数量',
|
||
`diff_qty` DECIMAL(12,3) GENERATED ALWAYS AS (`actual_qty` - `system_qty`) STORED COMMENT '差异',
|
||
`remark` VARCHAR(255) DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_check_id` (`check_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='盘点明细';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 财务流水
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `finance_records` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`partner_id` BIGINT UNSIGNED DEFAULT NULL,
|
||
`type` ENUM('receivable','payable','receipt','payment') NOT NULL COMMENT '应收/应付/收款/付款',
|
||
`amount` DECIMAL(16,2) NOT NULL,
|
||
`balance` DECIMAL(16,2) NOT NULL COMMENT '操作后余额',
|
||
`status` ENUM('open','closed') NOT NULL DEFAULT 'open' COMMENT '结清状态(payable/receivable 有效)',
|
||
`ref_type` VARCHAR(30) DEFAULT NULL COMMENT '关联单据类型',
|
||
`ref_id` BIGINT UNSIGNED DEFAULT NULL,
|
||
`operator_id` BIGINT UNSIGNED NOT NULL,
|
||
`record_date` DATE NOT NULL,
|
||
`custom_fields` JSON DEFAULT NULL,
|
||
`remark` VARCHAR(500) DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_partner` (`partner_id`),
|
||
KEY `idx_record_date` (`record_date`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='财务流水';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 编号规则配置
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `number_rules` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`type` VARCHAR(30) NOT NULL COMMENT 'stock_in/stock_out/check',
|
||
`prefix` VARCHAR(20) DEFAULT '' COMMENT '前缀',
|
||
`current_no` INT NOT NULL DEFAULT 0 COMMENT '当前序号',
|
||
`date_format` VARCHAR(20) DEFAULT 'YYYYMMDD' COMMENT '日期格式',
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_shop_type` (`shop_id`, `type`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='单号规则';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 基础数据选项
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `product_name_options` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`code` VARCHAR(50) DEFAULT NULL COMMENT '选项编号',
|
||
`name` VARCHAR(200) NOT NULL COMMENT '名称',
|
||
`remark` VARCHAR(500) DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_deleted_at` (`deleted_at`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品名称选项';
|
||
|
||
CREATE TABLE IF NOT EXISTS `product_series_options` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`code` VARCHAR(50) DEFAULT NULL COMMENT '选项编号',
|
||
`name` VARCHAR(200) NOT NULL COMMENT '系列名称',
|
||
`remark` VARCHAR(500) DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_deleted_at` (`deleted_at`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品系列选项';
|
||
|
||
CREATE TABLE IF NOT EXISTS `product_spec_options` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`code` VARCHAR(50) DEFAULT NULL COMMENT '选项编号',
|
||
`name` VARCHAR(200) NOT NULL COMMENT '规格名称',
|
||
`quantity` INT DEFAULT 0 COMMENT '单品数量',
|
||
`remark` VARCHAR(500) DEFAULT NULL,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`deleted_at` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_deleted_at` (`deleted_at`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品规格选项';
|
||
|
||
CREATE TABLE IF NOT EXISTS `feedbacks` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`shop_id` BIGINT UNSIGNED NOT NULL,
|
||
`shop_code` VARCHAR(50) DEFAULT NULL,
|
||
`user_id` BIGINT UNSIGNED DEFAULT NULL,
|
||
`username` VARCHAR(50) DEFAULT NULL,
|
||
`role` VARCHAR(20) DEFAULT NULL,
|
||
`type` VARCHAR(20) NOT NULL COMMENT 'bug / suggestion',
|
||
`content` TEXT,
|
||
`images` JSON,
|
||
`app_version` VARCHAR(30) DEFAULT NULL,
|
||
`platform` VARCHAR(20) DEFAULT NULL,
|
||
`client_ip` VARCHAR(60) DEFAULT NULL,
|
||
`status` VARCHAR(20) NOT NULL DEFAULT 'new',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_shop_id` (`shop_id`),
|
||
KEY `idx_user_id` (`user_id`),
|
||
KEY `idx_type` (`type`),
|
||
KEY `idx_status` (`status`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户意见反馈';
|
||
|
||
SET FOREIGN_KEY_CHECKS = 1;
|