Files
PartsInquiry/doc/database_documentation.md
2025-09-18 21:17:44 +08:00

503 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## partsinquiry 数据库文档
更新日期2025-09-16已插入演示数据
说明:本文件根据远程库 mysql.tonaspace.com 中 `partsinquiry` 的实际结构生成,字段/索引/外键信息以线上为准。
### shops
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | 店铺/租户ID |
| name | VARCHAR(100) | NOT NULL | | 店铺名称 |
| status | TINYINT UNSIGNED | NOT NULL | 1 | 状态1启用 0停用 |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_shops_status` (`status`)
### users
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | 用户ID |
| shop_id | BIGINT UNSIGNED | NOT NULL | | 所属店铺 |
| phone | VARCHAR(32) | YES | | 手机号 |
| name | VARCHAR(64) | NOT NULL | | 姓名 |
| role | VARCHAR(32) | NOT NULL | staff | 角色owner/staff/finance/... |
| password_hash | VARCHAR(255) | YES | | 密码哈希(若采用短信登录可为空) |
| status | TINYINT UNSIGNED | NOT NULL | 1 | 状态1启用 0停用 |
| is_owner | TINYINT(1) | NOT NULL | 0 | 是否店主 |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_users_shop` (`shop_id`) - UNIQUE: `ux_users_shop_phone` (`shop_id`,`phone`)
**Foreign Keys**: - `fk_users_shop`: `shop_id``shops(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
### user_identities
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| provider | ENUM('wechat_mp','wechat_app') | NOT NULL | | 身份提供方:小程序/APP |
| openid | VARCHAR(64) | NOT NULL | | |
| unionid | VARCHAR(64) | YES | | |
| nickname | VARCHAR(64) | YES | | |
| avatar_url | VARCHAR(512) | YES | | |
| last_login_at | DATETIME | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_identity_shop` (`shop_id`) - KEY: `idx_identity_user` (`user_id`) - UNIQUE: `ux_identity_provider_openid` (`provider`,`openid`) - UNIQUE: `ux_identity_unionid` (`unionid`)
**Foreign Keys**: - `fk_identity_shop`: `shop_id``shops(id)` ON UPDATE NO ACTION ON DELETE NO ACTION - `fk_identity_user`: `user_id``users(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
### wechat_sessions
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| provider | ENUM('wechat_mp','wechat_app') | NOT NULL | | |
| openid | VARCHAR(64) | NOT NULL | | |
| session_key | VARCHAR(128) | NOT NULL | | |
| expires_at | DATETIME | NOT NULL | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_wechat_session_expires` (`expires_at`) - UNIQUE: `ux_wechat_session` (`provider`,`openid`)
### system_parameters
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | 创建/最后修改人 |
| key | VARCHAR(64) | NOT NULL | | 参数键 |
| value | JSON | NOT NULL | | 参数值JSON |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_sysparams_shop` (`shop_id`) - UNIQUE: `ux_sysparams_shop_key` (`shop_id`,`key`)
**Foreign Keys**: - `fk_sysparams_shop`: `shop_id``shops(id)` ON UPDATE NO ACTION ON DELETE NO ACTION - `fk_sysparams_user`: `user_id``users(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
### product_units
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| name | VARCHAR(16) | NOT NULL | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_units_shop` (`shop_id`) - UNIQUE: `ux_units_shop_name` (`shop_id`,`name`)
**Foreign Keys**: - `fk_units_shop`: `shop_id``shops(id)` ON UPDATE NO ACTION ON DELETE NO ACTION - `fk_units_user`: `user_id``users(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
### global_skus
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| name | VARCHAR(120) | NOT NULL | | SKU名称 |
| brand | VARCHAR(64) | YES | | |
| model | VARCHAR(64) | YES | | |
| spec | VARCHAR(128) | YES | | |
| barcode | VARCHAR(32) | YES | | |
| unit_id | BIGINT UNSIGNED | YES | | |
| tags | JSON | YES | | |
| status | ENUM('published','offline') | NOT NULL | published | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_global_skus_brand_model` (`brand`,`model`) - UNIQUE: `ux_global_skus_barcode` (`barcode`)
**Foreign Keys**: - `fk_globalsku_unit`: `unit_id``product_units(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
### product_categories
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| name | VARCHAR(64) | NOT NULL | | |
| parent_id | BIGINT UNSIGNED | YES | | |
| sort_order | INT | NOT NULL | 0 | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_categories_shop` (`shop_id`) - KEY: `idx_categories_parent` (`parent_id`) - UNIQUE: `ux_categories_shop_name` (`shop_id`,`name`)
**Foreign Keys**: - `fk_categories_shop`: `shop_id``shops(id)` ON UPDATE NO ACTION ON DELETE NO ACTION - `fk_categories_user`: `user_id``users(id)` ON UPDATE NO ACTION ON DELETE NO ACTION - `fk_categories_parent`: `parent_id``product_categories(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
### products
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| name | VARCHAR(120) | NOT NULL | | 供全文检索 |
| category_id | BIGINT UNSIGNED | YES | | |
| unit_id | BIGINT UNSIGNED | NOT NULL | | |
| brand | VARCHAR(64) | YES | | |
| model | VARCHAR(64) | YES | | |
| spec | VARCHAR(128) | YES | | |
| origin | VARCHAR(64) | YES | | |
| barcode | VARCHAR(32) | YES | | |
| alias | VARCHAR(120) | YES | | |
| description | TEXT | YES | | |
| global_sku_id | BIGINT UNSIGNED | YES | | |
| safe_min | DECIMAL(18,3) | YES | | |
| safe_max | DECIMAL(18,3) | YES | | |
| search_text | TEXT | YES | | 供全文检索的聚合字段(名称/品牌/型号/规格/别名) |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_products_shop` (`shop_id`) - KEY: `idx_products_category` (`category_id`) - KEY: `idx_products_unit` (`unit_id`) - FULLTEXT: `ft_products_search` (`name`,`brand`,`model`,`spec`,`search_text`) - UNIQUE: `ux_products_shop_barcode` (`shop_id`,`barcode`)
**Foreign Keys**: - `fk_products_shop`: `shop_id``shops(id)` - `fk_products_user`: `user_id``users(id)` - `fk_products_category`: `category_id``product_categories(id)` - `fk_products_unit`: `unit_id``product_units(id)` - `fk_products_globalsku`: `global_sku_id``global_skus(id)`
### product_aliases
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| product_id | BIGINT UNSIGNED | NOT NULL | | |
| alias | VARCHAR(120) | NOT NULL | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_product_alias_product` (`product_id`) - UNIQUE: `ux_product_alias` (`product_id`,`alias`)
**Foreign Keys**: - `fk_alias_shop`: `shop_id``shops(id)` - `fk_alias_user`: `user_id``users(id)` - `fk_alias_product`: `product_id``products(id)`
### product_images
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| product_id | BIGINT UNSIGNED | NOT NULL | | |
| url | VARCHAR(512) | NOT NULL | | |
| hash | VARCHAR(64) | YES | | 内容哈希(去重) |
| sort_order | INT | NOT NULL | 0 | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_product_images_product` (`product_id`) - UNIQUE: `ux_product_image_hash` (`product_id`,`hash`)
**Foreign Keys**: - `fk_pimg_shop`: `shop_id``shops(id)` - `fk_pimg_user`: `user_id``users(id)` - `fk_pimg_product`: `product_id``products(id)` ON DELETE CASCADE
### product_prices
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| product_id | BIGINT UNSIGNED | NOT NULL | | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| purchase_price | DECIMAL(18,2) | NOT NULL | 0.00 | |
| retail_price | DECIMAL(18,2) | NOT NULL | 0.00 | |
| wholesale_price | DECIMAL(18,2) | NOT NULL | 0.00 | |
| big_client_price | DECIMAL(18,2) | NOT NULL | 0.00 | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `product_id` - KEY: `idx_prices_shop` (`shop_id`)
**Foreign Keys**: - `fk_prices_product`: `product_id``products(id)` ON DELETE CASCADE - `fk_prices_shop`: `shop_id``shops(id)` - `fk_prices_user`: `user_id``users(id)`
### inventories
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| product_id | BIGINT UNSIGNED | NOT NULL | | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| quantity | DECIMAL(18,3) | NOT NULL | 0.000 | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `product_id` - KEY: `idx_inventories_shop` (`shop_id`)
**Foreign Keys**: - `fk_inv_product`: `product_id``products(id)` ON DELETE CASCADE - `fk_inv_shop`: `shop_id``shops(id)` - `fk_inv_user`: `user_id``users(id)`
### customers
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| name | VARCHAR(120) | NOT NULL | | |
| phone | VARCHAR(32) | YES | | 座机 |
| address | VARCHAR(255) | YES | | 送货地址 |
| mobile | VARCHAR(32) | YES | | 手机 |
| level | VARCHAR(32) | YES | | 客户等级标签 |
| contact_name | VARCHAR(64) | YES | | 联系人 |
| price_level | ENUM('零售价','批发价','大单报价') | NOT NULL | 零售价 | 默认售价列(中文存储) |
| status | TINYINT UNSIGNED | NOT NULL | 1 | |
| ar_opening | DECIMAL(18,2) | NOT NULL | 0.00 | 期初应收 |
| remark | VARCHAR(255) | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_customers_shop` (`shop_id`) - KEY: `idx_customers_phone` (`phone`) - KEY: `idx_customers_mobile` (`mobile`)
**Foreign Keys**: - `fk_customers_shop`: `shop_id``shops(id)` - `fk_customers_user`: `user_id``users(id)`
### suppliers
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| name | VARCHAR(120) | NOT NULL | | |
| contact_name | VARCHAR(64) | YES | | 联系人 |
| mobile | VARCHAR(32) | YES | | 手机 |
| phone | VARCHAR(32) | YES | | 电话 |
| address | VARCHAR(255) | YES | | 经营地址 |
| status | TINYINT UNSIGNED | NOT NULL | 1 | |
| ap_opening | DECIMAL(18,2) | NOT NULL | 0.00 | 期初应付 |
| ap_payable | DECIMAL(18,2) | NOT NULL | 0.00 | 当前应付(实时维护) |
| remark | VARCHAR(255) | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_suppliers_shop` (`shop_id`) - KEY: `idx_suppliers_phone` (`phone`) - KEY: `idx_suppliers_mobile` (`mobile`)
**Foreign Keys**: - `fk_suppliers_shop`: `shop_id``shops(id)` - `fk_suppliers_user`: `user_id``users(id)`
### accounts
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| name | VARCHAR(64) | NOT NULL | | |
| type | ENUM('cash','bank','alipay','wechat','other') | NOT NULL | cash | |
| balance | DECIMAL(18,2) | NOT NULL | 0.00 | |
| status | TINYINT UNSIGNED | NOT NULL | 1 | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_accounts_shop` (`shop_id`) - UNIQUE: `ux_accounts_shop_name` (`shop_id`,`name`)
**Foreign Keys**: - `fk_accounts_shop`: `shop_id``shops(id)` - `fk_accounts_user`: `user_id``users(id)`
### sales_orders
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | 创建人 |
| customer_id | BIGINT UNSIGNED | YES | | |
| order_no | VARCHAR(32) | NOT NULL | | |
| order_time | DATETIME | NOT NULL | | |
| status | ENUM('draft','approved','returned','void') | NOT NULL | draft | |
| amount | DECIMAL(18,2) | NOT NULL | 0.00 | 应收合计 |
| paid_amount | DECIMAL(18,2) | NOT NULL | 0.00 | 已收合计 |
| remark | VARCHAR(255) | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_sales_shop_time` (`shop_id`,`order_time`) - KEY: `idx_sales_customer` (`customer_id`) - UNIQUE: `ux_sales_order_no` (`shop_id`,`order_no`)
**Foreign Keys**: - `fk_sales_shop`: `shop_id``shops(id)` - `fk_sales_user`: `user_id``users(id)` - `fk_sales_customer`: `customer_id``customers(id)`
### sales_order_items
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| order_id | BIGINT UNSIGNED | NOT NULL | | |
| product_id | BIGINT UNSIGNED | NOT NULL | | |
| quantity | DECIMAL(18,3) | NOT NULL | | |
| unit_price | DECIMAL(18,2) | NOT NULL | | |
| discount_rate | DECIMAL(5,2) | NOT NULL | 0.00 | 折扣百分比0-100 |
| amount | DECIMAL(18,2) | NOT NULL | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_soi_order` (`order_id`) - KEY: `idx_soi_product` (`product_id`)
**Foreign Keys**: - `fk_soi_order`: `order_id``sales_orders(id)` ON DELETE CASCADE - `fk_soi_product`: `product_id``products(id)`
### purchase_orders
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| supplier_id | BIGINT UNSIGNED | YES | | |
| order_no | VARCHAR(32) | NOT NULL | | |
| order_time | DATETIME | NOT NULL | | |
| status | ENUM('draft','approved','void','returned') | NOT NULL | draft | |
| amount | DECIMAL(18,2) | NOT NULL | 0.00 | 应付合计 |
| paid_amount | DECIMAL(18,2) | NOT NULL | 0.00 | 已付合计 |
| remark | VARCHAR(255) | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_purchase_shop_time` (`shop_id`,`order_time`) - KEY: `idx_purchase_supplier` (`supplier_id`) - UNIQUE: `ux_purchase_order_no` (`shop_id`,`order_no`)
**Foreign Keys**: - `fk_purchase_shop`: `shop_id``shops(id)` - `fk_purchase_user`: `user_id``users(id)` - `fk_purchase_supplier`: `supplier_id``suppliers(id)`
### purchase_order_items
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| order_id | BIGINT UNSIGNED | NOT NULL | | |
| product_id | BIGINT UNSIGNED | NOT NULL | | |
| quantity | DECIMAL(18,3) | NOT NULL | | |
| unit_price | DECIMAL(18,2) | NOT NULL | | |
| amount | DECIMAL(18,2) | NOT NULL | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_poi_order` (`order_id`) - KEY: `idx_poi_product` (`product_id`)
**Foreign Keys**: - `fk_poi_order`: `order_id``purchase_orders(id)` ON DELETE CASCADE - `fk_poi_product`: `product_id``products(id)`
### payments
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| biz_type | ENUM('sale','purchase','other') | NOT NULL | | |
| biz_id | BIGINT UNSIGNED | YES | | 业务表IDsales_orders/purchase_orders/other_transactions |
| account_id | BIGINT UNSIGNED | NOT NULL | | |
| direction | ENUM('in','out') | NOT NULL | | 收款/付款 |
| amount | DECIMAL(18,2) | NOT NULL | | |
| pay_time | DATETIME | NOT NULL | | |
| remark | VARCHAR(255) | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_payments_shop_time` (`shop_id`,`pay_time`) - KEY: `idx_payments_biz` (`biz_type`,`biz_id`)
**Foreign Keys**: - `fk_payments_shop`: `shop_id``shops(id)` - `fk_payments_user`: `user_id``users(id)` - `fk_payments_account`: `account_id``accounts(id)`
### other_transactions
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| type | ENUM('income','expense') | NOT NULL | | |
| category | VARCHAR(64) | NOT NULL | | |
| counterparty_type | VARCHAR(32) | YES | | customer/supplier/other |
| counterparty_id | BIGINT UNSIGNED | YES | | |
| account_id | BIGINT UNSIGNED | NOT NULL | | |
| amount | DECIMAL(18,2) | NOT NULL | | |
| tx_time | DATETIME | NOT NULL | | |
| remark | VARCHAR(255) | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_ot_shop_time` (`shop_id`,`tx_time`) - KEY: `idx_ot_account` (`account_id`)
**Foreign Keys**: - `fk_ot_shop`: `shop_id``shops(id)` - `fk_ot_user`: `user_id``users(id)` - `fk_ot_account`: `account_id``accounts(id)`
### 触发器
- `trg_products_bi`: BEFORE INSERT ON `products` → 设置 `products.search_text`
- `trg_products_au`: BEFORE UPDATE ON `products` → 维护 `products.search_text`
- `trg_palias_ai`: AFTER INSERT ON `product_aliases` → 重建 `products.search_text`
- `trg_palias_au`: AFTER UPDATE ON `product_aliases` → 重建 `products.search_text`
- `trg_palias_ad`: AFTER DELETE ON `product_aliases` → 重建 `products.search_text`
### notices
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| title | VARCHAR(120) | NOT NULL | | |
| content | VARCHAR(500) | NOT NULL | | |
| tag | VARCHAR(32) | YES | | |
| is_pinned | TINYINT(1) | NOT NULL | 0 | |
| starts_at | DATETIME | YES | | |
| ends_at | DATETIME | YES | | |
| status | ENUM('draft','published','offline') | NOT NULL | published | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_notices_shop` (`shop_id`,`status`,`is_pinned`,`created_at`) - KEY: `idx_notices_time` (`starts_at`,`ends_at`)
**Foreign Keys**: - `fk_notices_shop`: `shop_id``shops(id)` ON UPDATE NO ACTION ON DELETE NO ACTION - `fk_notices_user`: `user_id``users(id)` ON UPDATE NO ACTION ON DELETE NO ACTION
### inventory_movements
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| product_id | BIGINT UNSIGNED | NOT NULL | | |
| source_type | VARCHAR(32) | NOT NULL | | sale/purchase/sale_return/purchase_return/adjust |
| source_id | BIGINT UNSIGNED | YES | | 关联单据ID |
| qty_delta | DECIMAL(18,3) | NOT NULL | | 数量增减(正加负减) |
| amount_delta | DECIMAL(18,2) | YES | | 金额变动(可空) |
| reason | VARCHAR(64) | YES | | |
| tx_time | DATETIME | NOT NULL | | |
| remark | VARCHAR(255) | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_im_shop_time` (`shop_id`,`tx_time`) - KEY: `idx_im_product` (`product_id`)
**Foreign Keys**: - `fk_im_shop`: `shop_id``shops(id)` - `fk_im_user`: `user_id``users(id)` - `fk_im_product`: `product_id``products(id)`
### 附:演示种子数据(非完整,仅用于联调验证)
- 演示店铺演示店A用户 3全部店长 owner
- 商品域基础单位3条、类别2条、全局SKU2条、商品2条含别名/价格/库存/图片)
- 往来与账户客户2、供应商2、账户3
- 单据销售单1含明细2与进货单1含明细2、收付款各1、其他收支2
- 审核与公告part_submissions 1、attachments 1、notices 2、新增 wechat 身份与会话各1
### sales_return_orders
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| customer_id | BIGINT UNSIGNED | YES | | |
| order_no | VARCHAR(32) | NOT NULL | | |
| order_time | DATETIME | NOT NULL | | |
| status | ENUM('approved','void') | NOT NULL | approved | |
| amount | DECIMAL(18,2) | NOT NULL | 0.00 | |
| paid_amount | DECIMAL(18,2) | NOT NULL | 0.00 | |
| remark | VARCHAR(255) | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - UNIQUE: `ux_sr_order_no` (`shop_id`,`order_no`) - KEY: `idx_sr_shop_time` (`shop_id`,`order_time`)
**Foreign Keys**: - `fk_sr_shop`: `shop_id``shops(id)` - `fk_sr_user`: `user_id``users(id)` - `fk_sr_customer`: `customer_id``customers(id)`
### sales_return_order_items
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| order_id | BIGINT UNSIGNED | NOT NULL | | |
| product_id | BIGINT UNSIGNED | NOT NULL | | |
| quantity | DECIMAL(18,3) | NOT NULL | | |
| unit_price | DECIMAL(18,2) | NOT NULL | | |
| discount_rate | DECIMAL(5,2) | NOT NULL | 0.00 | |
| amount | DECIMAL(18,2) | NOT NULL | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_sroi_order` (`order_id`) - KEY: `idx_sroi_product` (`product_id`)
**Foreign Keys**: - `fk_sroi_order`: `order_id``sales_return_orders(id)` ON DELETE CASCADE - `fk_sroi_product`: `product_id``products(id)`
### purchase_return_orders
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| shop_id | BIGINT UNSIGNED | NOT NULL | | |
| user_id | BIGINT UNSIGNED | NOT NULL | | |
| supplier_id | BIGINT UNSIGNED | YES | | |
| order_no | VARCHAR(32) | NOT NULL | | |
| order_time | DATETIME | NOT NULL | | |
| status | ENUM('approved','void') | NOT NULL | approved | |
| amount | DECIMAL(18,2) | NOT NULL | 0.00 | |
| paid_amount | DECIMAL(18,2) | NOT NULL | 0.00 | |
| remark | VARCHAR(255) | YES | | |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| deleted_at | DATETIME | YES | | |
**Indexes**: - PRIMARY KEY: `id` - UNIQUE: `ux_pr_order_no` (`shop_id`,`order_no`) - KEY: `idx_pr_shop_time` (`shop_id`,`order_time`)
**Foreign Keys**: - `fk_pr_shop`: `shop_id``shops(id)` - `fk_pr_user`: `user_id``users(id)` - `fk_pr_supplier`: `supplier_id``suppliers(id)`
### purchase_return_order_items
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| order_id | BIGINT UNSIGNED | NOT NULL | | |
| product_id | BIGINT UNSIGNED | NOT NULL | | |
| quantity | DECIMAL(18,3) | NOT NULL | | |
| unit_price | DECIMAL(18,2) | NOT NULL | | |
| amount | DECIMAL(18,2) | NOT NULL | | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_proi_order` (`order_id`) - KEY: `idx_proi_product` (`product_id`)
**Foreign Keys**: - `fk_proi_order`: `order_id``purchase_return_orders(id)` ON DELETE CASCADE - `fk_proi_product`: `product_id``products(id)`