# 跨平台ERP系统核心数据模型设计 ## 1. 数据模型概述 本设计文档详细描述了跨平台ERP系统的核心数据模型,包括客户、供应商、分包商、项目、合同、付款节点、财务记录、商品、汇率管理等数据模型,确保数据模型之间的关系正确,支持财务串通管理和多币种功能。 ## 2. 核心数据模型设计 ### 2.1 基础数据模型 #### 2.1.1 用户表 (users) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 用户ID | | `username` | `VARCHAR(255)` | `UNIQUE NOT NULL` | 用户名 | | `password` | `VARCHAR(255)` | `NOT NULL` | 密码哈希 | | `name` | `VARCHAR(255)` | `NOT NULL` | 姓名 | | `email` | `VARCHAR(255)` | `UNIQUE NOT NULL` | 邮箱 | | `role_id` | `UUID` | `REFERENCES roles(id)` | 角色ID | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.1.2 角色表 (roles) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 角色ID | | `name` | `VARCHAR(255)` | `UNIQUE NOT NULL` | 角色名称 | | `description` | `TEXT` | | 角色描述 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.1.3 权限表 (permissions) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 权限ID | | `name` | `VARCHAR(255)` | `UNIQUE NOT NULL` | 权限名称 | | `description` | `TEXT` | | 权限描述 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.1.4 角色权限关联表 (role_permissions) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `role_id` | `UUID` | `REFERENCES roles(id)` | 角色ID | | `permission_id` | `UUID` | `REFERENCES permissions(id)` | 权限ID | | `PRIMARY KEY` | | `(role_id, permission_id)` | 复合主键 | ### 2.2 业务数据模型 #### 2.2.1 客户表 (customers) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 客户ID | | `name` | `VARCHAR(255)` | `NOT NULL` | 客户名称 | | `contact_person` | `VARCHAR(255)` | | 联系人 | | `phone` | `VARCHAR(50)` | | 电话 | | `email` | `VARCHAR(255)` | | 邮箱 | | `address` | `TEXT` | | 地址 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.2.2 供应商表 (suppliers) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 供应商ID | | `name` | `VARCHAR(255)` | `NOT NULL` | 供应商名称 | | `contact_person` | `VARCHAR(255)` | | 联系人 | | `phone` | `VARCHAR(50)` | | 电话 | | `email` | `VARCHAR(255)` | | 邮箱 | | `address` | `TEXT` | | 地址 | | `type` | `VARCHAR(50)` | | 类型: 本地/中国 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.2.3 分包商表 (subcontractors) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 分包商ID | | `name` | `VARCHAR(255)` | `NOT NULL` | 分包商名称 | | `contact_person` | `VARCHAR(255)` | | 联系人 | | `phone` | `VARCHAR(50)` | | 电话 | | `email` | `VARCHAR(255)` | | 邮箱 | | `address` | `TEXT` | | 地址 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.2.4 项目表 (projects) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 项目ID | | `name` | `VARCHAR(255)` | `NOT NULL` | 项目名称 | | `customer_id` | `UUID` | `REFERENCES customers(id)` | 客户ID | | `contract_number` | `VARCHAR(100)` | `UNIQUE NOT NULL` | 合同编号 | | `contract_amount` | `DECIMAL(18,2)` | `NOT NULL` | 合同金额 | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `rmb_equivalent` | `DECIMAL(18,2)` | `NOT NULL` | 人民币等价金额 | | `start_date` | `DATE` | | 开始日期 | | `end_date` | `DATE` | | 结束日期 | | `status` | `VARCHAR(50)` | `NOT NULL` | 状态 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.2.5 合同表 (contracts) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 合同ID | | `project_id` | `UUID` | `REFERENCES projects(id)` | 项目ID | | `type` | `VARCHAR(50)` | `NOT NULL` | 合同类型: 主合同/分包合同/采购合同 | | `contract_number` | `VARCHAR(100)` | `UNIQUE NOT NULL` | 合同编号 | | `contract_amount` | `DECIMAL(18,2)` | `NOT NULL` | 合同金额 | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `rmb_equivalent` | `DECIMAL(18,2)` | `NOT NULL` | 人民币等价金额 | | `start_date` | `DATE` | | 开始日期 | | `end_date` | `DATE` | | 结束日期 | | `status` | `VARCHAR(50)` | `NOT NULL` | 状态 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.2.6 付款节点表 (payment_terms) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 付款节点ID | | `contract_id` | `UUID` | `REFERENCES contracts(id)` | 合同ID | | `sequence` | `INTEGER` | `NOT NULL` | 付款顺序 | | `description` | `TEXT` | `NOT NULL` | 付款描述 | | `percentage` | `DECIMAL(5,2)` | `NOT NULL` | 付款比例 | | `amount` | `DECIMAL(18,2)` | `NOT NULL` | 付款金额 | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `rmb_equivalent` | `DECIMAL(18,2)` | `NOT NULL` | 人民币等价金额 | | `due_date` | `DATE` | | 到期日期 | | `status` | `VARCHAR(50)` | `NOT NULL` | 状态 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.2.7 商品分类表 (product_categories) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 分类ID | | `name` | `VARCHAR(255)` | `NOT NULL` | 分类名称 | | `parent_id` | `UUID` | `REFERENCES product_categories(id)` | 父分类ID | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.2.8 商品表 (products) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 商品ID | | `name` | `VARCHAR(255)` | `NOT NULL` | 商品名称 | | `category_id` | `UUID` | `REFERENCES product_categories(id)` | 分类ID | | `unit` | `VARCHAR(50)` | `NOT NULL` | 单位 | | `cost_price` | `DECIMAL(18,2)` | | 成本价 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.2.9 采购表 (purchases) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 采购ID | | `project_id` | `UUID` | `REFERENCES projects(id)` | 项目ID | | `supplier_id` | `UUID` | `REFERENCES suppliers(id)` | 供应商ID | | `contract_id` | `UUID` | `REFERENCES contracts(id)` | 合同ID | | `total_amount` | `DECIMAL(18,2)` | `NOT NULL` | 总金额 | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `rmb_equivalent` | `DECIMAL(18,2)` | `NOT NULL` | 人民币等价金额 | | `expected_delivery_date` | `DATE` | | 预计发货日期 | | `status` | `VARCHAR(50)` | `NOT NULL` | 状态 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.2.10 采购商品表 (purchase_items) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 采购商品ID | | `purchase_id` | `UUID` | `REFERENCES purchases(id)` | 采购ID | | `product_id` | `UUID` | `REFERENCES products(id)` | 商品ID | | `quantity` | `DECIMAL(18,2)` | `NOT NULL` | 数量 | | `unit_price` | `DECIMAL(18,2)` | `NOT NULL` | 单价 | | `total_price` | `DECIMAL(18,2)` | `NOT NULL` | 总价 | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `rmb_equivalent` | `DECIMAL(18,2)` | `NOT NULL` | 人民币等价金额 | #### 2.2.11 分包表 (subcontracts) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 分包ID | | `project_id` | `UUID` | `REFERENCES projects(id)` | 项目ID | | `subcontractor_id` | `UUID` | `REFERENCES subcontractors(id)` | 分包商ID | | `contract_id` | `UUID` | `REFERENCES contracts(id)` | 合同ID | | `total_amount` | `DECIMAL(18,2)` | `NOT NULL` | 总金额 | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `rmb_equivalent` | `DECIMAL(18,2)` | `NOT NULL` | 人民币等价金额 | | `status` | `VARCHAR(50)` | `NOT NULL` | 状态 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.2.12 预算报价表 (quotations) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 预算报价ID | | `customer_id` | `UUID` | `REFERENCES customers(id)` | 客户ID | | `project_name` | `VARCHAR(255)` | `NOT NULL` | 项目名称 | | `total_amount` | `DECIMAL(18,2)` | `NOT NULL` | 总金额 | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `rmb_equivalent` | `DECIMAL(18,2)` | `NOT NULL` | 人民币等价金额 | | `status` | `VARCHAR(50)` | `NOT NULL` | 状态 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.2.13 预算报价项目表 (quotation_items) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 预算报价项目ID | | `quotation_id` | `UUID` | `REFERENCES quotations(id)` | 预算报价ID | | `product_id` | `UUID` | `REFERENCES products(id)` | 商品ID | | `quantity` | `DECIMAL(18,2)` | `NOT NULL` | 数量 | | `unit_price` | `DECIMAL(18,2)` | `NOT NULL` | 单价 | | `total_price` | `DECIMAL(18,2)` | `NOT NULL` | 总价 | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `rmb_equivalent` | `DECIMAL(18,2)` | `NOT NULL` | 人民币等价金额 | ### 2.3 财务数据模型 #### 2.3.1 汇率表 (exchange_rates) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 汇率ID | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `rate` | `DECIMAL(18,6)` | `NOT NULL` | 汇率(1单位外币兑人民币) | | `reverse_rate` | `DECIMAL(18,6)` | `NOT NULL` | 反向汇率(1人民币兑外币) | | `effective_date` | `DATE` | `NOT NULL` | 生效日期 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.3.2 财务记录表 (financial_records) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 财务记录ID | | `type` | `VARCHAR(50)` | `NOT NULL` | 类型: 收入/支出 | | `amount` | `DECIMAL(18,2)` | `NOT NULL` | 金额 | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `rmb_equivalent` | `DECIMAL(18,2)` | `NOT NULL` | 人民币等价金额 | | `project_id` | `UUID` | `REFERENCES projects(id)` | 项目ID(可为空) | | `related_id` | `UUID` | | 关联ID(关联具体业务) | | `related_type` | `VARCHAR(50)` | | 关联类型 | | `payment_term_id` | `UUID` | `REFERENCES payment_terms(id)` | 付款节点ID | | `status` | `VARCHAR(50)` | `NOT NULL` | 状态 | | `description` | `TEXT` | | 描述 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.3.3 银行账户表 (bank_accounts) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 银行账户ID | | `name` | `VARCHAR(255)` | `NOT NULL` | 账户名称 | | `bank_name` | `VARCHAR(255)` | `NOT NULL` | 银行名称 | | `account_number` | `VARCHAR(100)` | `UNIQUE NOT NULL` | 账号 | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `balance` | `DECIMAL(18,2)` | `DEFAULT 0` | 余额 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | #### 2.3.4 财务交易表 (financial_transactions) | 字段名 | 数据类型 | 约束 | 描述 | | :--- | :--- | :--- | :--- | | `id` | `UUID` | `PRIMARY KEY` | 交易ID | | `financial_record_id` | `UUID` | `REFERENCES financial_records(id)` | 财务记录ID | | `bank_account_id` | `UUID` | `REFERENCES bank_accounts(id)` | 银行账户ID | | `amount` | `DECIMAL(18,2)` | `NOT NULL` | 交易金额 | | `currency` | `VARCHAR(10)` | `NOT NULL` | 币种 | | `transaction_date` | `DATE` | `NOT NULL` | 交易日期 | | `transaction_type` | `VARCHAR(50)` | `NOT NULL` | 交易类型: 转入/转出 | | `created_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 | | `updated_at` | `TIMESTAMP` | `DEFAULT CURRENT_TIMESTAMP` | 更新时间 | ## 3. 数据模型关系图 ```mermaid erDiagram %% 基础数据模型 users ||--o{ roles : "has" roles ||--o{ role_permissions : "has" permissions ||--o{ role_permissions : "has" %% 业务数据模型 customers ||--o{ projects : "has" customers ||--o{ quotations : "has" suppliers ||--o{ purchases : "has" subcontractors ||--o{ subcontracts : "has" projects ||--o{ contracts : "has" projects ||--o{ purchases : "has" projects ||--o{ subcontracts : "has" projects ||--o{ financial_records : "has" contracts ||--o{ payment_terms : "has" product_categories ||--o{ products : "has" products ||--o{ purchase_items : "has" products ||--o{ quotation_items : "has" purchases ||--o{ purchase_items : "has" quotations ||--o{ quotation_items : "has" payment_terms ||--o{ financial_records : "has" %% 财务数据模型 exchange_rates ||--o{ financial_records : "used by" bank_accounts ||--o{ financial_transactions : "has" financial_records ||--o{ financial_transactions : "has" ``` ## 4. 数据模型设计说明 ### 4.1 多币种支持 1. **汇率管理**: 通过`exchange_rates`表管理不同币种的汇率,支持人民币、老挝基普、泰铢、美元等多种币种。 2. **币种字段**: 所有涉及金额的表都包含`currency`字段,记录交易的原始币种。 3. **人民币等价金额**: 所有金额字段都包含`rmb_equivalent`字段,记录该金额按照当时汇率换算成人民币的等价金额,便于财务统计和分析。 4. **汇率换算**: 系统在创建财务记录时,会根据`exchange_rates`表中的最新汇率自动计算人民币等价金额。 ### 4.2 财务串通管理 1. **统一财务视图**: 通过`financial_records`表集中管理所有财务交易,确保所有收入支出既能从单个项目查看,又能从公司总账目中查看。 2. **关联关系**: 通过`related_id`和`related_type`字段关联具体业务,如合同、付款节点等。 3. **项目维度**: 通过`project_id`字段实现项目级财务视图,便于项目成本核算和利润分析。 4. **公司维度**: 不设置`project_id`的记录为公司级财务,如日常办公支出等。 5. **银行账户管理**: 通过`bank_accounts`和`financial_transactions`表管理银行账户和具体交易,实现资金流向的跟踪。 ### 4.3 数据一致性 1. **外键约束**: 所有关联关系都通过外键约束确保数据一致性。 2. **事务管理**: 重要业务操作(如财务交易)使用事务确保数据一致性。 3. **数据验证**: 在应用层实现数据验证,确保数据的完整性和准确性。 ### 4.4 性能优化 1. **索引设计**: 对常用查询字段(如`project_id`、`customer_id`、`created_at`等)创建索引,提高查询性能。 2. **分区策略**: 对于大型表(如`financial_records`),考虑使用分区策略,按时间或项目进行分区。 3. **缓存机制**: 对于频繁访问的数据(如汇率),使用缓存机制提高访问速度。 ## 5. 总结 本数据模型设计涵盖了跨平台ERP系统的核心数据模型,包括客户、供应商、分包商、项目、合同、付款节点、财务记录、商品、汇率管理等数据模型。通过合理的关系设计和字段定义,确保了数据模型之间的关系正确,支持财务串通管理和多币种功能。 该设计考虑了系统的可扩展性和性能优化,为后续功能扩展预留了接口,能够满足企业的业务需求,并为企业的财务管理提供有力支持。