Files
PartsInquiry/doc/database_documentation.md
Wdp-ab 562ec4abf9 后端:公告√
注意数据库新建notice表
2025-09-16 20:03:17 +08:00

402 lines
22 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 | |
| distribution_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 | | |
| level | VARCHAR(32) | YES | | 客户等级标签 |
| price_level | ENUM('retail','distribution','wholesale','big_client') | NOT NULL | retail | 默认售价列 |
| status | TINYINT UNSIGNED | NOT NULL | 1 | |
| 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`)
**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 | | |
| phone | VARCHAR(32) | YES | | |
| status | TINYINT UNSIGNED | NOT NULL | 1 | |
| 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`)
**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') | 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)`
### product_images 触发器
- `trg_products_ai`: AFTER 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