-- =============================================
-- 智慧水务管理系统 - 供水生产 + 巡检 + 报警 DDL
-- 版本: V1
-- =============================================

-- ==================== 报警规则 ====================

CREATE TABLE IF NOT EXISTS alert_rule (
    id BIGSERIAL PRIMARY KEY,
    rule_name VARCHAR(100) NOT NULL,
    device_type VARCHAR(30),
    metric_key VARCHAR(50) NOT NULL,
    alert_level VARCHAR(10) NOT NULL,        -- info/warning/critical/emergency
    condition_expr VARCHAR(200) NOT NULL,    -- "> 0.5" 或 "ABS_DELTA > 10"
    threshold_value DECIMAL(12,4),
    debounce_sec INT DEFAULT 300,            -- 去重窗口(秒)
    notify_scheme_id BIGINT REFERENCES sys_notify_scheme(id),
    enabled SMALLINT DEFAULT 1,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE alert_rule IS '报警规则表';
COMMENT ON COLUMN alert_rule.alert_level IS '报警等级: info/warning/critical/emergency';

CREATE TABLE IF NOT EXISTS alert_event (
    id BIGSERIAL PRIMARY KEY,
    rule_id BIGINT REFERENCES alert_rule(id),
    device_id BIGINT,
    device_sn VARCHAR(100) NOT NULL,
    device_name VARCHAR(200),
    area VARCHAR(50),
    metric_key VARCHAR(50) NOT NULL,
    metric_value DECIMAL(12,4),
    threshold_value VARCHAR(50),
    alert_level VARCHAR(10) NOT NULL,
    title VARCHAR(200),
    message TEXT,
    confirmed_by BIGINT,
    confirmed_at TIMESTAMP,
    dispatched SMALLINT DEFAULT 0,           -- 是否已派单
    resolved_by BIGINT,
    resolved_at TIMESTAMP,
    created_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE alert_event IS '报警事件表';
CREATE INDEX IF NOT EXISTS idx_alert_event_time ON alert_event(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_alert_event_device ON alert_event(device_sn, created_at DESC);

-- ==================== 调度指令 ====================

CREATE TABLE IF NOT EXISTS dispatch_command (
    id BIGSERIAL PRIMARY KEY,
    command_no VARCHAR(30) UNIQUE NOT NULL,
    command_type VARCHAR(30) NOT NULL,       -- routine/emergency
    command_title VARCHAR(200) NOT NULL,
    command_content TEXT NOT NULL,
    source VARCHAR(50),                      -- 来源: 平台/SCADA/上级
    issuer_id BIGINT,
    issuer_name VARCHAR(50),
    target_type VARCHAR(30),                 -- station/device_area/person
    target_ids JSONB,                        -- 目标站点/设备ID数组
    priority VARCHAR(10) DEFAULT 'normal',   -- low/normal/high/urgent
    status VARCHAR(20) DEFAULT 'draft',      -- draft/issued/received/executing/completed/rejected
    issued_at TIMESTAMP,
    received_at TIMESTAMP,
    completed_at TIMESTAMP,
    result_remark TEXT,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE dispatch_command IS '调度指令表';

CREATE TABLE IF NOT EXISTS dispatch_log (
    id BIGSERIAL PRIMARY KEY,
    command_id BIGINT REFERENCES dispatch_command(id),
    action VARCHAR(20) NOT NULL,             -- issue/receive/execute/complete/reject
    operator_id BIGINT,
    operator_name VARCHAR(50),
    remark TEXT,
    created_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE dispatch_log IS '调度指令操作日志';

-- ==================== 值班管理 ====================

CREATE TABLE IF NOT EXISTS duty_schedule (
    id BIGSERIAL PRIMARY KEY,
    schedule_name VARCHAR(100),
    dept_id BIGINT REFERENCES sys_dept(id),
    station_id BIGINT,
    shift_type VARCHAR(20),                  -- day/night/full
    start_time TIME NOT NULL,
    end_time TIME NOT NULL,
    status SMALLINT DEFAULT 1,
    created_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE duty_schedule IS '值班班次表';

CREATE TABLE IF NOT EXISTS duty_record (
    id BIGSERIAL PRIMARY KEY,
    schedule_id BIGINT REFERENCES duty_schedule(id),
    duty_date DATE NOT NULL,
    user_id BIGINT REFERENCES sys_user(id),
    shift_type VARCHAR(20),
    on_duty_at TIMESTAMP,
    off_duty_at TIMESTAMP,
    status VARCHAR(20) DEFAULT 'pending',    -- pending/on_duty/off_duty
    handover_remark TEXT,
    created_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE duty_record IS '值班记录表';

-- ==================== 巡检管理 ====================

CREATE TABLE IF NOT EXISTS patrol_route (
    id BIGSERIAL PRIMARY KEY,
    route_name VARCHAR(100) NOT NULL,
    area VARCHAR(50) NOT NULL,
    route_points JSONB,                      -- [{seq, lng, lat, name, device_ids}]
    estim_duration INT,                      -- 预计时长(分钟)
    status SMALLINT DEFAULT 1,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE patrol_route IS '巡检路线表';

CREATE TABLE IF NOT EXISTS patrol_task (
    id BIGSERIAL PRIMARY KEY,
    route_id BIGINT REFERENCES patrol_route(id),
    assignee_id BIGINT REFERENCES sys_user(id),
    task_name VARCHAR(200),
    task_date DATE NOT NULL,
    plan_start TIMESTAMP,
    plan_end TIMESTAMP,
    actual_start TIMESTAMP,
    actual_end TIMESTAMP,
    status VARCHAR(20) DEFAULT 'pending',    -- pending/in_progress/completed/expired/cancelled
    distance DECIMAL(8,2),                   -- 实际巡检距离(km)
    score INT,                               -- 评分
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE patrol_task IS '巡检任务表';
CREATE INDEX IF NOT EXISTS idx_patrol_task_date ON patrol_task(task_date);

CREATE TABLE IF NOT EXISTS patrol_record (
    id BIGSERIAL PRIMARY KEY,
    task_id BIGINT REFERENCES patrol_task(id),
    point_seq INT,
    device_id BIGINT,
    device_name VARCHAR(200),
    check_items JSONB,                       -- [{item, result, value, photo_urls, remark}]
    gps_lng DOUBLE PRECISION,
    gps_lat DOUBLE PRECISION,
    geom GEOMETRY(Point, 4326),
    record_time TIMESTAMP,
    created_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE patrol_record IS '巡检记录表';
CREATE INDEX IF NOT EXISTS idx_patrol_record_geom ON patrol_record USING GIST(geom);

-- ==================== 水质检测 ====================

CREATE TABLE IF NOT EXISTS water_quality_record (
    id BIGSERIAL PRIMARY KEY,
    test_type VARCHAR(20) NOT NULL,          -- manual/auto
    test_point VARCHAR(100) NOT NULL,        -- 检测点位名称
    point_type VARCHAR(20),                  -- source_water/plant_out/pipe_network/terminal
    area VARCHAR(50),
    station_id BIGINT,
    lng DOUBLE PRECISION,
    lat DOUBLE PRECISION,
    test_date DATE NOT NULL,
    test_time TIME,
    tester VARCHAR(50),
    turbidity DECIMAL(8,2),                  -- 浊度(NTU)
    ph DECIMAL(5,2),
    residual_chlorine DECIMAL(8,2),          -- 余氯(mg/L)
    total_chlorine DECIMAL(8,2),
    cod DECIMAL(8,2),                        -- 化学需氧量(mg/L)
    ammonia DECIMAL(8,2),                    -- 氨氮(mg/L)
    total_bacteria INT,                      -- 总大肠菌群(CFU/100mL)
    extra_data JSONB,                        -- 扩展指标
    is_qualified SMALLINT,
    created_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE water_quality_record IS '水质检测记录表';
CREATE INDEX IF NOT EXISTS idx_wq_record_date ON water_quality_record(test_date);
CREATE INDEX IF NOT EXISTS idx_wq_record_area ON water_quality_record(area);
-- =============================================
-- 智慧水务管理系统 - 巡检问题上报 + 工单管理 DDL
-- 版本: V1
-- =============================================

-- 巡检问题上报表
CREATE TABLE IF NOT EXISTS patrol_problem (
    id BIGSERIAL PRIMARY KEY,
    problem_no VARCHAR(30) UNIQUE NOT NULL,   -- 问题编号：WQ-2026-001
    task_id BIGINT REFERENCES patrol_task(id),
    point_seq INT,
    device_id BIGINT,
    device_name VARCHAR(200),
    problem_type VARCHAR(50) NOT NULL,       -- 设备故障/水质异常/安全隐患/环境卫生/其他
    problem_level VARCHAR(20) DEFAULT 'normal', -- low/normal/high/critical
    problem_title VARCHAR(200) NOT NULL,
    problem_description TEXT,
    location VARCHAR(300),
    lng DOUBLE PRECISION,
    lat DOUBLE PRECISION,
    photo_urls JSONB,                        -- 现场照片URL数组
    reporter_id BIGINT REFERENCES sys_user(id),
    reporter_name VARCHAR(50),
    report_time TIMESTAMP DEFAULT NOW(),
    status VARCHAR(20) DEFAULT 'reported',    -- reported/processing/completed/closed
    work_order_id BIGINT,                    -- 关联工单ID
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE patrol_problem IS '巡检问题上报表';
CREATE INDEX IF NOT EXISTS idx_problem_task ON patrol_problem(task_id);
CREATE INDEX IF NOT EXISTS idx_problem_status ON patrol_problem(status);
CREATE INDEX IF NOT EXISTS idx_problem_device ON patrol_problem(device_id);
CREATE INDEX IF NOT EXISTS idx_problem_type ON patrol_problem(problem_type);

-- 工单表
CREATE TABLE IF NOT EXISTS work_order (
    id BIGSERIAL PRIMARY KEY,
    order_no VARCHAR(30) UNIQUE NOT NULL,     -- 工单编号：WO-2026-001
    problem_id BIGINT REFERENCES patrol_problem(id),
    order_type VARCHAR(50) NOT NULL,        -- 设备维修/水质处理/安全隐患处理/清洁/其他
    priority VARCHAR(20) DEFAULT 'normal',   -- low/normal/high/critical
    title VARCHAR(200) NOT NULL,
    description TEXT,
    location VARCHAR(300),
    contact_person VARCHAR(50),
    contact_phone VARCHAR(20),
    reporter_id BIGINT REFERENCES sys_user(id),
    reporter_name VARCHAR(50),
    assignee_id BIGINT REFERENCES sys_user(id),
    assignee_name VARCHAR(50),
    status VARCHAR(20) DEFAULT 'pending',    -- pending/assigned/processing/completed/cancelled
    process_status VARCHAR(20) DEFAULT 'created', -- created/accepted/in_progress/completed
    estimated_duration INT,                  -- 预计工时(分钟)
    actual_start_time TIMESTAMP,
    actual_end_time TIMESTAMP,
    completion_time TIMESTAMP,
    photos_before JSONB,                     -- 处理前照片
    photos_after JSONB,                      -- 处理后照片
    solution_description TEXT,               -- 处理方案描述
    solution_result TEXT,                    -- 处理结果
    customer_feedback TEXT,                  -- 客户反馈
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE work_order IS '工单表';
CREATE INDEX IF NOT EXISTS idx_order_problem ON work_order(problem_id);
CREATE INDEX IF NOT EXISTS idx_order_status ON work_order(status, process_status);
CREATE INDEX IF NOT EXISTS idx_order_assignee ON work_order(assignee_id);

-- 工单处理记录表
CREATE TABLE IF NOT EXISTS work_order_process (
    id BIGSERIAL PRIMARY KEY,
    work_order_id BIGINT REFERENCES work_order(id),
    process_step VARCHAR(50) NOT NULL,       -- created/accepted/in_progress/completed
    processor_id BIGINT REFERENCES sys_user(id),
    processor_name VARCHAR(50),
    action VARCHAR(50) NOT NULL,            -- create/assign/start/complete/cancel
    comment TEXT,
    photos JSONB,                            -- 处理过程照片
    created_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE work_order_process IS '工单处理记录表';
CREATE INDEX IF NOT EXISTS idx_process_order ON work_order_process(work_order_id);
CREATE INDEX IF NOT EXISTS idx_process_step ON work_order_process(process_step);

-- 工单附件表
CREATE TABLE IF NOT EXISTS work_order_attachment (
    id BIGSERIAL PRIMARY KEY,
    work_order_id BIGINT REFERENCES work_order(id),
    file_name VARCHAR(200) NOT NULL,
    file_path VARCHAR(500) NOT NULL,
    file_type VARCHAR(50),                  -- image/pdf/doc/other
    file_size BIGINT,
    uploaded_by BIGINT REFERENCES sys_user(id),
    uploaded_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE work_order_attachment IS '工单附件表';
CREATE INDEX IF NOT EXISTS idx_attachment_order ON work_order_attachment(work_order_id);

-- 巡检问题与工单关联触发记录
CREATE TABLE IF NOT EXISTS patrol_work_order_trigger (
    id BIGSERIAL PRIMARY KEY,
    patrol_problem_id BIGINT REFERENCES patrol_problem(id),
    work_order_id BIGINT REFERENCES work_order(id),
    trigger_type VARCHAR(20) NOT NULL,      -- auto/manual
    trigger_condition JSONB,                 -- 触发条件
    created_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE patrol_work_order_trigger IS '巡检问题与工单关联触发记录';
CREATE INDEX IF NOT EXISTS idx_trigger_problem ON patrol_work_order_trigger(patrol_problem_id);
CREATE INDEX IF NOT EXISTS idx_trigger_order ON patrol_work_order_trigger(work_order_id);