640 lines
24 KiB
MySQL
640 lines
24 KiB
MySQL
|
|
-- 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;
|