640 lines
19 KiB
SQL
640 lines
19 KiB
SQL
SET client_encoding = 'UTF8';
|
|
|
|
-- ============================================================
|
|
-- 云海财务系统 - PostgreSQL 完整表结构
|
|
-- ============================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id SERIAL PRIMARY KEY,
|
|
username VARCHAR(255) UNIQUE,
|
|
name VARCHAR(255),
|
|
email VARCHAR(255),
|
|
phone VARCHAR(255),
|
|
role VARCHAR(50),
|
|
avatar TEXT,
|
|
passport TEXT,
|
|
driver_license TEXT,
|
|
password_hash VARCHAR(255),
|
|
is_active BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS customers (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255),
|
|
address VARCHAR(255),
|
|
remark TEXT,
|
|
contact_person VARCHAR(255),
|
|
phone VARCHAR(255),
|
|
email VARCHAR(255),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS projects (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255),
|
|
project_code VARCHAR(255),
|
|
customer_id INTEGER REFERENCES customers(id),
|
|
project_manager_id INTEGER REFERENCES users(id),
|
|
contract_amount NUMERIC,
|
|
start_date DATE,
|
|
end_date DATE,
|
|
description TEXT,
|
|
status VARCHAR(50) DEFAULT 'planning',
|
|
location VARCHAR(255),
|
|
type_template_id INTEGER,
|
|
current_phase VARCHAR(50),
|
|
phase_progress NUMERIC(5,2) DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS contacts (
|
|
id SERIAL PRIMARY KEY,
|
|
entity_id INTEGER NOT NULL,
|
|
entity_type VARCHAR(50) NOT NULL,
|
|
name VARCHAR(255),
|
|
position VARCHAR(255),
|
|
phone VARCHAR(255),
|
|
is_primary INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS suppliers (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
address TEXT,
|
|
contact_person VARCHAR(255),
|
|
phone VARCHAR(255),
|
|
email VARCHAR(255),
|
|
product_category VARCHAR(255),
|
|
supplier_source VARCHAR(100),
|
|
supply_category TEXT,
|
|
country TEXT,
|
|
remark TEXT,
|
|
status TEXT DEFAULT 'active',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS supplier_payment_infos (
|
|
id SERIAL PRIMARY KEY,
|
|
supplier_id INTEGER REFERENCES suppliers(id) ON DELETE CASCADE,
|
|
account_name TEXT,
|
|
bank_account TEXT,
|
|
bank_name TEXT,
|
|
qr_code TEXT,
|
|
is_primary INTEGER DEFAULT 0,
|
|
is_default BOOLEAN DEFAULT false,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS subcontractors (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
address TEXT,
|
|
contact_person VARCHAR(255),
|
|
phone VARCHAR(255),
|
|
email VARCHAR(255),
|
|
specialty TEXT,
|
|
category TEXT,
|
|
country TEXT,
|
|
remark TEXT,
|
|
score INTEGER DEFAULT 100,
|
|
initial_score INTEGER DEFAULT 100,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS subcontractor_payment_infos (
|
|
id SERIAL PRIMARY KEY,
|
|
subcontractor_id INTEGER REFERENCES subcontractors(id) ON DELETE CASCADE,
|
|
account_name TEXT,
|
|
bank_name TEXT,
|
|
bank_account TEXT,
|
|
qr_code TEXT,
|
|
is_primary INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS customer_payment_infos (
|
|
id SERIAL PRIMARY KEY,
|
|
customer_id INTEGER REFERENCES customers(id) ON DELETE CASCADE,
|
|
account_name TEXT,
|
|
bank_name TEXT,
|
|
bank_account TEXT,
|
|
qr_code TEXT,
|
|
is_primary INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS product_categories (
|
|
id SERIAL PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
parent_id INTEGER REFERENCES product_categories(id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS products (
|
|
id SERIAL PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
model TEXT,
|
|
category_id INTEGER REFERENCES product_categories(id),
|
|
category_name TEXT,
|
|
unit TEXT DEFAULT '件',
|
|
cost_price REAL,
|
|
price REAL DEFAULT 0,
|
|
brand TEXT,
|
|
specification TEXT,
|
|
source TEXT DEFAULT '老挝',
|
|
remark TEXT,
|
|
stock_quantity REAL DEFAULT 0,
|
|
stock_warning REAL DEFAULT 0,
|
|
status TEXT DEFAULT 'active',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS exchange_rates (
|
|
id SERIAL PRIMARY KEY,
|
|
currency_code TEXT NOT NULL,
|
|
to_currency_code TEXT NOT NULL,
|
|
rate REAL NOT NULL,
|
|
effective_date DATE NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS advances (
|
|
id SERIAL PRIMARY KEY,
|
|
applicant_id INTEGER REFERENCES users(id),
|
|
project_id INTEGER REFERENCES projects(id),
|
|
amount REAL NOT NULL DEFAULT 0,
|
|
currency TEXT DEFAULT 'CNY',
|
|
amount_cny REAL DEFAULT 0,
|
|
reason TEXT,
|
|
advance_date DATE,
|
|
advance_code TEXT UNIQUE,
|
|
status TEXT DEFAULT 'pending',
|
|
applicant TEXT,
|
|
attachments TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS reimbursements (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER REFERENCES users(id),
|
|
project_id INTEGER REFERENCES projects(id),
|
|
amount REAL NOT NULL DEFAULT 0,
|
|
currency TEXT DEFAULT 'CNY',
|
|
amount_cny REAL DEFAULT 0,
|
|
reason TEXT,
|
|
reimbursement_date DATE,
|
|
reimbursement_code TEXT UNIQUE,
|
|
status TEXT DEFAULT 'pending',
|
|
applicant TEXT,
|
|
expense_type TEXT,
|
|
detail_items TEXT,
|
|
attachments TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS payment_requests (
|
|
id SERIAL PRIMARY KEY,
|
|
request_code TEXT UNIQUE,
|
|
applicant TEXT,
|
|
payment_date DATE,
|
|
payee TEXT,
|
|
bank_account TEXT,
|
|
bank_name TEXT,
|
|
amount REAL DEFAULT 0,
|
|
currency TEXT DEFAULT 'CNY',
|
|
reason TEXT,
|
|
status TEXT DEFAULT 'pending',
|
|
detail_items TEXT,
|
|
attachments TEXT,
|
|
payee_type TEXT,
|
|
payee_id INTEGER,
|
|
expense_type TEXT DEFAULT 'company',
|
|
expense_category TEXT,
|
|
project_id INTEGER REFERENCES projects(id),
|
|
purchase_request_id INTEGER,
|
|
purchase_order_id INTEGER,
|
|
payment_type TEXT DEFAULT 'company',
|
|
logistics_company_id INTEGER,
|
|
logistics_document_url TEXT,
|
|
driver_phone TEXT,
|
|
cargo_weight REAL,
|
|
transport_distance REAL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS verifications (
|
|
id SERIAL PRIMARY KEY,
|
|
advance_id INTEGER REFERENCES advances(id),
|
|
amount REAL DEFAULT 0,
|
|
currency TEXT DEFAULT 'CNY',
|
|
reason TEXT,
|
|
verification_date DATE,
|
|
verification_code TEXT UNIQUE,
|
|
status TEXT DEFAULT 'pending',
|
|
applicant TEXT,
|
|
advance_code TEXT,
|
|
advance_amount REAL,
|
|
detail_items TEXT,
|
|
attachments TEXT,
|
|
expense_type TEXT,
|
|
project_id INTEGER REFERENCES projects(id),
|
|
settlement TEXT,
|
|
settlement_amount REAL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS executions (
|
|
id SERIAL PRIMARY KEY,
|
|
apply_id INTEGER,
|
|
apply_type TEXT,
|
|
action TEXT,
|
|
execute_method TEXT,
|
|
voucher_no TEXT,
|
|
remark TEXT,
|
|
reject_reason TEXT,
|
|
voucher_files TEXT,
|
|
operator TEXT,
|
|
operator_role TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS purchase_requests (
|
|
id SERIAL PRIMARY KEY,
|
|
request_code TEXT UNIQUE NOT NULL,
|
|
project_id INTEGER NOT NULL REFERENCES projects(id),
|
|
applicant TEXT,
|
|
request_date DATE,
|
|
supplier_id INTEGER REFERENCES suppliers(id),
|
|
supplier_name TEXT,
|
|
expense_category TEXT,
|
|
purchase_type TEXT DEFAULT 'inventory',
|
|
total_amount REAL NOT NULL DEFAULT 0,
|
|
currency TEXT DEFAULT 'CNY',
|
|
status TEXT DEFAULT 'pending',
|
|
remark TEXT,
|
|
remarks TEXT,
|
|
brief_description TEXT,
|
|
attachments TEXT,
|
|
expected_date DATE,
|
|
execute_date DATE,
|
|
execute_method TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS purchase_request_items (
|
|
id SERIAL PRIMARY KEY,
|
|
purchase_request_id INTEGER NOT NULL REFERENCES purchase_requests(id) ON DELETE CASCADE,
|
|
product_id INTEGER REFERENCES products(id),
|
|
product_name TEXT NOT NULL,
|
|
specification TEXT,
|
|
unit TEXT,
|
|
quantity REAL NOT NULL DEFAULT 0,
|
|
unit_price REAL NOT NULL DEFAULT 0,
|
|
total_price REAL NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS purchase_orders (
|
|
id SERIAL PRIMARY KEY,
|
|
code TEXT UNIQUE NOT NULL,
|
|
purchase_request_id INTEGER REFERENCES purchase_requests(id),
|
|
project_id INTEGER REFERENCES projects(id),
|
|
supplier_id INTEGER REFERENCES suppliers(id),
|
|
supplier_country TEXT DEFAULT 'Laos',
|
|
currency TEXT DEFAULT 'CNY',
|
|
status TEXT DEFAULT 'draft',
|
|
estimated_amount REAL DEFAULT 0,
|
|
paid_amount REAL DEFAULT 0,
|
|
contract_url TEXT,
|
|
quotation_url TEXT,
|
|
actual_delivery_date DATE,
|
|
expected_delivery_date DATE,
|
|
receiving_status VARCHAR(20) DEFAULT 'pending',
|
|
remark TEXT,
|
|
created_by TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS purchase_order_items (
|
|
id SERIAL PRIMARY KEY,
|
|
order_id INTEGER NOT NULL REFERENCES purchase_orders(id) ON DELETE CASCADE,
|
|
product_id INTEGER REFERENCES products(id),
|
|
product_name TEXT,
|
|
specification TEXT,
|
|
unit TEXT,
|
|
quantity REAL DEFAULT 0,
|
|
unit_price REAL DEFAULT 0,
|
|
total_price REAL DEFAULT 0,
|
|
received_quantity REAL DEFAULT 0,
|
|
verified_quantity REAL DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS payment_plans (
|
|
id SERIAL PRIMARY KEY,
|
|
purchase_order_id INTEGER REFERENCES purchase_orders(id),
|
|
project_id INTEGER REFERENCES projects(id),
|
|
plan_name TEXT,
|
|
stage TEXT,
|
|
planned_date DATE,
|
|
planned_amount REAL,
|
|
planned_percentage REAL,
|
|
actual_amount REAL DEFAULT 0,
|
|
actual_date DATE,
|
|
payment_request_id INTEGER,
|
|
reminder_days INTEGER DEFAULT 3,
|
|
amount REAL DEFAULT 0,
|
|
due_date DATE,
|
|
status TEXT DEFAULT 'pending',
|
|
remark TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS payment_nodes (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER REFERENCES projects(id),
|
|
name TEXT,
|
|
amount REAL DEFAULT 0,
|
|
due_date DATE,
|
|
status TEXT DEFAULT 'pending',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS payment_records (
|
|
id SERIAL PRIMARY KEY,
|
|
node_id INTEGER REFERENCES payment_nodes(id),
|
|
amount REAL DEFAULT 0,
|
|
payment_date DATE,
|
|
method TEXT,
|
|
status TEXT DEFAULT 'completed',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS inventory_records (
|
|
id SERIAL PRIMARY KEY,
|
|
record_type TEXT NOT NULL,
|
|
project_id INTEGER REFERENCES projects(id),
|
|
purchase_request_id INTEGER REFERENCES purchase_requests(id),
|
|
product_id INTEGER NOT NULL REFERENCES products(id),
|
|
quantity REAL NOT NULL DEFAULT 0,
|
|
unit_price REAL,
|
|
total_amount REAL,
|
|
record_date DATE NOT NULL,
|
|
operator TEXT,
|
|
remark TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS logistics_companies (
|
|
id SERIAL PRIMARY KEY,
|
|
code TEXT UNIQUE NOT NULL,
|
|
name TEXT NOT NULL,
|
|
address TEXT,
|
|
phone TEXT,
|
|
email TEXT,
|
|
quotation_description TEXT,
|
|
status TEXT DEFAULT 'active',
|
|
remark TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS logistics_company_contacts (
|
|
id SERIAL PRIMARY KEY,
|
|
logistics_company_id INTEGER REFERENCES logistics_companies(id) ON DELETE CASCADE,
|
|
name TEXT,
|
|
phone TEXT,
|
|
position TEXT,
|
|
is_primary INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS logistics_company_bank_accounts (
|
|
id SERIAL PRIMARY KEY,
|
|
logistics_company_id INTEGER REFERENCES logistics_companies(id) ON DELETE CASCADE,
|
|
account_name TEXT,
|
|
bank_name TEXT,
|
|
account_number TEXT,
|
|
is_default INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS construction_logs (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
log_date DATE NOT NULL,
|
|
weather TEXT,
|
|
recorded_by TEXT,
|
|
work_content TEXT,
|
|
next_plan TEXT,
|
|
issues TEXT,
|
|
photos TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS project_type_templates (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(100) NOT NULL,
|
|
description TEXT,
|
|
phases JSONB NOT NULL DEFAULT '[]',
|
|
is_system BOOLEAN DEFAULT false,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS project_phases (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
template_key VARCHAR(50),
|
|
phase_name VARCHAR(100) NOT NULL,
|
|
phase_order INTEGER NOT NULL,
|
|
phase_type VARCHAR(20) DEFAULT 'serial',
|
|
depends_on INTEGER[],
|
|
status VARCHAR(20) DEFAULT 'pending',
|
|
started_at TIMESTAMP,
|
|
completed_at TIMESTAMP,
|
|
completed_by INTEGER REFERENCES users(id),
|
|
remark TEXT,
|
|
photos TEXT[],
|
|
sub_items JSONB DEFAULT '[]',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS budget_projects (
|
|
id SERIAL PRIMARY KEY,
|
|
budget_code TEXT,
|
|
name TEXT NOT NULL,
|
|
customer_id INTEGER REFERENCES customers(id),
|
|
business_manager_id INTEGER REFERENCES users(id),
|
|
location TEXT,
|
|
survey_date DATE,
|
|
intermediary_name TEXT,
|
|
intermediary_fee_type TEXT DEFAULT 'fixed',
|
|
intermediary_fee REAL DEFAULT 0,
|
|
customer_requirements TEXT,
|
|
survey_notes TEXT,
|
|
status TEXT DEFAULT 'draft',
|
|
total_amount REAL DEFAULT 0,
|
|
currency TEXT DEFAULT 'CNY',
|
|
remark TEXT,
|
|
created_by INTEGER REFERENCES users(id),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS budget_quotations (
|
|
id SERIAL PRIMARY KEY,
|
|
budget_project_id INTEGER REFERENCES budget_projects(id) ON DELETE CASCADE,
|
|
version INTEGER DEFAULT 1,
|
|
quotation_date DATE,
|
|
amount REAL DEFAULT 0,
|
|
currency TEXT DEFAULT 'CNY',
|
|
file_url TEXT,
|
|
notes TEXT,
|
|
status TEXT DEFAULT 'draft',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS budget_attachments (
|
|
id SERIAL PRIMARY KEY,
|
|
budget_project_id INTEGER REFERENCES budget_projects(id) ON DELETE CASCADE,
|
|
file_url TEXT,
|
|
file_type TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS project_contracts (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
contract_no TEXT,
|
|
contract_amount REAL,
|
|
sign_date DATE,
|
|
file_url TEXT,
|
|
remark TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS project_milestones (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
milestone_name TEXT,
|
|
amount REAL DEFAULT 0,
|
|
due_date DATE,
|
|
status TEXT DEFAULT 'pending',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS project_receipts (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER REFERENCES projects(id),
|
|
milestone_id INTEGER REFERENCES project_milestones(id),
|
|
amount REAL DEFAULT 0,
|
|
receipt_date DATE,
|
|
financial_record_id INTEGER,
|
|
remark TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS subcontractor_events (
|
|
id SERIAL PRIMARY KEY,
|
|
subcontractor_id INTEGER REFERENCES subcontractors(id),
|
|
project_id INTEGER REFERENCES projects(id),
|
|
event_type VARCHAR(10),
|
|
score_change INTEGER,
|
|
event_date DATE,
|
|
title VARCHAR(200),
|
|
description TEXT,
|
|
created_by INTEGER REFERENCES users(id),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- 财务分类与账本(与 migrations 006/007 一致)
|
|
CREATE TABLE IF NOT EXISTS expense_categories (
|
|
id SERIAL PRIMARY KEY,
|
|
category_level1 TEXT NOT NULL,
|
|
category_level2 TEXT NOT NULL,
|
|
label TEXT NOT NULL,
|
|
description TEXT,
|
|
sort_order INTEGER DEFAULT 0,
|
|
is_active BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(category_level1, category_level2)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS financial_records (
|
|
id SERIAL PRIMARY KEY,
|
|
record_code TEXT UNIQUE NOT NULL,
|
|
txn_type TEXT NOT NULL CHECK (txn_type IN ('income', 'expense')),
|
|
category_level1 TEXT NOT NULL,
|
|
category_level2 TEXT NOT NULL,
|
|
project_id INTEGER REFERENCES projects(id),
|
|
user_id INTEGER REFERENCES users(id),
|
|
user_name TEXT,
|
|
amount_original REAL NOT NULL DEFAULT 0,
|
|
currency TEXT NOT NULL DEFAULT 'CNY',
|
|
exchange_rate REAL NOT NULL DEFAULT 1,
|
|
amount_cny REAL NOT NULL DEFAULT 0,
|
|
record_date DATE NOT NULL,
|
|
counterparty_name TEXT,
|
|
counterparty_type TEXT,
|
|
counterparty_id INTEGER,
|
|
source TEXT NOT NULL DEFAULT 'manual',
|
|
source_id INTEGER,
|
|
source_code TEXT,
|
|
description TEXT,
|
|
voucher_no TEXT,
|
|
attachments TEXT,
|
|
status TEXT NOT NULL DEFAULT 'confirmed' CHECK (status IN ('confirmed', 'pending', 'voided')),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_products_category ON products(category_id);
|
|
CREATE INDEX IF NOT EXISTS idx_purchase_requests_project ON purchase_requests(project_id);
|
|
CREATE INDEX IF NOT EXISTS idx_financial_records_project ON financial_records(project_id);
|
|
CREATE INDEX IF NOT EXISTS idx_expense_categories_level1 ON expense_categories(category_level1);
|
|
|
|
-- 兼容已存在的旧 projects 表,补充缺失字段
|
|
ALTER TABLE projects ADD COLUMN IF NOT EXISTS start_date DATE;
|
|
ALTER TABLE projects ADD COLUMN IF NOT EXISTS end_date DATE;
|
|
ALTER TABLE projects ADD COLUMN IF NOT EXISTS description TEXT;
|
|
ALTER TABLE projects ADD COLUMN IF NOT EXISTS type_template_id INTEGER;
|
|
ALTER TABLE projects ADD COLUMN IF NOT EXISTS current_phase VARCHAR(50);
|
|
ALTER TABLE projects ADD COLUMN IF NOT EXISTS phase_progress NUMERIC(5,2) DEFAULT 0;
|
|
|
|
-- 兼容已存在库:补充路由依赖字段
|
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS is_active BOOLEAN DEFAULT true;
|
|
UPDATE users SET is_active = true WHERE is_active IS NULL;
|
|
|
|
ALTER TABLE budget_projects ADD COLUMN IF NOT EXISTS budget_code TEXT;
|
|
ALTER TABLE budget_projects ADD COLUMN IF NOT EXISTS business_manager_id INTEGER REFERENCES users(id);
|
|
ALTER TABLE budget_projects ADD COLUMN IF NOT EXISTS location TEXT;
|
|
ALTER TABLE budget_projects ADD COLUMN IF NOT EXISTS survey_date DATE;
|
|
ALTER TABLE budget_projects ADD COLUMN IF NOT EXISTS intermediary_name TEXT;
|
|
ALTER TABLE budget_projects ADD COLUMN IF NOT EXISTS intermediary_fee_type TEXT DEFAULT 'fixed';
|
|
ALTER TABLE budget_projects ADD COLUMN IF NOT EXISTS intermediary_fee REAL DEFAULT 0;
|
|
ALTER TABLE budget_projects ADD COLUMN IF NOT EXISTS customer_requirements TEXT;
|
|
ALTER TABLE budget_projects ADD COLUMN IF NOT EXISTS survey_notes TEXT;
|
|
|
|
ALTER TABLE reimbursements ADD COLUMN IF NOT EXISTS approval_remark TEXT;
|