Bladeren bron

增加近期修改脚本到init.sql

taosj 3 uur geleden
bovenliggende
commit
ac72c5da2f
3 gewijzigde bestanden met toevoegingen van 1048 en 0 verwijderingen
  1. 381 0
      doc/数据库脚本/backend_ddl_2026112.sql
  2. 665 0
      doc/数据库脚本/backend_dml_2026112.sql
  3. 2 0
      doc/数据库脚本/init.sql

+ 381 - 0
doc/数据库脚本/backend_ddl_2026112.sql

@@ -0,0 +1,381 @@
+-- 创建序列
+CREATE SEQUENCE IF NOT EXISTS data_ultra_short_term_power_forecasting_id_seq;
+
+DROP TABLE IF EXISTS data_ultra_short_term_power_forecasting;
+-- 建表语句
+CREATE TABLE data_ultra_short_term_power_forecasting (
+    _id BIGINT NOT NULL DEFAULT nextval('data_ultra_short_term_power_forecasting_id_seq'::regclass),
+    data_sourcegrab_id INTEGER NOT NULL,
+    data_sourcegrab_pattern_name VARCHAR(255) NOT NULL,
+    entity_id VARCHAR(255) NOT NULL,
+    entity_type INTEGER NOT NULL,
+    entity_name VARCHAR(255),
+    create_time INTEGER NOT NULL,
+    start_time INTEGER NOT NULL,
+    forecast_time INTEGER NOT NULL,
+    power VARCHAR(255),
+    power15 VARCHAR(255),
+    power30 VARCHAR(255),
+    power45 VARCHAR(255),
+    power60 VARCHAR(255),
+    power75 VARCHAR(255),
+    power90 VARCHAR(255),
+    power105 VARCHAR(255),
+    power120 VARCHAR(255),
+    power135 VARCHAR(255),
+    power150 VARCHAR(255),
+    power165 VARCHAR(255),
+    power180 VARCHAR(255),
+    power195 VARCHAR(255),
+    power210 VARCHAR(255),
+    power225 VARCHAR(255),
+    power240 VARCHAR(255),
+    CONSTRAINT data_ultra_short_term_power_forecasting_pkey PRIMARY KEY (_id)
+);
+
+-- 表注释
+COMMENT ON TABLE "public"."data_ultra_short_term_power_forecasting" IS '超短期功率预测数据表';
+
+-- 字段注释
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."_id" IS '唯一标识';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."data_sourcegrab_id" IS '数据源抓取ID';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."data_sourcegrab_pattern_name" IS '数据抓取模式名称';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."entity_id" IS '实体ID';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."entity_type" IS '实体类型(场站/交易主体/省域)';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."entity_name" IS '实体名称';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."create_time" IS '创建时间';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."start_time" IS '起报时间(日期)';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."forecast_time" IS '起报时间(日期)';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power" IS '实发功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power15" IS 't+15min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power30" IS 't+30min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power45" IS 't+45min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power60" IS 't+60min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power75" IS 't+75min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power90" IS 't+90min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power105" IS 't+105min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power120" IS 't+120min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power135" IS 't+135min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power150" IS 't+150min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power165" IS 't+165min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power180" IS 't+180min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power195" IS 't+195min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power210" IS 't+210min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power225" IS 't+225min预测功率';
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."power240" IS 't+240min预测功率';
+
+-- 超短期功率预报时间
+ALTER TABLE "public"."data_ultra_short_term_power_forecasting" ADD COLUMN IF NOT EXISTS "forecast_time" integer;
+COMMENT ON COLUMN "public"."data_ultra_short_term_power_forecasting"."forecast_time" IS '预报时间';
+
+CREATE SEQUENCE IF NOT EXISTS "public"."data_medium_term_power_forecast_raw__id_seq";
+
+DROP TABLE IF EXISTS "public"."data_medium_term_power_forecast_raw";
+CREATE TABLE "public"."data_medium_term_power_forecast_raw" (
+  "_id" integer NOT NULL DEFAULT nextval(
+    'data_medium_term_power_forecast_raw__id_seq'::regclass
+  ),
+  "latitude" character varying(255),
+  "longitude" character varying(255),
+  "data_org_type" character varying(255) NOT NULL,
+  "data_type" integer NOT NULL,
+  "business_process_type" integer NOT NULL,
+  "data_source" integer NOT NULL,
+  "data_sourcegrab_id" integer NOT NULL,
+  "data_sourcegrab_pattern_name" character varying(255) NOT NULL,
+  "data_model_id" integer NOT NULL,
+  "data_model_name" character varying(255) NOT NULL,
+  "source_id" integer NOT NULL,
+  "source_name" character varying(255) NOT NULL,
+  "entity_id" character varying(255) NOT NULL,
+  "entity_type" character varying(255) NOT NULL,
+  "create_time" integer NOT NULL,
+  "start_time" integer NOT NULL,
+  "forecast_time" integer NOT NULL,
+  "pre_days" integer NOT NULL,
+  "lead_time" integer NOT NULL,
+  "station_id" bigint,
+  "station_name" character varying(255),
+  "subject_id" integer,
+  "subject_name" character varying(255),
+  "machine_id" character varying(255),
+  "machine_name" character varying(255),
+  "analyze_his_id" integer,
+  "archive_record_id" integer,
+  "power" character varying(255)
+);
+
+COMMENT ON TABLE "public"."data_medium_term_power_forecast_raw" IS '中期功率原始数据表';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."_id" IS '唯一标识';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."latitude" IS '经度';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."longitude" IS '纬度';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."data_org_type" IS '数据种类:单点时间序列';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."data_type" IS '数据类型:短期气象';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."business_process_type" IS '数据业务类型:原始';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."data_source" IS '数据来源';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."data_sourcegrab_id" IS '数据源抓取ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."data_sourcegrab_pattern_name" IS '数据抓取模式名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."data_model_id" IS '数据模型ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."data_model_name" IS '数据模型名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."source_id" IS '数据源ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."source_name" IS '数据源名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."entity_id" IS '实体ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."entity_type" IS '实体类型';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."create_time" IS '创建时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."start_time" IS '起报时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."forecast_time" IS '预测时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."pre_days" IS '预报天数';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."lead_time" IS '预报时效';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."station_id" IS '场站ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."station_name" IS '场站名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."subject_id" IS '交易主题ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."subject_name" IS '交易主题名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."machine_id" IS '风机ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."machine_name" IS '风机名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."analyze_his_id" IS '文件解析ID:文件解析时存在';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."archive_record_id" IS '文件归档ID:文件解析时存在';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_raw"."power" IS '预测功率';
+
+CREATE SEQUENCE IF NOT EXISTS "public"."data_medium_term_power_forecast_issued__id_seq";
+
+DROP TABLE IF EXISTS "public"."data_medium_term_power_forecast_issued";
+CREATE TABLE "public"."data_medium_term_power_forecast_issued" (
+  "_id" integer NOT NULL DEFAULT nextval(
+    'data_medium_term_power_forecast_issued__id_seq'::regclass
+  ),
+  "data_sourcegrab_id" integer NOT NULL,
+  "data_sourcegrab_pattern_name" character varying(255) NOT NULL,
+  "entity_id" character varying(255) NOT NULL,
+  "entity_type" integer NOT NULL,
+  "entity_name" character varying(255),
+  "create_time" integer NOT NULL,
+  "start_time" integer NOT NULL,
+  "forecast_time" integer NOT NULL,
+  "predays" integer NOT NULL,
+  "power" character varying(255)
+);
+
+COMMENT ON TABLE "public"."data_medium_term_power_forecast_issued" IS '中期功率下发数据表';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_issued"."_id" IS '唯一标识';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_issued"."data_sourcegrab_id" IS '数据源抓取ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_issued"."data_sourcegrab_pattern_name" IS '数据抓取模式名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_issued"."entity_id" IS '实体ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_issued"."entity_type" IS '实体类型';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_issued"."entity_name" IS '实体名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_issued"."create_time" IS '创建时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_issued"."start_time" IS '起报时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_issued"."forecast_time" IS '预测时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_issued"."predays" IS '预报天数';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_issued"."power" IS '预测功率';
+
+
+CREATE SEQUENCE IF NOT EXISTS "public"."data_medium_term_power_forecast_correct__id_seq";
+DROP TABLE IF EXISTS "public"."data_medium_term_power_forecast_correct";
+CREATE TABLE "public"."data_medium_term_power_forecast_correct" (
+  "_id" integer NOT NULL DEFAULT nextval(
+    'data_medium_term_power_forecast_correct__id_seq'::regclass
+  ),
+  "data_sourcegrab_id" integer NOT NULL,
+  "data_sourcegrab_pattern_name" character varying(255) NOT NULL,
+  "entity_id" character varying(255) NOT NULL,
+  "entity_type" integer NOT NULL,
+  "entity_name" character varying(255),
+  "create_time" integer NOT NULL,
+  "start_time" integer NOT NULL,
+  "forecast_time" integer NOT NULL,
+  "predays" integer NOT NULL,
+  "power" character varying(255)
+);
+
+COMMENT ON TABLE "public"."data_medium_term_power_forecast_correct" IS '中期功率修正数据表';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_correct"."_id" IS '唯一标识';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_correct"."data_sourcegrab_id" IS '数据源抓取ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_correct"."data_sourcegrab_pattern_name" IS '数据抓取模式名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_correct"."entity_id" IS '实体ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_correct"."entity_type" IS '实体类型';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_correct"."entity_name" IS '实体名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_correct"."create_time" IS '创建时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_correct"."start_time" IS '起报时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_correct"."forecast_time" IS '预测时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_correct"."predays" IS '预报天数';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_correct"."power" IS '预测功率';
+
+
+CREATE SEQUENCE IF NOT EXISTS "public"."data_medium_term_power_forecast_report__id_seq";
+DROP TABLE IF EXISTS "public"."data_medium_term_power_forecast_report";
+CREATE TABLE "public"."data_medium_term_power_forecast_report" (
+  "_id" integer NOT NULL DEFAULT nextval(
+    'data_medium_term_power_forecast_report__id_seq'::regclass
+  ),
+  "data_sourcegrab_id" integer NOT NULL,
+  "data_sourcegrab_pattern_name" character varying(255) NOT NULL,
+  "entity_id" character varying(255) NOT NULL,
+  "entity_type" integer NOT NULL,
+  "entity_name" character varying(255),
+  "create_time" integer NOT NULL,
+  "start_time" integer NOT NULL,
+  "forecast_time" integer NOT NULL,
+  "predays" integer NOT NULL,
+  "power" character varying(255)
+);
+
+COMMENT ON TABLE "public"."data_medium_term_power_forecast_report" IS '中期功率上报数据表';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_report"."_id" IS '唯一标识';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_report"."data_sourcegrab_id" IS '数据源抓取ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_report"."data_sourcegrab_pattern_name" IS '数据抓取模式名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_report"."entity_id" IS '实体ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_report"."entity_type" IS '实体类型';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_report"."entity_name" IS '实体名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_report"."create_time" IS '创建时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_report"."start_time" IS '起报时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_report"."forecast_time" IS '预测时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_report"."predays" IS '预报天数';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_report"."power" IS '预测功率';
+
+
+CREATE SEQUENCE IF NOT EXISTS "public"."data_medium_term_power_forecast_back__id_seq";
+DROP TABLE IF EXISTS "public"."data_medium_term_power_forecast_back";
+CREATE TABLE "public"."data_medium_term_power_forecast_back" (
+  "_id" integer NOT NULL DEFAULT nextval(
+    'data_medium_term_power_forecast_back__id_seq'::regclass
+  ),
+  "data_sourcegrab_id" integer NOT NULL,
+  "data_sourcegrab_pattern_name" character varying(255) NOT NULL,
+  "entity_id" character varying(255) NOT NULL,
+  "entity_type" integer NOT NULL,
+  "entity_name" character varying(255),
+  "create_time" integer NOT NULL,
+  "start_time" integer NOT NULL,
+  "forecast_time" integer NOT NULL,
+  "predays" integer NOT NULL,
+  "power" character varying(255)
+);
+
+COMMENT ON TABLE "public"."data_medium_term_power_forecast_back" IS '中期功率回传数据表';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_back"."_id" IS '唯一标识';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_back"."data_sourcegrab_id" IS '数据源抓取ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_back"."data_sourcegrab_pattern_name" IS '数据抓取模式名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_back"."entity_id" IS '实体ID';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_back"."entity_type" IS '实体类型';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_back"."entity_name" IS '实体名称';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_back"."create_time" IS '创建时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_back"."start_time" IS '起报时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_back"."forecast_time" IS '预测时间';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_back"."predays" IS '预报天数';
+
+COMMENT ON COLUMN "public"."data_medium_term_power_forecast_back"."power" IS '预测功率';
+
+-- JSON 数组配置可能超过 dict_value 原长度(VARCHAR(100)), 扩容(可重复执行)
+ALTER TABLE sys_dict_data ALTER COLUMN dict_value TYPE VARCHAR(2000);
+
+ALTER TABLE "public"."sys_dict_data" ALTER COLUMN "dict_value" DROP DEFAULT, 
+ALTER COLUMN "dict_value" TYPE character varying(1000) USING "dict_value"::character varying(1000), 
+ALTER COLUMN "dict_value" SET DEFAULT '';
+
+-- -----------------------------------------------------
+-- 1. 待处理文件表 data_file_sync_files
+-- -----------------------------------------------------
+CREATE TABLE IF NOT EXISTS data_file_sync_files (
+    id SERIAL NOT NULL,
+    type VARCHAR(64),
+    file VARCHAR(1024) NOT NULL,
+    status INTEGER NOT NULL DEFAULT 0,
+    handler VARCHAR(255),
+    create_time TIMESTAMP NOT NULL DEFAULT now(),
+    update_time TIMESTAMP NOT NULL DEFAULT now(),
+    fail_reason VARCHAR(1024),
+    process_times INTEGER NOT NULL DEFAULT 0,
+    priority INTEGER NOT NULL DEFAULT 3,
+    CONSTRAINT pk_data_file_sync_files PRIMARY KEY (id)
+);
+
+-- 文件路径查重保险(扫描任务按 file 去重插入)
+CREATE UNIQUE INDEX IF NOT EXISTS uk_data_file_sync_files_file ON data_file_sync_files (file);
+
+COMMENT ON TABLE data_file_sync_files IS '待处理数据文件同步';
+COMMENT ON COLUMN data_file_sync_files.id IS '唯一标识';
+COMMENT ON COLUMN data_file_sync_files.type IS '类型';
+COMMENT ON COLUMN data_file_sync_files.file IS '文件(完整路径)';
+COMMENT ON COLUMN data_file_sync_files.status IS '状态(0待处理,1处理中,2完成,99失败,-1取消)';
+COMMENT ON COLUMN data_file_sync_files.handler IS '处理器bean名称';
+COMMENT ON COLUMN data_file_sync_files.create_time IS '创建时间';
+COMMENT ON COLUMN data_file_sync_files.update_time IS '更新时间';
+COMMENT ON COLUMN data_file_sync_files.fail_reason IS '失败原因';
+COMMENT ON COLUMN data_file_sync_files.process_times IS '处理次数';
+COMMENT ON COLUMN data_file_sync_files.priority IS '优先级';
+
+-- 增加告警类别字段(幂等)
+ALTER TABLE alarm_event_record ADD COLUMN IF NOT EXISTS alarm_category VARCHAR(50);
+COMMENT ON COLUMN alarm_event_record.alarm_category IS '告警类别';

