| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- -- 易积水点台账表(KingbaseES, schema app_user)
- --
- -- 背景:旧表 app_user.psgw_waterlogging_point 混了「监测点」口径的字段,存在三类问题:
- -- 1) time(数据时间)、waterlogging_count(易积水点数量)属于运行数据/派生值,
- -- 不该落在基础档案表里;
- -- 2) waterlogging_points 存多节点坐标 JSON,但一个易积水点在地图上就是一个位置,
- -- 应直接落 WGS84 经纬度;
- -- 3) equipment_id 实际存的是「视频设备 ID(equipment_base.equipment_type_id=20)」,
- -- 易积水点关联的是摄像头,不是通用监测设备,字段名应表达真实语义。
- --
- -- 本脚本做四件事:
- -- 1. 建新表 app_user.drainage_waterlogging_point;
- -- 2. 对「已建过表」的库幂等补列(见步骤 1.1),两种执行顺序都能到位;
- -- 3. 登记字典「风险等级」(积水程度沿用已有字典 drainage_waterlogging_level);
- -- 4. 从旧表迁移数据(坐标取 waterlogging_points 的第一个点;解析失败置 NULL)。
- --
- -- 字段口径刻意保持精简(不做全量台账):
- -- 基本 point_code / point_name / district / location / longitude / latitude
- -- 积水 waterlogging_level / water_depth / water_volume / water_area
- -- 管理 risk_level / duty_unit / duty_person / duty_phone
- -- (后三项为名称快照,另有 duty_dept_id / duty_user_id 指向 sys_dept / sys_user,
- -- 由 migration_drainage_waterlogging_duty.sql 维护)
- -- 关联其他 camera_ids / remark / 审计字段 / del_flag
- --
- -- 说明:
- -- · 旧表的 equipment_id 直接搬进 camera_ids。若历史数据里曾混入过普通监测设备 ID,
- -- 迁移后需要人工核对(旧页面早期版本确实调用过通用设备关联)。
- -- · 幂等:建表/补列/索引/字典均可重复执行;数据迁移仅在「新表为空」时执行一次。
- --
- -- 前置:结束上一次失败执行遗留的 aborted 事务(事务外执行只会告警,不报错)
- ROLLBACK;
- BEGIN;
- -- =====================================================================
- -- 1. 建新表
- -- =====================================================================
- CREATE TABLE IF NOT EXISTS app_user.drainage_waterlogging_point (
- point_id varchar(64) NOT NULL,
- point_code varchar(64),
- point_name varchar(200) NOT NULL,
- district varchar(100),
- location varchar(500),
- longitude numeric(12, 8),
- latitude numeric(12, 8),
- waterlogging_level int2 DEFAULT 0,
- water_depth numeric(10, 2),
- water_volume numeric(14, 2),
- water_area numeric(14, 2),
- risk_level varchar(8),
- duty_unit varchar(200),
- duty_person varchar(64),
- duty_phone varchar(32),
- duty_dept_id bigint,
- duty_user_id bigint,
- camera_ids varchar(500),
- remark varchar(500),
- create_by varchar(64),
- create_time timestamp,
- update_by varchar(64),
- update_time timestamp,
- del_flag char(1) DEFAULT '0',
- CONSTRAINT pk_drainage_waterlogging_point PRIMARY KEY (point_id)
- );
- -- ---------------------------------------------------------------------
- -- 1.1 幂等补列:兼容「表已按旧版本建过」的库
- -- 逐列判断后 ALTER,已存在的列直接跳过。
- -- ---------------------------------------------------------------------
- DO $$
- DECLARE
- col record;
- BEGIN
- IF to_regclass('app_user.drainage_waterlogging_point') IS NULL THEN
- RETURN;
- END IF;
- FOR col IN
- SELECT * FROM (VALUES
- ('water_depth', 'numeric(10,2)'),
- ('water_area', 'numeric(14,2)'),
- ('risk_level', 'varchar(8)'),
- ('duty_unit', 'varchar(200)'),
- ('duty_person', 'varchar(64)'),
- ('duty_phone', 'varchar(32)'),
- ('duty_dept_id', 'bigint'),
- ('duty_user_id', 'bigint')
- ) AS x(name, type)
- LOOP
- IF NOT EXISTS (
- SELECT 1 FROM information_schema.columns
- WHERE table_schema = 'app_user'
- AND table_name = 'drainage_waterlogging_point'
- AND column_name = col.name
- ) THEN
- EXECUTE format('ALTER TABLE app_user.drainage_waterlogging_point ADD COLUMN %I %s',
- col.name, col.type);
- RAISE NOTICE '已补列:%', col.name;
- END IF;
- END LOOP;
- END $$;
- COMMENT ON TABLE app_user.drainage_waterlogging_point IS '易积水点台账';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.point_id IS '点位ID(主键)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.point_code IS '点位编码';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.point_name IS '点位名称';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.district IS '所属区域';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.location IS '位置描述';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.longitude IS 'WGS84 经度';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.latitude IS 'WGS84 纬度';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.waterlogging_level IS '积水程度(字典 drainage_waterlogging_level:0未积水 1轻度 2中度 3严重)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.water_depth IS '积水深度(cm)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.water_volume IS '积水量(m³)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.water_area IS '积水面积(m²)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.risk_level IS '风险等级(字典 drainage_waterlogging_risk_level:0低风险 1中风险 2高风险)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.duty_unit IS '责任单位(名称快照,对应 duty_dept_id)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.duty_person IS '责任人(姓名快照,对应 duty_user_id)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.duty_phone IS '联系电话(快照,选人时取 sys_user.phonenumber)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.duty_dept_id IS '责任单位ID(sys_dept.dept_id)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.duty_user_id IS '责任人ID(sys_user.user_id)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.camera_ids IS '关联摄像头ID(equipment_base.equipment_id,多个用逗号分隔)';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.remark IS '备注';
- COMMENT ON COLUMN app_user.drainage_waterlogging_point.del_flag IS '删除标志(0正常 2删除)';
- CREATE INDEX IF NOT EXISTS idx_dwp_point_code ON app_user.drainage_waterlogging_point (point_code);
- CREATE INDEX IF NOT EXISTS idx_dwp_point_name ON app_user.drainage_waterlogging_point (point_name);
- CREATE INDEX IF NOT EXISTS idx_dwp_district ON app_user.drainage_waterlogging_point (district);
- CREATE INDEX IF NOT EXISTS idx_dwp_level ON app_user.drainage_waterlogging_point (waterlogging_level);
- CREATE INDEX IF NOT EXISTS idx_dwp_risk_level ON app_user.drainage_waterlogging_point (risk_level);
- -- =====================================================================
- -- 2. 字典:风险等级
- -- (积水程度沿用已有字典 drainage_waterlogging_level,本脚本不重复建)
- -- 注意:本库 sys_dict_data / sys_dict_type 是 MySQL 兼容 auto_increment,
- -- 自增计数器未随迁移数据推进,因此主键一律显式取 max+序号。
- -- =====================================================================
- INSERT INTO app_user.sys_dict_type
- (dict_id, dict_name, dict_type, status, create_by, create_time, remark)
- SELECT (SELECT COALESCE(MAX(dict_id), 0) FROM app_user.sys_dict_type) + 1,
- '易积水点风险等级', 'drainage_waterlogging_risk_level', '0', 'admin', CURRENT_TIMESTAMP,
- '风险等级:0低风险 1中风险 2高风险'
- WHERE NOT EXISTS (SELECT 1 FROM app_user.sys_dict_type WHERE dict_type = 'drainage_waterlogging_risk_level');
- UPDATE app_user.sys_dict_type
- SET dict_name = '易积水点风险等级',
- status = '0',
- update_by = 'admin',
- update_time = CURRENT_TIMESTAMP,
- remark = '风险等级:0低风险 1中风险 2高风险'
- WHERE dict_type = 'drainage_waterlogging_risk_level';
- DELETE FROM app_user.sys_dict_data WHERE dict_type = 'drainage_waterlogging_risk_level';
- INSERT INTO app_user.sys_dict_data
- (dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class,
- is_default, status, create_by, create_time, remark)
- SELECT (SELECT COALESCE(MAX(dict_code), 0) FROM app_user.sys_dict_data) + v.rn,
- v.dict_sort, v.dict_label, v.dict_value, 'drainage_waterlogging_risk_level',
- '', v.list_class, v.is_default, '0', 'admin', CURRENT_TIMESTAMP, v.remark
- FROM (VALUES
- (1, 1, '低风险', '0', 'success', 'Y', '风险等级:低风险'),
- (2, 2, '中风险', '1', 'warning', 'N', '风险等级:中风险'),
- (3, 3, '高风险', '2', 'danger', 'N', '风险等级:高风险')
- ) AS v(rn, dict_sort, dict_label, dict_value, list_class, is_default, remark)
- ORDER BY v.rn;
- -- =====================================================================
- -- 3. 旧表数据迁移(仅当新表为空时执行一次)
- -- 可迁移的只有旧表真实存在的语义:名称/区域/积水量/积水程度/摄像头/坐标。
- -- =====================================================================
- DO $$
- DECLARE
- v_idx integer := 0;
- r record;
- v_lng numeric(12, 8);
- v_lat numeric(12, 8);
- BEGIN
- IF to_regclass('app_user.psgw_waterlogging_point') IS NULL THEN
- RAISE NOTICE '旧表 app_user.psgw_waterlogging_point 不存在,跳过数据迁移';
- RETURN;
- END IF;
- IF EXISTS (SELECT 1 FROM app_user.drainage_waterlogging_point) THEN
- RAISE NOTICE '新表 app_user.drainage_waterlogging_point 已有数据,跳过迁移(避免重复导入)';
- RETURN;
- END IF;
- FOR r IN SELECT * FROM app_user.psgw_waterlogging_point LOOP
- v_idx := v_idx + 1;
- v_lng := NULL;
- v_lat := NULL;
- BEGIN
- IF r.waterlogging_points IS NOT NULL AND r.waterlogging_points <> '' THEN
- v_lng := (regexp_match(r.waterlogging_points, '"lng"\s*:\s*(-?[0-9]+(\.[0-9]+)?)'))[1]::numeric(12, 8);
- v_lat := (regexp_match(r.waterlogging_points, '"lat"\s*:\s*(-?[0-9]+(\.[0-9]+)?)'))[1]::numeric(12, 8);
- END IF;
- EXCEPTION WHEN OTHERS THEN
- v_lng := NULL;
- v_lat := NULL;
- END;
- INSERT INTO app_user.drainage_waterlogging_point (
- point_id, point_code, point_name, district, location,
- longitude, latitude, waterlogging_level, water_volume, camera_ids,
- create_by, create_time, update_by, update_time, del_flag
- ) VALUES (
- r.id,
- 'JSD-' || lpad(v_idx::text, 4, '0'),
- COALESCE(NULLIF(trim(r.name), ''), '未命名易积水点'),
- r.area,
- NULL,
- v_lng,
- v_lat,
- COALESCE(r.waterlogging_level, 0),
- r.water_volume,
- r.equipment_id,
- 'admin', COALESCE(r.create_time, CURRENT_TIMESTAMP),
- 'admin', COALESCE(r.update_time, r.create_time, CURRENT_TIMESTAMP),
- '0'
- );
- END LOOP;
- RAISE NOTICE '旧表数据迁移完成,共迁移 % 条', v_idx;
- EXCEPTION WHEN OTHERS THEN
- RAISE NOTICE '旧表数据迁移跳过:%', SQLERRM;
- END $$;
- -- =====================================================================
- -- 4. 结果核验(可选,取消注释执行)
- -- =====================================================================
- -- 风险等级分布
- -- SELECT risk_level, count(*) FROM app_user.drainage_waterlogging_point
- -- WHERE del_flag = '0' GROUP BY risk_level;
- -- 风险等级字典(应返回 3 行)
- -- SELECT dict_value, dict_label, list_class FROM app_user.sys_dict_data
- -- WHERE dict_type = 'drainage_waterlogging_risk_level' ORDER BY dict_sort;
- COMMIT;
|