Phase 1 #18: PostgreSQL + TDengine 完整 DDL 建表脚本
- 15+张核心表: sys_*(部门/用户/角色/菜单/日志/字典/通知/文件) - iot_*: 设备模型/设备实例/设备影子/设备事件/站点(PostGIS空间坐标) - rev_*: 用水户/水价阶梯/水表档案/水表操作日志/抄表/账单/缴费/报装 - production: alert_rule(报警规则)/alert_event(报警事件)/dispatch_command(调度)/duty(值班)/patrol(巡检)/water_quality(水质) - TDengine: iot_telemetry超级表(6类设备子表)+事件表+小时聚合 - 种子数据: admin管理员/5个角色/6个片区/基础字典
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
-- =============================================
|
||||
-- 智慧水务管理系统 - PostgreSQL DDL
|
||||
-- 版本: V1
|
||||
-- 描述: 核心业务表建表脚本
|
||||
-- =============================================
|
||||
|
||||
-- ==================== 系统管理 ====================
|
||||
|
||||
-- 部门表
|
||||
CREATE TABLE IF NOT EXISTS sys_dept (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
parent_id BIGINT,
|
||||
dept_name VARCHAR(100) NOT NULL,
|
||||
dept_type VARCHAR(20) NOT NULL DEFAULT 'water_company', -- water_bureau/water_company/ops
|
||||
sort_order INT DEFAULT 0,
|
||||
leader VARCHAR(50),
|
||||
phone VARCHAR(20),
|
||||
status SMALLINT DEFAULT 1,
|
||||
deleted SMALLINT DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE sys_dept IS '部门表';
|
||||
COMMENT ON COLUMN sys_dept.dept_type IS '部门类型: water_bureau(水利局)/water_company(水务公司)/ops(运维单位)';
|
||||
|
||||
-- 用户表
|
||||
CREATE TABLE IF NOT EXISTS sys_user (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
dept_id BIGINT REFERENCES sys_dept(id),
|
||||
username VARCHAR(50) UNIQUE NOT NULL,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
real_name VARCHAR(50),
|
||||
nickname VARCHAR(50),
|
||||
phone VARCHAR(20),
|
||||
email VARCHAR(100),
|
||||
avatar VARCHAR(500),
|
||||
gender SMALLINT DEFAULT 0, -- 0:未知 1:男 2:女
|
||||
role_type VARCHAR(30) DEFAULT 'operator', -- admin/leader/manager/operator/tech
|
||||
status SMALLINT DEFAULT 1, -- 0:停用 1:启用
|
||||
login_ip VARCHAR(50),
|
||||
login_at TIMESTAMP,
|
||||
deleted SMALLINT DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE sys_user IS '用户表';
|
||||
COMMENT ON COLUMN sys_user.role_type IS '角色类型: admin/leader/manager/operator/tech';
|
||||
|
||||
-- 角色表
|
||||
CREATE TABLE IF NOT EXISTS sys_role (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
role_name VARCHAR(50) UNIQUE NOT NULL,
|
||||
role_key VARCHAR(50) UNIQUE NOT NULL,
|
||||
role_sort INT DEFAULT 0,
|
||||
data_scope VARCHAR(20) DEFAULT 'SELF', -- ALL/DEPT/CUSTOM/SELF
|
||||
status SMALLINT DEFAULT 1,
|
||||
remark VARCHAR(500),
|
||||
deleted SMALLINT DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE sys_role IS '角色表';
|
||||
COMMENT ON COLUMN sys_role.role_key IS '角色标识: admin/supervisor/biz_manager/field_ops/tech_maintain';
|
||||
COMMENT ON COLUMN sys_role.data_scope IS '数据权限范围: ALL/DEPT/CUSTOM/SELF';
|
||||
|
||||
-- 菜单表
|
||||
CREATE TABLE IF NOT EXISTS sys_menu (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
parent_id BIGINT DEFAULT 0,
|
||||
menu_name VARCHAR(50) NOT NULL,
|
||||
menu_type CHAR(1) DEFAULT 'M', -- M:目录 C:菜单 F:按钮
|
||||
path VARCHAR(200),
|
||||
component VARCHAR(255),
|
||||
perms VARCHAR(100),
|
||||
icon VARCHAR(100),
|
||||
sort_order INT DEFAULT 0,
|
||||
visible SMALLINT DEFAULT 1,
|
||||
status SMALLINT DEFAULT 1,
|
||||
deleted SMALLINT DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE sys_menu IS '菜单表';
|
||||
|
||||
-- 角色-菜单关联
|
||||
CREATE TABLE IF NOT EXISTS sys_role_menu (
|
||||
role_id BIGINT NOT NULL REFERENCES sys_role(id),
|
||||
menu_id BIGINT NOT NULL REFERENCES sys_menu(id),
|
||||
PRIMARY KEY (role_id, menu_id)
|
||||
);
|
||||
COMMENT ON TABLE sys_role_menu IS '角色菜单关联表';
|
||||
|
||||
-- 用户-角色关联
|
||||
CREATE TABLE IF NOT EXISTS sys_user_role (
|
||||
user_id BIGINT NOT NULL REFERENCES sys_user(id),
|
||||
role_id BIGINT NOT NULL REFERENCES sys_role(id),
|
||||
PRIMARY KEY (user_id, role_id)
|
||||
);
|
||||
COMMENT ON TABLE sys_user_role IS '用户角色关联表';
|
||||
|
||||
-- 操作日志表
|
||||
CREATE TABLE IF NOT EXISTS sys_oper_log (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT,
|
||||
username VARCHAR(50),
|
||||
module VARCHAR(50),
|
||||
operation VARCHAR(50),
|
||||
method VARCHAR(200),
|
||||
request_method VARCHAR(10),
|
||||
request_url VARCHAR(500),
|
||||
request_params TEXT,
|
||||
response_result TEXT,
|
||||
ip VARCHAR(50),
|
||||
location VARCHAR(100),
|
||||
duration BIGINT,
|
||||
status SMALLINT DEFAULT 1,
|
||||
error_msg TEXT,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE sys_oper_log IS '操作日志表';
|
||||
|
||||
-- 登录日志表
|
||||
CREATE TABLE IF NOT EXISTS sys_login_log (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
username VARCHAR(50),
|
||||
ip VARCHAR(50),
|
||||
location VARCHAR(100),
|
||||
browser VARCHAR(100),
|
||||
os VARCHAR(100),
|
||||
status SMALLINT DEFAULT 1, -- 0:失败 1:成功
|
||||
msg VARCHAR(500),
|
||||
login_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE sys_login_log IS '登录日志表';
|
||||
|
||||
-- ==================== 数据字典 ====================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_dict_type (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
dict_name VARCHAR(100) NOT NULL,
|
||||
dict_key VARCHAR(100) UNIQUE NOT NULL,
|
||||
status SMALLINT DEFAULT 1,
|
||||
remark VARCHAR(500),
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE sys_dict_type IS '字典类型表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_dict_data (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
dict_type_id BIGINT REFERENCES sys_dict_type(id),
|
||||
dict_label VARCHAR(100) NOT NULL,
|
||||
dict_value VARCHAR(100) NOT NULL,
|
||||
css_class VARCHAR(100),
|
||||
list_class VARCHAR(100),
|
||||
sort_order INT DEFAULT 0,
|
||||
status SMALLINT DEFAULT 1,
|
||||
remark VARCHAR(500),
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE sys_dict_data IS '字典数据表';
|
||||
|
||||
-- ==================== 通知方案 ====================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_notify_scheme (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
scheme_name VARCHAR(100) NOT NULL,
|
||||
channels VARCHAR(200), -- sms,app_push,websocket,wechat (逗号分隔)
|
||||
template_id VARCHAR(50),
|
||||
status SMALLINT DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE sys_notify_scheme IS '通知方案表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_notify_record (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
scheme_id BIGINT REFERENCES sys_notify_scheme(id),
|
||||
target_user_id BIGINT,
|
||||
target_phone VARCHAR(20),
|
||||
channel VARCHAR(20),
|
||||
title VARCHAR(200),
|
||||
content TEXT,
|
||||
status VARCHAR(20) DEFAULT 'pending', -- pending/sent/failed/read
|
||||
sent_at TIMESTAMP,
|
||||
read_at TIMESTAMP,
|
||||
error_msg VARCHAR(500),
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE sys_notify_record IS '通知记录表';
|
||||
|
||||
-- ==================== 文件管理 ====================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_file (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
file_name VARCHAR(200) NOT NULL,
|
||||
original_name VARCHAR(200),
|
||||
file_path VARCHAR(500) NOT NULL,
|
||||
file_size BIGINT,
|
||||
mime_type VARCHAR(100),
|
||||
file_ext VARCHAR(20),
|
||||
storage_type VARCHAR(20) DEFAULT 'minio',
|
||||
bucket VARCHAR(100) DEFAULT 'water-management',
|
||||
module VARCHAR(50),
|
||||
biz_id BIGINT,
|
||||
upload_by BIGINT,
|
||||
deleted SMALLINT DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE sys_file IS '文件管理表';
|
||||
@@ -0,0 +1,101 @@
|
||||
-- =============================================
|
||||
-- 智慧水务管理系统 - 物联网设备相关 DDL
|
||||
-- 版本: V1
|
||||
-- =============================================
|
||||
|
||||
-- 扩展
|
||||
CREATE EXTENSION IF NOT EXISTS postgis;
|
||||
|
||||
-- 设备模型定义
|
||||
CREATE TABLE IF NOT EXISTS iot_device_model (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
model_key VARCHAR(50) UNIQUE NOT NULL,
|
||||
model_name VARCHAR(100) NOT NULL,
|
||||
vendor VARCHAR(100),
|
||||
protocol VARCHAR(20) NOT NULL, -- MQTT/Modbus/CoAP/HTTP
|
||||
properties JSONB, -- [{key, name, unit, data_type, range_min, range_max}]
|
||||
commands JSONB, -- [{key, name, params: [{key, name, type}]}]
|
||||
status SMALLINT DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE iot_device_model IS '设备模型定义表';
|
||||
COMMENT ON COLUMN iot_device_model.properties IS '属性定义JSON数组';
|
||||
COMMENT ON COLUMN iot_device_model.commands IS '支持指令JSON数组';
|
||||
|
||||
-- 设备实例
|
||||
CREATE TABLE IF NOT EXISTS iot_device (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
device_sn VARCHAR(100) UNIQUE NOT NULL,
|
||||
device_name VARCHAR(200) NOT NULL,
|
||||
model_id BIGINT REFERENCES iot_device_model(id),
|
||||
device_type VARCHAR(30) NOT NULL, -- flow_meter/pressure_sensor/valve/water_quality/level_sensor/pump
|
||||
position_type VARCHAR(20), -- water_plant/pressure_station/pipe_network/village
|
||||
label VARCHAR(50), -- 设备标签(便于搜索)
|
||||
loc_lng DOUBLE PRECISION,
|
||||
loc_lat DOUBLE PRECISION,
|
||||
geom GEOMETRY(Point, 4326),
|
||||
area VARCHAR(50) NOT NULL, -- 所属片区
|
||||
station_id BIGINT, -- 所属站点
|
||||
address VARCHAR(300),
|
||||
install_date DATE,
|
||||
warranty_until DATE,
|
||||
status VARCHAR(20) DEFAULT 'offline', -- online/offline/maintenance/fault
|
||||
firmware_version VARCHAR(20),
|
||||
last_report_time TIMESTAMP,
|
||||
metadata JSONB,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE iot_device IS '设备实例表';
|
||||
COMMENT ON COLUMN iot_device.geom IS 'PostGIS空间坐标点';
|
||||
COMMENT ON COLUMN iot_device.metadata IS '扩展元数据';
|
||||
|
||||
-- 空间索引
|
||||
CREATE INDEX IF NOT EXISTS idx_iot_device_geom ON iot_device USING GIST(geom);
|
||||
CREATE INDEX IF NOT EXISTS idx_iot_device_area ON iot_device(area);
|
||||
CREATE INDEX IF NOT EXISTS idx_iot_device_type ON iot_device(device_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_iot_device_status ON iot_device(status);
|
||||
|
||||
-- 设备影子
|
||||
CREATE TABLE IF NOT EXISTS iot_device_shadow (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
device_id BIGINT UNIQUE REFERENCES iot_device(id),
|
||||
reported_state JSONB, -- 设备上报的最新状态
|
||||
desired_state JSONB, -- 期望状态(云端下发)
|
||||
delta_state JSONB, -- 差异状态
|
||||
version BIGINT DEFAULT 1,
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE iot_device_shadow IS '设备影子表';
|
||||
|
||||
-- 设备事件
|
||||
CREATE TABLE IF NOT EXISTS iot_device_event (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
device_id BIGINT REFERENCES iot_device(id),
|
||||
device_sn VARCHAR(100) NOT NULL,
|
||||
event_type VARCHAR(30) NOT NULL, -- online/offline/fault/recovery/ota
|
||||
event_data JSONB,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE iot_device_event IS '设备事件表';
|
||||
CREATE INDEX IF NOT EXISTS idx_iot_device_event_sn ON iot_device_event(device_sn, created_at DESC);
|
||||
|
||||
-- 站点管理(水厂/调压站等)
|
||||
CREATE TABLE IF NOT EXISTS iot_station (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
station_name VARCHAR(100) NOT NULL,
|
||||
station_type VARCHAR(30) NOT NULL, -- water_plant/pressure_station/pump_station
|
||||
area VARCHAR(50) NOT NULL,
|
||||
loc_lng DOUBLE PRECISION,
|
||||
loc_lat DOUBLE PRECISION,
|
||||
geom GEOMETRY(Point, 4326),
|
||||
address VARCHAR(300),
|
||||
manager VARCHAR(50),
|
||||
manager_phone VARCHAR(20),
|
||||
status SMALLINT DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE iot_station IS '站点管理表';
|
||||
CREATE INDEX IF NOT EXISTS idx_iot_station_geom ON iot_station USING GIST(geom);
|
||||
@@ -0,0 +1,189 @@
|
||||
-- =============================================
|
||||
-- 智慧水务管理系统 - 供水生产 + 巡检 + 报警 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);
|
||||
@@ -0,0 +1,164 @@
|
||||
-- =============================================
|
||||
-- 智慧水务管理系统 - 营业收费相关 DDL
|
||||
-- 版本: V1
|
||||
-- =============================================
|
||||
|
||||
-- 用水户
|
||||
CREATE TABLE IF NOT EXISTS rev_customer (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
customer_no VARCHAR(30) UNIQUE NOT NULL,
|
||||
customer_name VARCHAR(100) NOT NULL,
|
||||
customer_type VARCHAR(20) NOT NULL, -- residential/business/enterprise/institution
|
||||
area VARCHAR(50) NOT NULL,
|
||||
address VARCHAR(300),
|
||||
phone VARCHAR(20),
|
||||
id_card VARCHAR(18),
|
||||
contract_no VARCHAR(50),
|
||||
open_date DATE,
|
||||
meter_count INT DEFAULT 0,
|
||||
status VARCHAR(20) DEFAULT 'active', -- active/suspended/closed
|
||||
remark VARCHAR(500),
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE rev_customer IS '用水户表';
|
||||
|
||||
-- 水价阶梯
|
||||
CREATE TABLE IF NOT EXISTS rev_water_price (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
customer_type VARCHAR(20) NOT NULL, -- residential/business/enterprise/institution
|
||||
tier_no INT NOT NULL, -- 第几阶梯
|
||||
range_start DECIMAL(12,2) DEFAULT 0, -- 起始水量(立方米)
|
||||
range_end DECIMAL(12,2), -- 结束水量(null=无上限)
|
||||
water_price DECIMAL(10,4) NOT NULL, -- 水价(元/立方米)
|
||||
sewage_price DECIMAL(10,4) DEFAULT 0, -- 污水处理费
|
||||
effective_date DATE NOT NULL,
|
||||
status SMALLINT DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE rev_water_price IS '水价阶梯配置表';
|
||||
|
||||
-- 水表档案
|
||||
CREATE TABLE IF NOT EXISTS rev_meter (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
meter_no VARCHAR(50) UNIQUE NOT NULL,
|
||||
customer_id BIGINT REFERENCES rev_customer(id),
|
||||
device_id BIGINT, -- 关联 IoT 设备
|
||||
caliber VARCHAR(10), -- DN15/DN20/DN40/DN80+
|
||||
meter_type VARCHAR(20), -- mechanical/ultrasonic/electromagnetic
|
||||
manufacturer VARCHAR(100),
|
||||
max_reading DECIMAL(10,2) DEFAULT 99999,
|
||||
initial_reading DECIMAL(10,2) DEFAULT 0,
|
||||
current_reading DECIMAL(10,2) DEFAULT 0,
|
||||
install_date DATE,
|
||||
install_address VARCHAR(300),
|
||||
status VARCHAR(20) DEFAULT 'active', -- active/dismantled/scrapped/repaired/warehouse
|
||||
remark VARCHAR(500),
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE rev_meter IS '水表档案表';
|
||||
|
||||
-- 水表操作记录(全生命周期)
|
||||
CREATE TABLE IF NOT EXISTS rev_meter_log (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
meter_id BIGINT REFERENCES rev_meter(id),
|
||||
operation_type VARCHAR(30) NOT NULL, -- install/dismantle/repair/change/scrap/calibrate/refurbish
|
||||
old_reading DECIMAL(10,2),
|
||||
new_reading DECIMAL(10,2),
|
||||
new_meter_no VARCHAR(50),
|
||||
operator_id BIGINT,
|
||||
operator_name VARCHAR(50),
|
||||
photos JSONB, -- 现场照片URL数组
|
||||
remark VARCHAR(500),
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE rev_meter_log IS '水表操作记录表(全生命周期)';
|
||||
|
||||
-- 抄表记录
|
||||
CREATE TABLE IF NOT EXISTS rev_reading (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
meter_id BIGINT REFERENCES rev_meter(id),
|
||||
reading_date DATE NOT NULL,
|
||||
reading_period VARCHAR(10), -- 2026-06
|
||||
prev_reading DECIMAL(10,2),
|
||||
curr_reading DECIMAL(10,2),
|
||||
consumption DECIMAL(10,2),
|
||||
read_type VARCHAR(20) DEFAULT 'manual', -- manual/remote/estimate
|
||||
reader_id BIGINT,
|
||||
reader_name VARCHAR(50),
|
||||
photo_urls JSONB, -- 拍照图片URL数组
|
||||
abnormal_flag SMALLINT DEFAULT 0, -- 0:正常 1:异常
|
||||
verified SMALLINT DEFAULT 0, -- 0:未审核 1:已审核
|
||||
verified_by BIGINT,
|
||||
verified_at TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE rev_reading IS '抄表记录表';
|
||||
CREATE INDEX IF NOT EXISTS idx_reading_period ON rev_reading(reading_period);
|
||||
|
||||
-- 水费账单
|
||||
CREATE TABLE IF NOT EXISTS rev_bill (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
bill_no VARCHAR(30) UNIQUE NOT NULL,
|
||||
customer_id BIGINT REFERENCES rev_customer(id),
|
||||
meter_id BIGINT REFERENCES rev_meter(id),
|
||||
reading_id BIGINT REFERENCES rev_reading(id),
|
||||
bill_period VARCHAR(10) NOT NULL, -- 2026-06
|
||||
prev_reading DECIMAL(10,2),
|
||||
curr_reading DECIMAL(10,2),
|
||||
consumption DECIMAL(10,2),
|
||||
water_fee DECIMAL(10,2),
|
||||
sewage_fee DECIMAL(10,2),
|
||||
other_fee DECIMAL(10,2) DEFAULT 0, -- 污水处理费/垃圾处理费等
|
||||
total_fee DECIMAL(10,2),
|
||||
paid_fee DECIMAL(10,2) DEFAULT 0,
|
||||
discount_fee DECIMAL(10,2) DEFAULT 0,
|
||||
status VARCHAR(20) DEFAULT 'pending', -- pending/partial/paid/overdue/cancelled
|
||||
due_date DATE,
|
||||
paid_at TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE rev_bill IS '水费账单表';
|
||||
CREATE INDEX IF NOT EXISTS idx_bill_customer ON rev_bill(customer_id, bill_period);
|
||||
CREATE INDEX IF NOT EXISTS idx_bill_status ON rev_bill(status);
|
||||
|
||||
-- 缴费记录
|
||||
CREATE TABLE IF NOT EXISTS rev_payment (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
bill_id BIGINT REFERENCES rev_bill(id),
|
||||
customer_id BIGINT REFERENCES rev_customer(id),
|
||||
payment_no VARCHAR(50) UNIQUE NOT NULL,
|
||||
amount DECIMAL(10,2) NOT NULL,
|
||||
pay_method VARCHAR(20), -- wechat/alipay/cash/bank_transfer/pos
|
||||
pay_channel VARCHAR(30), -- counter/app/wechat_mini/third_party
|
||||
transaction_id VARCHAR(100),
|
||||
operator_id BIGINT,
|
||||
remark VARCHAR(500),
|
||||
paid_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE rev_payment IS '缴费记录表';
|
||||
|
||||
-- 报装申请
|
||||
CREATE TABLE IF NOT EXISTS rev_install (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
application_no VARCHAR(30) UNIQUE NOT NULL,
|
||||
applicant_name VARCHAR(50) NOT NULL,
|
||||
applicant_phone VARCHAR(20) NOT NULL,
|
||||
applicant_id_card VARCHAR(18),
|
||||
area VARCHAR(50),
|
||||
address VARCHAR(300),
|
||||
customer_type VARCHAR(20), -- residential/business/enterprise
|
||||
caliber VARCHAR(10), -- 申请管径
|
||||
purpose VARCHAR(200),
|
||||
status VARCHAR(20) DEFAULT 'pre_apply', -- pre_apply/engineering/pending_review/approved/rejected/completed
|
||||
survey_date DATE,
|
||||
survey_result TEXT,
|
||||
approved_by BIGINT,
|
||||
approved_at TIMESTAMP,
|
||||
completed_at TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
COMMENT ON TABLE rev_install IS '报装申请表';
|
||||
@@ -0,0 +1,79 @@
|
||||
-- =============================================
|
||||
-- 种子数据:管理员 + 基础角色 + 字典
|
||||
-- =============================================
|
||||
|
||||
-- 插入部门
|
||||
INSERT INTO sys_dept (id, parent_id, dept_name, dept_type, sort_order) VALUES
|
||||
(1, NULL, '精河县水利局', 'water_bureau', 1),
|
||||
(2, NULL, '安阜清源水务公司', 'water_company', 2),
|
||||
(3, 2, '一体化水厂', 'water_company', 1),
|
||||
(4, 2, '精芒片区', 'water_company', 2),
|
||||
(5, 2, '八家户片区', 'water_company', 3),
|
||||
(6, 2, '托里片区', 'water_company', 4),
|
||||
(7, 2, '大镇阿合其片区', 'water_company', 5),
|
||||
(8, 2, '托托片区', 'water_company', 6),
|
||||
(9, 2, '运维中心', 'ops', 7)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- 重置序列
|
||||
SELECT setval('sys_dept_id_seq', (SELECT MAX(id) FROM sys_dept));
|
||||
|
||||
-- 插入角色
|
||||
INSERT INTO sys_role (id, role_name, role_key, role_sort, data_scope, remark) VALUES
|
||||
(1, '系统管理员', 'admin', 1, 'ALL', '最高权限,管理全部功能'),
|
||||
(2, '水务分管领导', 'leader', 2, 'ALL', '查看全部数据、BI看板'),
|
||||
(3, '水务业务管理人员', 'manager', 3, 'DEPT', '调度、营收、水质管理'),
|
||||
(4, '现场运维操作人员', 'operator', 4, 'DEPT', '巡检、值班、工单处理'),
|
||||
(5, '系统技术维护人员', 'tech', 5, 'DEPT', '配置管理、设备维护')
|
||||
ON CONFLICT (role_key) DO NOTHING;
|
||||
|
||||
-- 插入管理员用户 (密码: admin123, BCrypt加密)
|
||||
INSERT INTO sys_user (id, dept_id, username, password, real_name, role_type, status) VALUES
|
||||
(1, 1, 'admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt6Z5Eh', '系统管理员', 'admin', 1)
|
||||
ON CONFLICT (username) DO NOTHING;
|
||||
|
||||
-- 管理员关联角色
|
||||
INSERT INTO sys_user_role (user_id, role_id) VALUES (1, 1) ON CONFLICT DO NOTHING;
|
||||
|
||||
-- 插入字典类型
|
||||
INSERT INTO sys_dict_type (id, dict_key, dict_name) VALUES
|
||||
(1, 'device_type', '设备类型'),
|
||||
(2, 'area', '片区'),
|
||||
(3, 'customer_type', '用水户类型'),
|
||||
(4, 'alert_level', '报警等级'),
|
||||
(5, 'meter_status', '水表状态')
|
||||
ON CONFLICT (dict_key) DO NOTHING;
|
||||
|
||||
-- 插入字典数据
|
||||
INSERT INTO sys_dict_data (dict_type_id, dict_label, dict_value, sort_order) VALUES
|
||||
-- 设备类型
|
||||
(1, '流量计', 'flow_meter', 1),
|
||||
(1, '压力传感器', 'pressure_sensor', 2),
|
||||
(1, '电动阀门', 'valve', 3),
|
||||
(1, '水质监测仪', 'water_quality', 4),
|
||||
(1, '液位计', 'level_sensor', 5),
|
||||
(1, '水泵', 'pump', 6),
|
||||
-- 片区
|
||||
(2, '一体化水厂', '一体化水厂', 1),
|
||||
(2, '精芒片区', '精芒片区', 2),
|
||||
(2, '八家户片区', '八家户片区', 3),
|
||||
(2, '托里片区', '托里片区', 4),
|
||||
(2, '大镇阿合其片区', '大镇阿合其片区', 5),
|
||||
(2, '托托片区', '托托片区', 6),
|
||||
-- 用水户类型
|
||||
(3, '居民', 'residential', 1),
|
||||
(3, '商业', 'business', 2),
|
||||
(3, '企业', 'enterprise', 3),
|
||||
(3, '事业单位', 'institution', 4),
|
||||
-- 报警等级
|
||||
(4, '提示', 'info', 1),
|
||||
(4, '一般', 'warning', 2),
|
||||
(4, '严重', 'critical', 3),
|
||||
(4, '紧急', 'emergency', 4),
|
||||
-- 水表状态
|
||||
(5, '正常使用', 'active', 1),
|
||||
(5, '已拆除', 'dismantled', 2),
|
||||
(5, '已报废', 'scrapped', 3),
|
||||
(5, '维修中', 'repaired', 4),
|
||||
(5, '库存', 'warehouse', 5)
|
||||
ON CONFLICT DO NOTHING;
|
||||
@@ -0,0 +1,68 @@
|
||||
-- =============================================
|
||||
-- 智慧水务管理系统 - TDengine 建表脚本
|
||||
-- 用于物联网设备遥测数据存储
|
||||
-- =============================================
|
||||
|
||||
-- 创建数据库
|
||||
CREATE DATABASE IF NOT EXISTS water_iot
|
||||
KEEP 365
|
||||
DURATION 30
|
||||
BUFFER 256
|
||||
PAGES 256
|
||||
PAGESIZE 4
|
||||
WAL_LEVEL 1;
|
||||
|
||||
USE water_iot;
|
||||
|
||||
-- 遥测数据超级表
|
||||
CREATE STABLE IF NOT EXISTS iot_telemetry (
|
||||
ts TIMESTAMP,
|
||||
device_sn NCHAR(100),
|
||||
metric_key NCHAR(50),
|
||||
metric_value DOUBLE,
|
||||
quality TINYINT
|
||||
) TAGS (
|
||||
device_type NCHAR(30),
|
||||
area NCHAR(50),
|
||||
station NCHAR(100)
|
||||
);
|
||||
|
||||
-- 按设备类型创建子表(模板,实际运行时动态创建)
|
||||
CREATE TABLE IF NOT EXISTS telemetry_flow_meter USING iot_telemetry TAGS('flow_meter', 'default', 'default');
|
||||
CREATE TABLE IF NOT EXISTS telemetry_pressure USING iot_telemetry TAGS('pressure_sensor', 'default', 'default');
|
||||
CREATE TABLE IF NOT EXISTS telemetry_valve USING iot_telemetry TAGS('valve', 'default', 'default');
|
||||
CREATE TABLE IF NOT EXISTS telemetry_water_quality USING iot_telemetry TAGS('water_quality', 'default', 'default');
|
||||
CREATE TABLE IF NOT EXISTS telemetry_level USING iot_telemetry TAGS('level_sensor', 'default', 'default');
|
||||
CREATE TABLE IF NOT EXISTS telemetry_pump USING iot_telemetry TAGS('pump', 'default', 'default');
|
||||
|
||||
-- 设备事件超级表
|
||||
CREATE STABLE IF NOT EXISTS iot_device_event (
|
||||
ts TIMESTAMP,
|
||||
device_sn NCHAR(100),
|
||||
event_type NCHAR(30),
|
||||
event_data NCHAR(2000)
|
||||
) TAGS (
|
||||
device_type NCHAR(30),
|
||||
area NCHAR(50)
|
||||
);
|
||||
|
||||
-- 小时聚合超级表(自动聚合)
|
||||
CREATE STABLE IF NOT EXISTS iot_telemetry_hourly (
|
||||
ts TIMESTAMP,
|
||||
device_sn NCHAR(100),
|
||||
metric_key NCHAR(50),
|
||||
min_value DOUBLE,
|
||||
max_value DOUBLE,
|
||||
avg_value DOUBLE,
|
||||
count_value INT
|
||||
) TAGS (
|
||||
device_type NCHAR(30),
|
||||
area NCHAR(50)
|
||||
);
|
||||
|
||||
-- 日聚合视图(示例)
|
||||
-- CREATE STREAM IF NOT EXISTS hourly_stream INTO iot_telemetry_hourly AS
|
||||
-- SELECT _wstart as ts, device_sn, metric_key,
|
||||
-- MIN(metric_value), MAX(metric_value), AVG(metric_value), COUNT(*)
|
||||
-- FROM iot_telemetry
|
||||
-- INTERVAL(1h);
|
||||
Reference in New Issue
Block a user