Files
PartsInquiry/doc/database_documentation.md
2025-09-24 20:35:15 +08:00

512 lines
26 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-23已插入演示数据新增演示店B/演示店C与其默认账户、两名用户
说明:本文件根据远程库 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 | | |
字段说明:
- id: 主键,自增
- name: 店铺名称
- status: 店铺状态1启用/0停用
- created_at/updated_at: 创建/更新时间
- deleted_at: 逻辑删除时间
### 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 | 是否店主 |
| is_platform_admin | 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: `uk_users_phone` (`phone`) - UNIQUE: `ux_users_shop_phone` (`shop_id`,`phone`)
字段说明:
- shop_id: 归属店铺
- role: 角色标识字符串
- is_owner: 是否店主标记
- is_platform_admin: 是否平台管理员(平台级权限)
- 其余同名含义
### 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 | |
说明:当前 `user_identities` 仅支持微信身份;短信登录采用 `users.phone` 作为全局唯一身份,不新增 identity 记录。
### sms_codes
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| id | BIGINT UNSIGNED | NOT NULL | AUTO_INCREMENT | |
| phone | VARCHAR(32) | NOT NULL | | 手机号 |
| scene | VARCHAR(32) | NOT NULL | login | 场景,默认为 login |
| code_hash | CHAR(64) | NOT NULL | | 验证码哈希SHA-256|
| salt | CHAR(32) | NOT NULL | | 加盐字符串 |
| expire_at | DATETIME | NOT NULL | | 过期时间 |
| status | TINYINT UNSIGNED | NOT NULL | 0 | 0=active,1=used,2=expired,3=blocked |
| fail_count | TINYINT UNSIGNED | NOT NULL | 0 | 错误次数 |
| ip | VARCHAR(45) | YES | | 发送IP |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_phone_created_at` (`phone`,`created_at`) - KEY: `idx_phone_scene_status` (`phone`,`scene`,`status`) - KEY: `idx_expire_at` (`expire_at`) - KEY: `idx_ip_created_at` (`ip`,`created_at`)
字段说明:
- provider: wechat_mp小程序、wechat_appAPP
- openid/unionid: 微信身份标识
### vip_users
| 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 | | 用户 |
| is_vip | TINYINT(1) | NOT NULL | 1 | 是否VIP1是 0否 |
| status | TINYINT UNSIGNED | NOT NULL | 0 | 启用状态1启用 0停用审核通过后启用 |
| expire_at | DATETIME | YES | | 到期时间 |
| remark | VARCHAR(255) | YES | | 备注/审核说明 |
| reviewer_id | BIGINT UNSIGNED | YES | | 审核人 |
| reviewed_at | DATETIME | YES | | 审核时间 |
| created_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
| updated_at | TIMESTAMP | NOT NULL | CURRENT_TIMESTAMP | |
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_vu_shop_user` (`shop_id`,`user_id`) - KEY: `idx_vu_shop_status` (`shop_id`,`status`)
**Foreign Keys**: - `fk_vu_shop`: `shop_id``shops(id)` - `fk_vu_user`: `user_id``users(id)` - `fk_vu_reviewer`: `reviewer_id``users(id)`
### vip_price
| Column Name | Data Type | Nullable | Default | Comment |
| ----------- | --------- | -------- | ------- | ------- |
| price | DECIMAL(10,2) | NOT NULL | | 全局价格(仅一条记录) |
说明:该表为全局配置表,仅包含一条记录用于表示当前 VIP 单月价格。
### 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 | |
字段说明:
- session_key/expires_at: 会话密钥与过期时间
### 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 | |
字段说明:
- key/value: 键/值JSON
### 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 | | |
字段说明product_units
- name: 单位名称,如 件/个/箱
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_units_shop` (`shop_id`) - UNIQUE: `ux_units_shop_name` (`shop_id`,`name`)
全局字典约定方案A
-`shop_id=0` 作为“全局字典库”的承载店铺(不对应真实租户)。
- 单位接口 `/api/product-units` 始终返回 `shop_id=0` 的记录;新建/修改/删除仅写入 `shop_id=0`
- 兼容历史:不强制迁移既有数据,各店已有单位保留。
**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 | | |
字段说明global_skus
- name/brand/model/spec/barcode: SKU 基本属性
- unit_id: 对应的计量单位
- tags: 结构化标签 JSON
- status: 上架状态published/offline
**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 | | |
字段说明product_categories
- parent_id: 父分类,可为空
- sort_order: 排序
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_categories_shop` (`shop_id`) - KEY: `idx_categories_parent` (`parent_id`) - UNIQUE: `ux_categories_shop_name` (`shop_id`,`name`)
全局字典约定方案A
- 类别接口 `/api/product-categories` 始终返回 `shop_id=0` 的记录;新建/修改/删除仅写入 `shop_id=0`
- 历史上各店铺已存在的基础项,后续逐步收敛至 `shop_id=0` 字典;为兼容引用,暂不强制删除。
**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 | | |
| is_blacklisted | TINYINT(1) | NOT NULL | 0 | 黑名单标记(管理端可控) |
| 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 | | |
字段说明products
- category_id/unit_id/global_sku_id: 归属分类/单位/全局SKU
- safe_min/safe_max: 安全库存上下限
- search_text: 聚合检索字段(触发器维护)
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_products_shop` (`shop_id`) - KEY: `idx_products_category` (`category_id`) - KEY: `idx_products_unit` (`unit_id`) - KEY: `idx_products_shop_blacklist` (`shop_id`,`is_blacklisted`) - 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 | | |
字段说明product_aliases
- alias: 商品别名(同义词)
**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 | |
字段说明product_images
- url/hash: 图片地址/内容哈希
- sort_order: 展示顺序
**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 | |
字段说明product_prices
- purchase_price: 当前进价(用于近似毛利)
- retail/wholesale/big_client_price: 售价列
**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 | |
字段说明inventories
- quantity: 当前库存数量(按商品一行聚合)
**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 | | |
字段说明customers
- level: 等级标签
- price_level: 默认售价列(中文存储:零售价/批发价/大单报价)
- ar_opening: 期初应收
**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 | | |
字段说明suppliers
- ap_opening/ap_payable: 期初应付/当前应付
**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 | |
| bank_name | VARCHAR(64) | YES | | 银行名称type=bank 可用) |
| bank_account | VARCHAR(64) | YES | | 银行账号type=bank 可用) |
| 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 | | |
字段说明accounts
- type: 账户类型cash/bank/alipay/wechat/other
- bank_name/bank_account: 银行账户信息type=bank 时使用)
**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 | | |
字段说明sales_orders
- status: 单据状态draft/approved/returned/void
- amount/paid_amount: 应收/已收合计
**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 | | |
字段说明sales_order_items
- quantity/unit_price/discount_rate/amount: 数量/单价/折扣%/行金额
**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 | | |
字段说明purchase_orders/purchase_order_items
- 与销售单结构类似,含应付与明细
**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)`
image.png
### 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 | |
字段说明payments
- biz_type/biz_id: 业务来源及关联主键
- direction: in 收款 / out 付款
- account_id: 使用的结算账户
**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 | | |
字段说明other_transactions
- type/category: 收入/支出与分类
- counterparty_type/id: 往来单位(可空)
**Indexes**: - PRIMARY KEY: `id` - KEY: `idx_ot_shop_time`