+ 665 - 0
doc/数据库脚本/backend_dml_2026112.sql

@@ -0,0 +1,665 @@
+-- 短期功率预测
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '短期功率预测',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '功率预测'),
+  4, 'short-term-power', 'ufo/electricity/forecast/ShortTermPowerForecasting', '', 'ShortTermPowerForecasting', 1, 0, 'C', '0', '0', 'electricity:forecast:shorttermpower', 'area-chart', 'admin', now(), '', NULL, '短期功率预测菜单'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '短期功率预测');
+
+-- 超短期功率预测
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '超短期功率预测',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '功率预测'),
+  4, 'ultra-short-term-power', 'ufo/electricity/forecast/UltraShortTermPowerForecasting', '', 'UltraShortTermPowerForecasting', 1, 0, 'C', '0', '0', 'electricity:forecast:ultrashorttermpower', 'area-chart', 'admin', now(), '', NULL, '超短期功率预测菜单'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '超短期功率预测');
+
+-- 辐照度功率对比
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '辐照度功率对比',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '功率预测'),
+  9, 'irradiance-power-comparison', 'ufo/electricity/forecast/IrradiancePowerComparison', '', 'IrradiancePowerComparison', 1, 0, 'C', '0', '0', 'data:irradiancePowerComparison:list', 'BarChartOutlined', 'admin', '2026-08-31 00:00:00', '', NULL, ''
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '辐照度功率对比');
+
+-- 短期预测功率
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '短期预测功率',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '功率预测'),
+  9, 'powerForecastIssued', 'ufo/electricity/forecast/ShortTermPowerForecastIssued', '', 'ShortTermPowerForecastIssued', 1, 0, 'C', '0', '0', 'power:powerForecastIssued:list', 'chart', 'admin', '2026-08-31 00:00:00', '', NULL, ''
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '短期预测功率');
+
+-- 短期预测功率修正
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '短期预测功率修正',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '功率预测'),
+  11, 'shortTermPowerForecastCorrect', 'ufo/electricity/forecast/DataShortTermPowerForecastCorrect', '', 'DataShortTermPowerForecastCorrect', 1, 0, 'C', '0', '0', 'power:powerForecastCorrect:list', 'chart', 'admin', '2026-08-31 00:00:00', '', NULL, ''
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '短期预测功率修正');
+
+-- 超短期预测功率修正
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '超短期预测功率修正',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '功率预测'),
+  12, 'superShortTermForecastCorrect', 'ufo/electricity/forecast/DataSuperShortTermForecastCorrect', '', 'DataSuperShortTermForecastCorrect', 1, 0, 'C', '0', '0', 'supershort:dataSuperForecastCorrect:list', 'chart', 'admin', '2026-08-31 00:00:00', '', NULL, ''
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '超短期预测功率修正');
+
+-- 超短期预测功率
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '超短期预测功率',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '功率预测'),
+  10, 'superShortTermForecastIssued', 'ufo/electricity/forecast/DataSuperShortTermForecastIssued', '', 'DataSuperShortTermForecastIssued', 1, 0, 'C', '0', '0', 'supershort:dataSuperForecastIssued:list', 'chart', 'admin', '2026-08-31 00:00:00', '', NULL, ''
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '超短期预测功率');
+
+-- 光伏电场累计报表数据采集频率配置(单位:秒)
+INSERT INTO "public"."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
+    NULL, COALESCE((SELECT MAX(dict_sort) + 1 FROM sys_dict_data WHERE dict_type = 'data_local_frequency'), 1),
+    '15分钟', '900', 'data_local_frequency', '', 'default', 'N', '0', 'admin', NOW(),
+    '数据采集频率(秒)'
+WHERE NOT EXISTS (
+    SELECT 1 FROM sys_dict_data WHERE dict_type = 'data_local_frequency' AND dict_value = '900'
+);
+
+-- 隐藏、修复菜单
+UPDATE "public"."sys_menu" set status = 1 where menu_name in ('多源多模型预测', '理论功率预测');
+update "public"."sys_menu" set menu_name = '湿度曲线图' where menu_name = '温度曲线图' and menu_id = 2074;
+update "public"."sys_menu" set menu_name = '气压曲线图' where menu_name = '湿度曲线图' and menu_id = 2075;
+update "public"."sys_menu" set menu_name = '辐照曲线图' where menu_name = '气压曲线图' and menu_id = 2076;
+update "public"."sys_menu" set menu_name = '功率预测' where menu_name = '预报管理' and menu_id = 2007;
+update "public"."sys_menu" set status =  1 where menu_name = '发电量预测' and menu_id = 2010;
+update "public"."sys_menu" set status =  1 where menu_name = '短期预测功率' and menu_id = 2083;
+update "public"."sys_menu" set status =  1 where menu_name = '超短期预测功率' and menu_id = 2084;
+update "public"."sys_menu" set menu_name = '短期功率预测修正' where menu_name = '短期预测功率修正' and menu_id = 2085;
+update "public"."sys_menu" set menu_name = '超短期功率预测修正' where menu_name = '超短期预测功率修正' and menu_id = 2086;
+update "public"."sys_menu" set parent_id =  SELECT 1, (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '功率预测') where menu_name = '辐照度功率对比';
+
+-- 新加菜单
+DELETE FROM sys_role_menu t where t.menu_id
+in (
+SELECT menu_id from sys_menu where menu_name in (
+'数据报表',
+'短期预测日报',
+'短期预测月报',
+'短期预测年报',
+'超短期预测日报',
+'超短期预测月报',
+'超短期预测年报',
+'光伏电场累计日报',
+'光伏电场累计月报',
+'光伏电场累计年报',
+'光伏气象资源数据报表',
+'辐照度累计值报表'
+)
+);
+
+delete from sys_menu where menu_name in (
+'数据报表',
+'短期预测日报',
+'短期预测月报',
+'短期预测年报',
+'超短期预测日报',
+'超短期预测月报',
+'超短期预测年报',
+'光伏电场累计日报',
+'光伏电场累计月报',
+'光伏电场累计年报',
+'光伏气象资源数据报表',
+'辐照度累计值报表'
+);
+
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT 
+nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'数据报表', 0, 15, 'datareport', '', '', '', 1, 0, 'M', '0', '0', '', 'PieChartOutlined', 'admin', now(), '', NULL, '短期预测日报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '数据报表');
+
+-- 短期预测日报
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT 
+nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'短期预测日报', 
+(select menu_id from sys_menu t where t.menu_name = '数据报表'), 
+3, 'short-term-forecast-daily', 'ufo/electricity/datareport/shorTermForecastDailyReport', '', 'ShorTermForecastDailyReport', 1, 0, 'C', '0', '0', 'data:shortTermForecastReport:daily', 'StockOutlined', 'admin', '2026-09-14 00:00:00', '', NULL, '短期预测日报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '短期预测日报');
+-- 短期预测月报
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'短期预测月报', 
+(select menu_id from sys_menu t where t.menu_name = '数据报表'), 
+4, 'short-term-forecast-monthly', 'ufo/electricity/datareport/shorTermForecastMonthlyReport', '', 'ShorTermForecastMonthlyReport', 1, 0, 'C', '0', '0', 'data:shortTermForecastReport:monthly', 'LineChartOutlined', 'admin', '2026-09-14 00:00:00', '', NULL, '短期预测月报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '短期预测月报');
+-- 短期预测年报
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'短期预测年报', 
+(select menu_id from sys_menu t where t.menu_name = '数据报表')
+, 5, 'short-term-forecast-yearly', 'ufo/electricity/datareport/shorTermForecastYearlyReport', '', 'ShorTermForecastYearlyReport', 1, 0, 'C', '0', '0', 'data:shortTermForecastReport:yearly', 'AreaChartOutlined', 'admin', '2026-09-14 00:00:00', '', NULL, '短期预测年报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '短期预测年报');
+-- 超短期预测日报
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'超短期预测日报', 
+(select menu_id from sys_menu t where t.menu_name = '数据报表')
+, 6, 'ultra-short-term-forecast-daily', 'ufo/electricity/datareport/ultraShortTermForecastDailyReport', '', 'UltraShorTermForecastDailyReport', 1, 0, 'C', '0', '0', 'data:ultraShortTermForecastReport:daily', 'StockOutlined', 'admin', '2026-09-14 00:00:00', '', NULL, '超短期预测日报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '超短期预测日报');
+-- 超短期预测月报
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'超短期预测月报', 
+(select menu_id from sys_menu t where t.menu_name = '数据报表')
+, 6, 'ultra-short-term-forecast-monthly', 'ufo/electricity/datareport/ultraShortTermForecastMonthlyReport', '', 'UltraShorTermForecastMonthlyReport', 1, 0, 'C', '0', '0', 'data:ultraShortTermForecastReport:monthly', 'LineChartOutlined', 'admin', '2026-09-14 00:00:00', '', NULL, '超短期预测月报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '超短期预测月报');
+-- 超短期预测年报
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'超短期预测年报', 
+(select menu_id from sys_menu t where t.menu_name = '数据报表')
+, 6, 'ultra-short-term-forecast-yearly', 'ufo/electricity/datareport/ultraShortTermForecastYearlyReport', '', 'UltraShorTermForecastYearlyReport', 1, 0, 'C', '0', '0', 'data:ultraShortTermForecastReport:yearly', 'AreaChartOutlined', 'admin', '2026-09-14 00:00:00', '', NULL, '超短期预测年报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '超短期预测年报');
+-- 光伏电场累计日报
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '光伏电场累计日报',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '数据报表'),
+  9, 'pv-plant-cumulative-daily', 'ufo/electricity/datareport/pvPlantCumulativeDailyReport', '', 'PvPlantCumulativeDailyReport', 1, 0, 'C', '0', '0', 'data:pvPlantCumulativeReport:daily', 'StockOutlined', 'admin', '2026-09-14 00:00:00', '', NULL, '光伏电场累计日报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '光伏电场累计日报');
+-- 光伏电场累计月报
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '光伏电场累计月报',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '数据报表'),
+  10, 'pv-plant-cumulative-monthly', 'ufo/electricity/datareport/pvPlantCumulativeMonthlyReport', '', 'PvPlantCumulativeMonthlyReport', 1, 0, 'C', '0', '0', 'data:pvPlantCumulativeReport:monthly', 'LineChartOutlined', 'admin', '2026-09-14 00:00:00', '', NULL, '光伏电场累计月报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '光伏电场累计月报');
+-- 光伏电场累计年报
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '光伏电场累计年报',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '数据报表'),
+  11, 'pv-plant-cumulative-yearly', 'ufo/electricity/datareport/pvPlantCumulativeYearlyReport', '', 'PvPlantCumulativeYearlyReport', 1, 0, 'C', '0', '0', 'data:pvPlantCumulativeReport:yearly', 'AreaChartOutlined', 'admin', '2026-09-14 00:00:00', '', NULL, '光伏电场累计年报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '光伏电场累计年报');
+-- 光伏气象资源数据报表
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '光伏气象资源数据报表',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '数据报表'),
+  12, 'pv-meteorological-resource-data', 'ufo/electricity/datareport/pvMeteorologicalResourceDataReport', '', 'PvMeteorologicalResourceDataReport', 1, 0, 'C', '0', '0', 'data:pvMeteorologicalResourceData:list', 'HeatMapOutlined', 'admin', '2026-09-14 00:00:00', '', NULL, '光伏气象资源数据报表页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '光伏气象资源数据报表');
+-- 辐照度累计值报表
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+  nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+  '辐照度累计值报表',
+  (SELECT menu_id FROM sys_menu t WHERE t.menu_name = '数据报表'),
+  13, 'cumulative-irradiance', 'ufo/electricity/datareport/cumulativeIrradianceDataReport', '', 'CumulativeIrradianceDataReport', 1, 0, 'C', '0', '0', 'data:cumulativeIrradiance:list', 'DotChartOutlined', 'admin', '2026-09-16 00:00:00', '', NULL, '辐照度累计值报表页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '辐照度累计值报表');
+
+
+INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, remark)
+SELECT
+nextval(pg_get_serial_sequence('sys_dict_type', 'dict_id')),
+'网关服务配置项', 'gateway_app_config', '0', 'admin', now(), '网关服务(gatewayapp)地址与接口配置, JSON格式'
+WHERE NOT EXISTS (SELECT 1 FROM sys_dict_type t WHERE t.dict_type = 'gateway_app_config');
+
+INSERT INTO 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
+nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')),
+1, '网关服务配置项', '{"baseUrl":"http://xxx","pointStateUrl":"/biz/point-state/real","channelStateExpressions":"#iValue != null and #iValue == 1","channelOperationUrl":"/biz/channel/control"}', 'gateway_app_config', '', '', 'Y', '0', 'admin', now(), 'JSON: baseUrl/pointStateUrl/channelStateExpressions/channelOperationUrl'
+WHERE NOT EXISTS (SELECT 1 FROM sys_dict_data t WHERE t.dict_type = 'gateway_app_config');
+
+-- 测点监测
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'测点监测', 
+(select menu_id from sys_menu t where t.menu_name = '实时监控')
+, 3, 'point-monitor', 'ufo/electricity/realtime/PointMonitor', '', 'PointMonitor', 1, 0, 'C', '0', '0', 'data:oointMonitor', 'MonitorOutlined', 'admin', now(), '', NULL, '测点监测页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '测点监测');
+
+-- 优化菜单名称
+update public.sys_menu set menu_name = '短期功率预测修正' where menu_name = '短期预测功率修正';
+update public.sys_menu set menu_name = '超短期功率预测修正' where menu_name = '超短期预测功率修正';
+update public.sys_menu set menu_name = '气象资源' where menu_name = '气象与灾害预警地图';
+-- 20260922
+UPDATE public.sys_menu set menu_name = '设备管理' where menu_name = '风机设备信息';
+update public.sys_menu set status = 1 where menu_name = '设备状态监控';
+
+-- 1. 中期功率预测(工作台,挂在"功率预测"菜单下)
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'中期功率预测',
+(SELECT menu_id FROM sys_menu t WHERE t.menu_name = '功率预测'),
+5, 'medium-term-power', 'ufo/electricity/forecast/MediumTermPowerForecasting', '', 'MediumTermPowerForecasting', 1, 0, 'C', '0', '0', 'electricity:forecast:mediumtermpower', 'area-chart', 'admin', now(), '', NULL, '中期功率预测菜单'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '中期功率预测');
+-- 2. 中期预测日报(挂在"数据报表"菜单下)
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'中期预测日报',
+(SELECT menu_id FROM sys_menu t WHERE t.menu_name = '数据报表'),
+10, 'medium-term-forecast-daily', 'ufo/electricity/datareport/mediumTermForecastDailyReport', '', 'MediumTermForecastDailyReport', 1, 0, 'C', '0', '0', 'data:mediumTermForecastReport:daily', 'StockOutlined', 'admin', now(), '', NULL, '中期预测日报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '中期预测日报');
+-- 3. 中期预测月报
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'中期预测月报',
+(SELECT menu_id FROM sys_menu t WHERE t.menu_name = '数据报表'),
+11, 'medium-term-forecast-monthly', 'ufo/electricity/datareport/mediumTermForecastMonthlyReport', '', 'MediumTermForecastMonthlyReport', 1, 0, 'C', '0', '0', 'data:mediumTermForecastReport:monthly', 'LineChartOutlined', 'admin', now(), '', NULL, '中期预测月报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '中期预测月报');
+-- 4. 中期预测年报
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT nextval(pg_get_serial_sequence('sys_menu', 'menu_id')),
+'中期预测年报',
+(SELECT menu_id FROM sys_menu t WHERE t.menu_name = '数据报表'),
+12, 'medium-term-forecast-yearly', 'ufo/electricity/datareport/mediumTermForecastYearlyReport', '', 'MediumTermForecastYearlyReport', 1, 0, 'C', '0', '0', 'data:mediumTermForecastReport:yearly', 'AreaChartOutlined', 'admin', now(), '', NULL, '中期预测年报页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '中期预测年报');
+
+
+update "public"."sys_menu" set order_num = 5 where menu_name = '中期功率预测';
+update "public"."sys_menu" set order_num = 6 where menu_name = '超短期功率预测';
+update "public"."sys_menu" set order_num = 11 where menu_name = '中期预测日报';
+update "public"."sys_menu" set order_num = 12 where menu_name = '中期预测月报';
+update "public"."sys_menu" set order_num = 13 where menu_name = '中期预测年报';
+update "public"."sys_menu" set order_num = 21 where menu_name = '超短期预测日报';
+update "public"."sys_menu" set order_num = 22 where menu_name = '超短期预测月报';
+update "public"."sys_menu" set order_num = 23 where menu_name = '超短期预测年报';
+update "public"."sys_menu" set order_num = 31 where menu_name = '光伏电场累计日报';
+update "public"."sys_menu" set order_num = 32 where menu_name = '光伏电场累计月报';
+update "public"."sys_menu" set order_num = 33 where menu_name = '光伏电场累计年报';
+update "public"."sys_menu" set order_num = 41 where menu_name = '光伏气象资源数据报表';
+update "public"."sys_menu" set order_num = 51 where menu_name = '辐照度累计值报表';
+
+INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, remark)
+SELECT
+nextval(pg_get_serial_sequence('sys_dict_type', 'dict_id')),
+'场站编码-文件映射', 'station_file_code_mapping', '0', 'admin', now(), '气象数据文件名编码到场站编码(config_station.station_code)的映射, JSON格式'
+WHERE NOT EXISTS (SELECT 1 FROM sys_dict_type t WHERE t.dict_type = 'station_file_code_mapping');
+
+INSERT INTO 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
+nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')),
+1, '场站编码-文件映射', '{"JMJD01":"JMJD01","YUWEI":"YUWEI","ZHONGXIN":"ZHONGXIN"}', 'station_file_code_mapping', '', '', 'Y', '0', 'admin', now(), 'JSON对象: key=文件名首段编码, value=场站编码'
+WHERE NOT EXISTS (SELECT 1 FROM sys_dict_data t WHERE t.dict_type = 'station_file_code_mapping');
+
+INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, remark)
+SELECT
+nextval(pg_get_serial_sequence('sys_dict_type', 'dict_id')),
+'数据文件同步配置', 'data_file_sync_config', '0', 'admin', now(), '气象、功率数据文件同步扫描目录配置'
+WHERE NOT EXISTS (SELECT 1 FROM sys_dict_type t WHERE t.dict_type = 'data_file_sync_config');
+
+INSERT INTO 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
+nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')),
+1, '文件同步配置', '[]', 'data_file_sync_config', '', '', 'Y', '0', 'admin', now(), 'JSON数组, 每项含 scanFolder/updateInterval/handler, type可选'
+WHERE NOT EXISTS (SELECT 1 FROM sys_dict_data t WHERE t.dict_type = 'data_file_sync_config');
+
+
+-- 1.3.1 江门 (JMJD01)
+INSERT INTO config_station (
+    station_name, station_code, superior_area_id, period_total,
+    longitude, latitude,
+    province_number, city_number, position,
+    installed_capacity, grid_connected_capacity, fans_pv_panelquantity,
+    elevation, operation_time, boosterstation_voltage_level,
+    booster_station_longitude, boosterstation_latitude,
+    responsible_person_name, responsible_person_phone,
+    is_enable, push_status, subject_total, is_full_power, is_del,
+    create_by, create_time, update_by, update_time,
+    station_type, system_power_uuid, area_id
+) select
+    '江门', 'JMJD01', 'EAST01', 0,
+    '113.135232', '22.555907',
+    '440700', '440700', '广东省江门市江海区东宁路91号',
+    4050, 4050, 8723,
+    '6', '2025-05-30', '10.5KV',
+    '113.135232', '22.555907',
+    '张工', '13800000000',
+    'true', 1, 1, '0', 'false',
+    'admin', NOW(), 'admin', NOW(),
+    1, '', 'EAST01'
+WHERE NOT EXISTS (SELECT 1 FROM config_station t WHERE t.station_code = 'JMJD01');
+
+-- 1.3.2 北流煜炜 (YUWEI)
+INSERT INTO config_station (
+    station_name, station_code, superior_area_id, period_total,
+    longitude, latitude,
+    province_number, city_number, position,
+    installed_capacity, grid_connected_capacity, fans_pv_panelquantity,
+    elevation, operation_time, boosterstation_voltage_level,
+    booster_station_longitude, boosterstation_latitude,
+    responsible_person_name, responsible_person_phone,
+    is_enable, push_status, subject_total, is_full_power, is_del,
+    create_by, create_time, update_by, update_time,
+    station_type, system_power_uuid, area_id
+) select
+    '北流煜炜', 'YUWEI', 'EAST01', 0,
+    '110.305066', '22.615142',
+    '450981', '450981', '广西壮族自治区玉林市北流市塘岸镇六和村241国道与和谐路交叉口东北 480 米处',
+    3000, 3000, 5567,
+    '108', '2025-04-30', '10.5KV',
+    '110.305066', '22.615142',
+    '', '',
+    'true', 1, 1, '0', 'false',
+    'admin', NOW(), 'admin', NOW(),
+    1, '', 'EAST01'
+WHERE NOT EXISTS (SELECT 1 FROM config_station t WHERE t.station_code = 'YUWEI');
+
+-- 1.3.3 清远忠信 (ZHONGXIN)
+INSERT INTO config_station (
+    station_name, station_code, superior_area_id, period_total,
+    longitude, latitude,
+    province_number, city_number, position,
+    installed_capacity, grid_connected_capacity, fans_pv_panelquantity,
+    elevation, operation_time, boosterstation_voltage_level,
+    booster_station_longitude, boosterstation_latitude,
+    responsible_person_name, responsible_person_phone,
+    is_enable, push_status, subject_total, is_full_power, is_del,
+    create_by, create_time, update_by, update_time,
+    station_type, system_power_uuid, area_id
+) select
+    '清远忠信', 'ZHONGXIN', 'EAST01', 0,
+    '112.996233', '23.542156',
+    '441802', '441802', '广东省清远市清城区石龙大道建滔循环经济工业园',
+    2250, 2250, 3980,
+    '13', '', '10.5KV',
+    '112.996233', '23.542156',
+    '', '',
+    'true', 1, 1, '0', 'false',
+    'admin', NOW(), 'admin', NOW(),
+    1, '', 'EAST01'
+WHERE NOT EXISTS (SELECT 1 FROM config_station t WHERE t.station_code = 'ZHONGXIN');
+
+
+-- ============================================================
+-- UPDATE 脚本 (站码已存在时执行)
+-- ============================================================
+
+-- 1.3.1 江门
+UPDATE config_station SET
+    station_name            = '江门',
+    superior_area_id        = 'EAST01',
+    period_total            = 0,
+    longitude               = '113.135232',
+    latitude                = '22.555907',
+    province_number         = '440700',
+    city_number             = '440700',
+    position                = '广东省江门市江海区东宁路91号',
+    installed_capacity      = 4050,
+    grid_connected_capacity = 4050,
+    fans_pv_panelquantity   = 8723,
+    elevation               = '6',
+    operation_time          = '2025-05-30',
+    boosterstation_voltage_level = '10.5KV',
+    booster_station_longitude = '113.135232',
+    boosterstation_latitude   = '22.555907',
+    responsible_person_name = '张工',
+    responsible_person_phone  = '13800000000',
+    is_enable               = 'true',
+    push_status             = 1,
+    subject_total           = 1,
+    is_full_power           = '0',
+    update_by               = 'admin',
+    update_time             = NOW(),
+    station_type            = 1,
+    system_power_uuid       = '',
+    area_id                 = 'EAST01'
+WHERE station_code = 'JMJD01';
+
+-- 1.3.2 北流煜炜
+UPDATE config_station SET
+    station_name            = '北流煜炜',
+    superior_area_id        = 'EAST01',
+    period_total            = 0,
+    longitude               = '110.305066',
+    latitude                = '22.615142',
+    province_number         = '450981',
+    city_number             = '450981',
+    position                = '广西壮族自治区玉林市北流市塘岸镇六和村241国道与和谐路交叉口东北 480 米处',
+    installed_capacity      = 3000,
+    grid_connected_capacity = 3000,
+    fans_pv_panelquantity   = 5567,
+    elevation               = '108',
+    operation_time          = '2025-04-30',
+    boosterstation_voltage_level = '10.5KV',
+    booster_station_longitude = '110.305066',
+    boosterstation_latitude   = '22.615142',
+    responsible_person_name = '',
+    responsible_person_phone  = '',
+    is_enable               = 'true',
+    push_status             = 1,
+    subject_total           = 1,
+    is_full_power           = '0',
+    update_by               = 'admin',
+    update_time             = NOW(),
+    station_type            = 1,
+    system_power_uuid       = '',
+    area_id                 = 'EAST01'
+WHERE station_code = 'YUWEI';
+
+-- 1.3.3 清远忠信
+UPDATE config_station SET
+    station_name            = '清远忠信',
+    superior_area_id        = 'EAST01',
+    period_total            = 0,
+    longitude               = '112.996233',
+    latitude                = '23.542156',
+    province_number         = '441802',
+    city_number             = '441802',
+    position                = '广东省清远市清城区石龙大道建滔循环经济工业园',
+    installed_capacity      = 2250,
+    grid_connected_capacity = 2250,
+    fans_pv_panelquantity   = 3980,
+    elevation               = '13',
+    operation_time          = '',
+    boosterstation_voltage_level = '10.5KV',
+    booster_station_longitude = '112.996233',
+    boosterstation_latitude   = '23.542156',
+    responsible_person_name = '',
+    responsible_person_phone  = '',
+    is_enable               = 'true',
+    push_status             = 1,
+    subject_total           = 1,
+    is_full_power           = '0',
+    update_by               = 'admin',
+    update_time             = NOW(),
+    station_type            = 1,
+    system_power_uuid       = '',
+    area_id                 = 'EAST01'
+WHERE station_code = 'ZHONGXIN';
+
+-- 几个菜单名称顺序调整
+UPDATE public.sys_menu
+SET order_num = CASE menu_name
+    WHEN '辐照度曲线' THEN 10
+    WHEN '光伏温度'   THEN 20
+    WHEN '光伏风速'   THEN 30
+    WHEN '光伏风向'   THEN 40
+    WHEN '光伏湿度'   THEN 50
+    WHEN '光伏气压'   THEN 60
+    ELSE order_num
+END
+WHERE menu_name IN (
+    '辐照度曲线',
+    '光伏温度',
+    '光伏风速',
+    '光伏风向',
+    '光伏湿度',
+    '光伏气压'
+);
+-- 菜单名称调整
+update "public"."sys_menu" set menu_name = '辐照度' where menu_name = '辐照度曲线';
+update "public"."sys_menu" set menu_name = '风向' where menu_name = '光伏风向';
+update "public"."sys_menu" set menu_name = '风速' where menu_name = '光伏风速';
+update "public"."sys_menu" set menu_name = '温度' where menu_name = '光伏温度';
+update "public"."sys_menu" set menu_name = '湿度' where menu_name = '光伏湿度';
+update "public"."sys_menu" set menu_name = '气压' where menu_name = '光伏气压';
+update "public"."sys_menu" set order_num = 10 where menu_name = '超短期功率预测';
+update "public"."sys_menu" set order_num = 20 where menu_name = '短期功率预测';
+update "public"."sys_menu" set order_num = 30 where menu_name = '中期功率预测';
+update "public"."sys_menu" set order_num = 40 where menu_name = '辐照度功率对比';
+update "public"."sys_menu" set order_num = 50 where menu_name = '超短期功率预测修正';
+update "public"."sys_menu" set order_num = 60 where menu_name = '短期功率预测修正';
+
+-- 中期功率预测修正菜单
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT 
+(SELECT COALESCE(MAX(menu_id), 0) + 1 FROM sys_menu),
+'中期功率预测修正', 
+(select menu_id from sys_menu t where t.menu_name = '功率预测'), 
+70, 'mediumTermPowerForecastCorrect', 'ufo/electricity/forecast/DataMediumTermPowerForecastCorrect', '', 'DataMediumTermPowerForecastCorrect', 1, 0, 'C', '0', '0', 'mediumterm:powerForecastCorrect:list', 'StockOutlined', 'admin', '2026-09-14 00:00:00', '', NULL, '中期功率预测修正'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '中期功率预测修正');
+update sys_menu set icon = 'StockOutlined' where menu_name = '超短期功率预测修正';
+update sys_menu set icon = 'StockOutlined' where menu_name = '短期功率预测修正';
+
+-- 功率误差统计菜单补丁(幂等,可重复执行)
+-- 增加 统计分析 一级目录菜单
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+(SELECT COALESCE(MAX(menu_id), 0) + 1 FROM sys_menu),
+'统计分析', 0, 20, 'statanalysis', '', '', '', 1, 0, 'M', '0', '0', '', 'BarChartOutlined', 'admin', now(), '', NULL, '统计分析'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '统计分析' AND t.parent_id = 0);
+
+-- 增加 功率误差统计 二级菜单
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+(SELECT COALESCE(MAX(menu_id), 0) + 1 FROM sys_menu),
+'功率误差统计',
+(select menu_id from sys_menu t where t.menu_name = '统计分析' and t.parent_id = 0),
+10, 'power-error-stat', 'ufo/electricity/statanalysis/powerErrorStat', '', 'PowerErrorStat', 1, 0, 'C', '0', '0', 'data:powerErrorStat:list', 'CalculatorOutlined', 'admin', now(), '', NULL, '功率误差统计页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '功率误差统计');
+
+-- 增加 上传状态查询 二级菜单(挂在 统计分析 下)
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+(SELECT COALESCE(MAX(menu_id), 0) + 1 FROM sys_menu),
+'上传状态查询',
+(SELECT menu_id FROM sys_menu t WHERE t.menu_name = '统计分析' AND t.parent_id = 0),
+20, 'report-log-query', 'ufo/electricity/statanalysis/reportLogQuery', '', 'ReportLogQuery', 1, 0, 'C', '0', '0', 'fileupload:reportLog:list', 'CloudUploadOutlined', 'admin', now(), '', NULL, '上传状态查询页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '上传状态查询');
+
+-- 增加 功率频率分布统计 二级菜单(挂在 统计分析 下)
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+(SELECT COALESCE(MAX(menu_id), 0) + 1 FROM sys_menu),
+'功率频率分布统计',
+(SELECT menu_id FROM sys_menu t WHERE t.menu_name = '统计分析' AND t.parent_id = 0),
+30, 'power-frequency-distribution', 'ufo/electricity/statanalysis/powerFrequencyDistribution', '', 'PowerFrequencyDistribution', 1, 0, 'C', '0', '0', 'data:powerFrequencyDistribution:list', 'BarChartOutlined', 'admin', now(), '', NULL, '功率频率分布统计页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '功率频率分布统计');
+
+-- 增加 辐照度频率分布统计 二级菜单(挂在 统计分析 下)
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+(SELECT COALESCE(MAX(menu_id), 0) + 1 FROM sys_menu),
+'辐照度频率分布统计',
+(SELECT menu_id FROM sys_menu t WHERE t.menu_name = '统计分析' AND t.parent_id = 0),
+40, 'irradiance-frequency-distribution', 'ufo/electricity/statanalysis/irradianceFrequencyDistribution', '', 'IrradianceFrequencyDistribution', 1, 0, 'C', '0', '0', 'data:irradianceFrequencyDistribution:list', 'BarChartOutlined', 'admin', now(), '', NULL, '辐照度频率分布统计页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '辐照度频率分布统计');
+
+INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, remark)
+SELECT
+nextval(pg_get_serial_sequence('sys_dict_type', 'dict_id')),
+'文件上报配置', 'power_forecast_report_batch_config', '0', 'admin', now(), '短期/超短期功率预测上报批次生成配置'
+WHERE NOT EXISTS (SELECT 1 FROM sys_dict_type t WHERE t.dict_type = 'power_forecast_report_batch_config');
+
+INSERT INTO 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
+nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')),
+1, '短期/超短期批次生成配置', '[]', 'power_forecast_report_batch_config', '', '', 'Y', '0', 'admin', now(), 'JSON数组, 每项含 stationCode/type/period/times/initInterval(分钟)'
+WHERE NOT EXISTS (SELECT 1 FROM sys_dict_data t WHERE t.dict_type = 'power_forecast_report_batch_config');
+
+-- 删除风场
+UPDATE "public"."config_station" set is_del = 'true' where station_code in ('BHWP01', 'HHWP02');
+
+-- 字典类型: 告警类别
+INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, remark)
+SELECT
+nextval(pg_get_serial_sequence('sys_dict_type', 'dict_id')),
+'告警类别', 'alarm_category', '0', 'admin', now(), '事件查询-告警类别'
+WHERE NOT EXISTS (SELECT 1 FROM sys_dict_type t WHERE t.dict_type = 'alarm_category');
+-- 字典类型: 告警等级
+INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, remark)
+SELECT
+nextval(pg_get_serial_sequence('sys_dict_type', 'dict_id')),
+'告警等级', 'alarm_level', '0', 'admin', now(), '事件查询-告警等级'
+WHERE NOT EXISTS (SELECT 1 FROM sys_dict_type t WHERE t.dict_type = 'alarm_level');
+-- 告警类别字典数据(先删后插,保证幂等)
+DELETE FROM sys_dict_data WHERE dict_type = 'alarm_category';
+
+INSERT INTO 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)
+VALUES
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 1, '通信异常', '1', 'alarm_category', '', '', 'N', '0', 'admin', now(), '事件查询-告警类别'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 2, '数据异常', '2', 'alarm_category', '', '', 'N', '0', 'admin', now(), '事件查询-告警类别'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 3, '气象预报异常', '3', 'alarm_category', '', '', 'N', '0', 'admin', now(), '事件查询-告警类别'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 4, '功率预测异常', '4', 'alarm_category', '', '', 'N', '0', 'admin', now(), '事件查询-告警类别'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 5, '数据上报异常', '5', 'alarm_category', '', '', 'N', '0', 'admin', now(), '事件查询-告警类别'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 6, '系统运行异常', '6', 'alarm_category', '', '', 'N', '0', 'admin', now(), '事件查询-告警类别');
+-- 告警等级字典数据(颜色值配置在 css_class,页面按等级值渲染颜色;先删后插,保证幂等)
+DELETE FROM sys_dict_data WHERE dict_type = 'alarm_level';
+
+INSERT INTO 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)
+VALUES
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 1, '紧急告警', '1', 'alarm_level', 'red', '', 'N', '0', 'admin', now(), '事件查询-告警等级'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 2, '重要告警', '2', 'alarm_level', 'orange', '', 'N', '0', 'admin', now(), '事件查询-告警等级'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 3, '一般告警', '3', 'alarm_level', 'gold', '', 'N', '0', 'admin', now(), '事件查询-告警等级'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 4, '提示信息', '4', 'alarm_level', 'blue', '', 'N', '0', 'admin', now(), '事件查询-告警等级');
+-- 增加 事件查询 二级菜单(挂在 统计分析 下)
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+(SELECT COALESCE(MAX(menu_id), 0) + 1 FROM sys_menu),
+'事件查询',
+(SELECT menu_id FROM sys_menu t WHERE t.menu_name = '统计分析' AND t.parent_id = 0),
+5, 'event-query', 'ufo/electricity/statanalysis/eventQuery', '', 'EventQuery', 1, 0, 'C', '0', '0', 'alarm:eventRecord:list', 'AlertOutlined', 'admin', now(), '', NULL, '事件查询页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '事件查询');
+
+-- 增加 数据补传 二级菜单(挂在 功率预测 下)
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+(SELECT COALESCE(MAX(menu_id), 0) + 1 FROM sys_menu),
+'数据补传',
+(SELECT menu_id FROM sys_menu t WHERE t.menu_name = '功率预测'),
+35, 'data-resend', 'ufo/electricity/forecast/DataResend', '', 'DataResend', 1, 0, 'C', '0', '0', 'fileupload:reportLog:reUpload', 'CloudUploadOutlined', 'admin', now(), '', NULL, '数据补传页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '数据补传');
+
+-- 字典类型: 每日文件上传配置
+INSERT INTO sys_dict_type (dict_id, dict_name, dict_type, status, create_by, create_time, remark)
+SELECT
+nextval(pg_get_serial_sequence('sys_dict_type', 'dict_id')),
+'每日文件上传配置', 'daily_file_upload_config', '0', 'admin', now(), '光伏上传率统计-每日文件上传配置'
+WHERE NOT EXISTS (SELECT 1 FROM sys_dict_type t WHERE t.dict_type = 'daily_file_upload_config');
+-- 字典数据(先删后插,保证幂等)
+DELETE FROM sys_dict_data WHERE dict_type = 'daily_file_upload_config';
+
+INSERT INTO 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)
+VALUES
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 1, '超短期文件', '{"type":"supershort","num":16}', 'daily_file_upload_config', '', '', 'N', '0', 'admin', now(), 'num=每日期望上传数'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 2, '短期文件', '{"type":"short","num":1}', 'daily_file_upload_config', '', '', 'N', '0', 'admin', now(), 'num=每日期望上传数'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 3, '中期文件', '{"type":"medium","num":1}', 'daily_file_upload_config', '', '', 'N', '0', 'admin', now(), 'num=每日期望上传数'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 4, '环境检测仪数据', '{"type":"envlDetec","num":1}', 'daily_file_upload_config', '', '', 'N', '0', 'admin', now(), 'num=每日期望上传数'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 5, '逆变器运行信息文件', '{"type":"ivtOpr","num":1}', 'daily_file_upload_config', '', '', 'N', '0', 'admin', now(), 'num=每日期望上传数'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 6, '升压变数据', '{"type":"bstTrn","num":1}', 'daily_file_upload_config', '', '', 'N', '0', 'admin', now(), 'num=每日期望上传数'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 7, '理论功率文件', '{"type":"thrPower","num":1}', 'daily_file_upload_config', '', '', 'N', '0', 'admin', now(), 'num=每日期望上传数'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 8, '数值天气预报文件', '{"type":"nmrWeather","num":1}', 'daily_file_upload_config', '', '', 'N', '0', 'admin', now(), 'num=每日期望上传数'),
+(nextval(pg_get_serial_sequence('sys_dict_data', 'dict_code')), 9, '发电计划文件', '{"type":"pwrGen","num":1}', 'daily_file_upload_config', '', '', 'N', '0', 'admin', now(), 'num=每日期望上传数');
+-- 增加 光伏上传率统计 二级菜单(挂在 统计分析 下)
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+SELECT
+(SELECT COALESCE(MAX(menu_id), 0) + 1 FROM sys_menu),
+'光伏上传率统计',
+(SELECT menu_id FROM sys_menu t WHERE t.menu_name = '统计分析' AND t.parent_id = 0),
+15, 'upload-rate-stat', 'ufo/electricity/statanalysis/uploadRateStat', '', 'UploadRateStat', 1, 0, 'C', '0', '0', 'fileupload:reportLog:uploadRate', 'BarChartOutlined', 'admin', now(), '', NULL, '光伏上传率统计页面'
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu t WHERE t.menu_name = '光伏上传率统计');

+ 2 - 0
doc/数据库脚本/init.sql

@@ -3,3 +3,5 @@
 \i ../../forecast-backend-server/src/main/resources/sql/electricity_mock_new.sql
 \i ./gatewway.sql
 \i ./gatewway-data.sql
+\i ./backend_ddl_2026112.sql
+\i ./backend_dml_2026112.sql