-- iloom 微服务数据库初始化脚本 -- 创建 5 个 Schema,迁移表结构,建立跨 Schema 视图 -- ============================================= -- 1. 创建 Schema -- ============================================= CREATE SCHEMA IF NOT EXISTS common; CREATE SCHEMA IF NOT EXISTS purchaser; CREATE SCHEMA IF NOT EXISTS textile; CREATE SCHEMA IF NOT EXISTS washing; CREATE SCHEMA IF NOT EXISTS audit; -- ============================================= -- 2. 创建枚举类型(在 public schema,所有 schema 共享) -- ============================================= DO $$ BEGIN CREATE TYPE app_role AS ENUM ('purchaser', 'textile', 'washing'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE factory_type AS ENUM ('textile', 'washing'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE plan_status AS ENUM ('pending', 'producing', 'completed'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE step_status AS ENUM ('pending', 'active', 'completed', 'rejected'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE step_type AS ENUM ('confirm', 'yarn_purchase', 'dyeing', 'machine_start', 'fabric_warehouse'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE warehouse_type AS ENUM ('raw_fabric', 'fabric', 'finished', 'yarn'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE payment_status AS ENUM ('pending', 'completed'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- ============================================= -- 3. common Schema 表 -- ============================================= CREATE TABLE IF NOT EXISTS common.companies ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, role app_role NOT NULL, address TEXT, contact_phone TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS common.profiles ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), username TEXT NOT NULL UNIQUE, password TEXT NOT NULL, phone TEXT, company_id UUID REFERENCES common.companies(id), is_master BOOLEAN NOT NULL DEFAULT true, master_id UUID REFERENCES common.profiles(id), display_name TEXT, image_url TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS common.company_members ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES common.companies(id), user_id UUID NOT NULL REFERENCES common.profiles(id), role TEXT NOT NULL DEFAULT 'member', created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS common.company_relationships ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), purchaser_company_id UUID NOT NULL REFERENCES common.companies(id), factory_company_id UUID NOT NULL REFERENCES common.companies(id), factory_type factory_type NOT NULL, status TEXT NOT NULL DEFAULT 'active', created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS common.notifications ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), recipient_id UUID NOT NULL, sender_id UUID, sender_company_id UUID REFERENCES common.companies(id), title TEXT NOT NULL, content TEXT NOT NULL, type TEXT NOT NULL, plan_id UUID, is_read BOOLEAN DEFAULT false, read_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT now() ); CREATE TABLE IF NOT EXISTS common.share_links ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), plan_id UUID NOT NULL, created_by UUID NOT NULL, short_code TEXT NOT NULL UNIQUE, factory_type TEXT NOT NULL, hide_sensitive BOOLEAN DEFAULT false, status TEXT NOT NULL DEFAULT 'pending', expires_at TIMESTAMPTZ, clicked_at TIMESTAMPTZ, click_count INT DEFAULT 0, used_at TIMESTAMPTZ, response_result TEXT, reject_reason TEXT, responded_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS common.user_feedback ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID, type TEXT NOT NULL, content TEXT NOT NULL, contact TEXT, status TEXT NOT NULL DEFAULT 'pending', created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS common.crash_reports ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID, error_message TEXT NOT NULL, error_stack TEXT, component_stack TEXT, url TEXT, user_agent TEXT, user_description TEXT, status TEXT NOT NULL DEFAULT 'new', created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- ============================================= -- 4. purchaser Schema 表 -- ============================================= CREATE TABLE IF NOT EXISTS purchaser.production_plans ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), plan_code TEXT NOT NULL, purchaser_id UUID NOT NULL REFERENCES common.companies(id), product_name TEXT NOT NULL, fabric_code TEXT NOT NULL, color TEXT NOT NULL, color_code TEXT NOT NULL DEFAULT '', target_quantity NUMERIC NOT NULL DEFAULT 0, completed_quantity NUMERIC NOT NULL DEFAULT 0, production_price NUMERIC, yarn_usage_per_meter NUMERIC, status plan_status NOT NULL DEFAULT 'pending', remark TEXT, start_time TIMESTAMPTZ, created_by UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS purchaser.plan_factories ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), plan_id UUID NOT NULL REFERENCES purchaser.production_plans(id) ON DELETE CASCADE, factory_id UUID NOT NULL REFERENCES common.companies(id), factory_type factory_type NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS purchaser.yarn_ratios ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), plan_id UUID NOT NULL REFERENCES purchaser.production_plans(id) ON DELETE CASCADE, yarn_name TEXT NOT NULL, yarn_type TEXT, ratio NUMERIC NOT NULL DEFAULT 0, amount_per_meter NUMERIC NOT NULL DEFAULT 0, total_amount NUMERIC NOT NULL DEFAULT 0, company_id UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS purchaser.products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES common.companies(id), product_name TEXT NOT NULL, fabric_code TEXT NOT NULL, color TEXT NOT NULL, color_code TEXT NOT NULL DEFAULT '', weight NUMERIC NOT NULL DEFAULT 0, warp_weight NUMERIC, weft_weight NUMERIC, total_weight NUMERIC, yarn_usage_per_meter NUMERIC NOT NULL DEFAULT 0, production_price NUMERIC, total_stock NUMERIC NOT NULL DEFAULT 0, raw_fabric_meters NUMERIC NOT NULL DEFAULT 0, raw_fabric_rolls INT NOT NULL DEFAULT 0, image_url TEXT, yarn_types TEXT[], yarn_ratios NUMERIC[], created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS purchaser.product_inventory_records ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), product_id UUID NOT NULL REFERENCES purchaser.products(id) ON DELETE CASCADE, batch_no TEXT NOT NULL, rolls INT NOT NULL DEFAULT 0, meters NUMERIC NOT NULL DEFAULT 0, notes TEXT, operator_id UUID, company_id UUID, warehouse_id UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS purchaser.product_outbound_records ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), product_id UUID NOT NULL REFERENCES purchaser.products(id) ON DELETE CASCADE, batch_no TEXT NOT NULL DEFAULT '', rolls INT NOT NULL DEFAULT 0, meters NUMERIC NOT NULL DEFAULT 0, outbound_type TEXT NOT NULL DEFAULT 'normal', notes TEXT, operator_id UUID, company_id UUID, recipient_company_id UUID, recipient_company_name TEXT, source_batch_id UUID, washing_plan_id UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS purchaser.product_yarn_ratios ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), product_id UUID NOT NULL REFERENCES purchaser.products(id) ON DELETE CASCADE, yarn_name TEXT NOT NULL, yarn_type TEXT, ratio NUMERIC NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS purchaser.product_price_history ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), product_id UUID NOT NULL REFERENCES purchaser.products(id) ON DELETE CASCADE, company_id UUID NOT NULL, old_price NUMERIC NOT NULL DEFAULT 0, new_price NUMERIC NOT NULL DEFAULT 0, change_amount NUMERIC NOT NULL DEFAULT 0, change_reason TEXT, operator_id UUID, operator_name TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS purchaser.production_price_history ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), plan_id UUID NOT NULL REFERENCES purchaser.production_plans(id) ON DELETE CASCADE, old_price NUMERIC NOT NULL DEFAULT 0, new_price NUMERIC NOT NULL DEFAULT 0, change_amount NUMERIC NOT NULL DEFAULT 0, change_reason TEXT, operator_id UUID, operator_name TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS purchaser.accounts_payable ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), plan_id UUID NOT NULL REFERENCES purchaser.production_plans(id), purchaser_id UUID NOT NULL REFERENCES common.companies(id), textile_factory_id UUID NOT NULL REFERENCES common.companies(id), price_per_meter NUMERIC NOT NULL DEFAULT 0, total_quantity NUMERIC NOT NULL DEFAULT 0, total_amount NUMERIC NOT NULL DEFAULT 0, paid_quantity NUMERIC NOT NULL DEFAULT 0, paid_amount NUMERIC NOT NULL DEFAULT 0, unpaid_quantity NUMERIC NOT NULL DEFAULT 0, unpaid_amount NUMERIC NOT NULL DEFAULT 0, status TEXT NOT NULL DEFAULT 'pending', created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS purchaser.accounts_payable_items ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), accounts_payable_id UUID NOT NULL REFERENCES purchaser.accounts_payable(id) ON DELETE CASCADE, inventory_record_id UUID, payment_id UUID, quantity NUMERIC NOT NULL DEFAULT 0, price_per_meter NUMERIC NOT NULL DEFAULT 0, amount NUMERIC NOT NULL DEFAULT 0, rolls INT, status TEXT NOT NULL DEFAULT 'pending', paid_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS purchaser.washing_plans ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), plan_code TEXT NOT NULL, company_id UUID NOT NULL REFERENCES common.companies(id), product_id UUID NOT NULL REFERENCES purchaser.products(id), washing_factory_id UUID REFERENCES common.companies(id), planned_meters NUMERIC NOT NULL DEFAULT 0, washing_price NUMERIC NOT NULL DEFAULT 0, estimated_shrinkage_rate NUMERIC NOT NULL DEFAULT 0, estimated_washed_meters NUMERIC, estimated_total_cost NUMERIC, actual_shrinkage_rate NUMERIC, actual_washed_meters NUMERIC, actual_total_cost NUMERIC, washing_date TIMESTAMPTZ, status TEXT NOT NULL DEFAULT 'pending', notes TEXT, created_by UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- ============================================= -- 5. textile Schema 表 -- ============================================= CREATE TABLE IF NOT EXISTS textile.plan_process_steps ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), plan_id UUID NOT NULL REFERENCES purchaser.production_plans(id) ON DELETE CASCADE, step_type step_type NOT NULL, status step_status NOT NULL DEFAULT 'pending', notes TEXT, operator_id UUID, company_id UUID, timestamp TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS textile.warehouses ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES common.companies(id), name TEXT NOT NULL, type warehouse_type NOT NULL, location TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS textile.inventory_records ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), plan_id UUID NOT NULL REFERENCES purchaser.production_plans(id), warehouse_id UUID NOT NULL REFERENCES textile.warehouses(id), quantity NUMERIC NOT NULL DEFAULT 0, rolls INT, price_per_meter NUMERIC, price_note TEXT, warehouse_location TEXT, operator_id UUID, company_id UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS textile.yarn_stock ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES common.companies(id), name TEXT NOT NULL, spec TEXT, quantity NUMERIC NOT NULL DEFAULT 0, unit TEXT NOT NULL DEFAULT 'kg', min_stock NUMERIC NOT NULL DEFAULT 0, warehouse_id UUID REFERENCES textile.warehouses(id), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS textile.yarn_stock_records ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), yarn_stock_id UUID REFERENCES textile.yarn_stock(id), company_id UUID NOT NULL REFERENCES common.companies(id), record_type TEXT NOT NULL, quantity NUMERIC NOT NULL DEFAULT 0, unit TEXT NOT NULL DEFAULT 'kg', batch_no TEXT, plan_id UUID, notes TEXT, operator_id UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS textile.payments ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), plan_id UUID NOT NULL REFERENCES purchaser.production_plans(id), from_company_id UUID NOT NULL REFERENCES common.companies(id), to_company_id UUID NOT NULL REFERENCES common.companies(id), amount NUMERIC NOT NULL DEFAULT 0, quantity NUMERIC NOT NULL DEFAULT 0, price_per_meter NUMERIC NOT NULL DEFAULT 0, status payment_status NOT NULL DEFAULT 'pending', paid_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- ============================================= -- 6. washing Schema 表 -- ============================================= CREATE TABLE IF NOT EXISTS washing.washing_process_steps ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), washing_plan_id UUID NOT NULL REFERENCES purchaser.washing_plans(id) ON DELETE CASCADE, company_id UUID NOT NULL REFERENCES common.companies(id), step_type TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'pending', notes TEXT, operator_id UUID, timestamp TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS washing.washing_plan_completions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), washing_plan_id UUID NOT NULL REFERENCES purchaser.washing_plans(id), company_id UUID NOT NULL REFERENCES common.companies(id), actual_shrinkage_rate NUMERIC NOT NULL, actual_washed_meters NUMERIC NOT NULL, actual_washing_cost NUMERIC, unit_cost NUMERIC, rolls INT NOT NULL DEFAULT 0, washing_date DATE NOT NULL, notes TEXT, completed_by UUID, completed_at TIMESTAMPTZ NOT NULL DEFAULT now(), finished_product_id UUID, auto_imported BOOLEAN DEFAULT false, warehouse_id UUID, warehouse_location TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS washing.finished_products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES common.companies(id), product_name TEXT NOT NULL, fabric_code TEXT NOT NULL, color TEXT NOT NULL, color_code TEXT, weight NUMERIC, shrinkage_rate NUMERIC NOT NULL DEFAULT 0, washed_meters NUMERIC NOT NULL DEFAULT 0, stock_meters NUMERIC NOT NULL DEFAULT 0, stock_rolls INT NOT NULL DEFAULT 0, rolls INT, washing_cost NUMERIC, unit_cost NUMERIC, status TEXT NOT NULL DEFAULT 'active', notes TEXT, product_id UUID, washing_plan_id UUID, warehouse_id UUID, warehouse_location TEXT, created_by UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS washing.finished_product_inventory_records ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), finished_product_id UUID NOT NULL REFERENCES washing.finished_products(id) ON DELETE CASCADE, company_id UUID NOT NULL REFERENCES common.companies(id), record_type TEXT NOT NULL, rolls INT NOT NULL DEFAULT 0, meters NUMERIC NOT NULL DEFAULT 0, batch_no TEXT, notes TEXT, operator_id UUID, warehouse_id UUID, warehouse_location TEXT, washing_completion_id UUID, related_order_id UUID, related_order_type TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- ============================================= -- 7. audit Schema 表 -- ============================================= CREATE TABLE IF NOT EXISTS audit.audit_logs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID, company_id UUID, action TEXT NOT NULL, resource_type TEXT NOT NULL, resource_id UUID, details JSONB, ip_address TEXT, user_agent TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS audit.data_audit_logs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), table_name TEXT NOT NULL, record_id TEXT NOT NULL, operation TEXT NOT NULL, old_values JSONB, new_values JSONB, changed_by UUID, error_message TEXT, validation_passed BOOLEAN NOT NULL DEFAULT true, changed_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- ============================================= -- 8. 跨 Schema 只读视图 -- ============================================= -- textile-service 需要读取分配给自己的计划 CREATE OR REPLACE VIEW textile.v_assigned_plans AS SELECT pp.id, pp.plan_code, pp.product_name, pp.fabric_code, pp.color, pp.color_code, pp.target_quantity, pp.completed_quantity, pp.production_price, pp.yarn_usage_per_meter, pp.status, pp.remark, pp.start_time, pp.created_at, pp.updated_at, pf.factory_id, pf.id AS plan_factory_id, c.name AS purchaser_name FROM purchaser.production_plans pp JOIN purchaser.plan_factories pf ON pp.id = pf.plan_id JOIN common.companies c ON pp.purchaser_id = c.id WHERE pf.factory_type = 'textile'; -- washing-service 需要读取分配给自己的水洗计划 CREATE OR REPLACE VIEW washing.v_assigned_washing_plans AS SELECT wp.id, wp.plan_code, wp.company_id, wp.product_id, wp.washing_factory_id, wp.planned_meters, wp.washing_price, wp.estimated_shrinkage_rate, wp.estimated_washed_meters, wp.estimated_total_cost, wp.actual_shrinkage_rate, wp.actual_washed_meters, wp.actual_total_cost, wp.washing_date, wp.status, wp.notes, wp.created_at, wp.updated_at, p.product_name, p.fabric_code, p.color, p.color_code, c.name AS purchaser_name FROM purchaser.washing_plans wp LEFT JOIN purchaser.products p ON wp.product_id = p.id LEFT JOIN common.companies c ON wp.company_id = c.id; -- purchaser-service 需要读取计划的流程步骤 CREATE OR REPLACE VIEW purchaser.v_plan_steps AS SELECT ps.id, ps.plan_id, ps.step_type, ps.status, ps.notes, ps.operator_id, ps.company_id, ps.timestamp, ps.created_at, pr.display_name AS operator_name FROM textile.plan_process_steps ps LEFT JOIN common.profiles pr ON ps.operator_id = pr.id; -- purchaser-service 需要读取入库记录 CREATE OR REPLACE VIEW purchaser.v_plan_inventory AS SELECT ir.id, ir.plan_id, ir.warehouse_id, ir.quantity, ir.rolls, ir.price_per_meter, ir.price_note, ir.warehouse_location, ir.operator_id, ir.company_id, ir.created_at, w.name AS warehouse_name, pr.display_name AS operator_name FROM textile.inventory_records ir LEFT JOIN textile.warehouses w ON ir.warehouse_id = w.id LEFT JOIN common.profiles pr ON ir.operator_id = pr.id; -- ============================================= -- 9. 索引 -- ============================================= CREATE INDEX IF NOT EXISTS idx_profiles_username ON common.profiles(username); CREATE INDEX IF NOT EXISTS idx_profiles_company ON common.profiles(company_id); CREATE INDEX IF NOT EXISTS idx_company_members_company ON common.company_members(company_id); CREATE INDEX IF NOT EXISTS idx_company_relationships_purchaser ON common.company_relationships(purchaser_company_id); CREATE INDEX IF NOT EXISTS idx_company_relationships_factory ON common.company_relationships(factory_company_id); CREATE INDEX IF NOT EXISTS idx_notifications_recipient ON common.notifications(recipient_id); CREATE INDEX IF NOT EXISTS idx_share_links_code ON common.share_links(short_code); CREATE INDEX IF NOT EXISTS idx_plans_purchaser ON purchaser.production_plans(purchaser_id); CREATE INDEX IF NOT EXISTS idx_plans_status ON purchaser.production_plans(status); CREATE INDEX IF NOT EXISTS idx_plan_factories_plan ON purchaser.plan_factories(plan_id); CREATE INDEX IF NOT EXISTS idx_plan_factories_factory ON purchaser.plan_factories(factory_id); CREATE INDEX IF NOT EXISTS idx_yarn_ratios_plan ON purchaser.yarn_ratios(plan_id); CREATE INDEX IF NOT EXISTS idx_products_company ON purchaser.products(company_id); CREATE INDEX IF NOT EXISTS idx_product_inventory_product ON purchaser.product_inventory_records(product_id); CREATE INDEX IF NOT EXISTS idx_ap_purchaser ON purchaser.accounts_payable(purchaser_id); CREATE INDEX IF NOT EXISTS idx_washing_plans_company ON purchaser.washing_plans(company_id); CREATE INDEX IF NOT EXISTS idx_washing_plans_factory ON purchaser.washing_plans(washing_factory_id); CREATE INDEX IF NOT EXISTS idx_process_steps_plan ON textile.plan_process_steps(plan_id); CREATE INDEX IF NOT EXISTS idx_inventory_plan ON textile.inventory_records(plan_id); CREATE INDEX IF NOT EXISTS idx_yarn_stock_company ON textile.yarn_stock(company_id); CREATE INDEX IF NOT EXISTS idx_yarn_records_stock ON textile.yarn_stock_records(yarn_stock_id); CREATE INDEX IF NOT EXISTS idx_payments_to ON textile.payments(to_company_id); CREATE INDEX IF NOT EXISTS idx_washing_steps_plan ON washing.washing_process_steps(washing_plan_id); CREATE INDEX IF NOT EXISTS idx_completions_plan ON washing.washing_plan_completions(washing_plan_id); CREATE INDEX IF NOT EXISTS idx_finished_products_company ON washing.finished_products(company_id); CREATE INDEX IF NOT EXISTS idx_fp_inventory_product ON washing.finished_product_inventory_records(finished_product_id); -- ============================================= -- 10. 权限授予 -- ============================================= GRANT USAGE ON SCHEMA common TO iloom; GRANT USAGE ON SCHEMA purchaser TO iloom; GRANT USAGE ON SCHEMA textile TO iloom; GRANT USAGE ON SCHEMA washing TO iloom; GRANT USAGE ON SCHEMA audit TO iloom; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA common TO iloom; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA purchaser TO iloom; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA textile TO iloom; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA washing TO iloom; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA audit TO iloom; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA common TO iloom; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA purchaser TO iloom; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA textile TO iloom; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA washing TO iloom; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA audit TO iloom; ALTER DEFAULT PRIVILEGES IN SCHEMA common GRANT ALL ON TABLES TO iloom; ALTER DEFAULT PRIVILEGES IN SCHEMA purchaser GRANT ALL ON TABLES TO iloom; ALTER DEFAULT PRIVILEGES IN SCHEMA textile GRANT ALL ON TABLES TO iloom; ALTER DEFAULT PRIVILEGES IN SCHEMA washing GRANT ALL ON TABLES TO iloom; ALTER DEFAULT PRIVILEGES IN SCHEMA audit GRANT ALL ON TABLES TO iloom;