feat: 初始化临时项目管理项目结构及核心功能

- 新增项目根目录及配置文件,包括 .gitignore、.env.example 和 package.json
- 实现数据库连接池、配置加载、日志记录和 HTTP 客户端工具
- 添加数据服务层,支持酒店、房间、房型和回路数据的批量事务处理
- 创建主脚本,实现分阶段数据获取、处理和存储流程
- 提供数据库初始化脚本和测试用例
- 添加项目文档,包括 README.md 和项目需求说明
This commit is contained in:
2026-02-02 09:10:53 +08:00
commit a4763b5e30
23 changed files with 5931 additions and 0 deletions

15
project_management/.env Normal file
View File

@@ -0,0 +1,15 @@
PORT=3000
DB_FILE=./local.db
API_BASE_URL=http://www.boonlive-rcu.com:7000/api/values
PORT=3000
# 数据库配置
POSTGRES_HOST=10.8.8.109
POSTGRES_PORT=5433
POSTGRES_DATABASE=log_platform
POSTGRES_USER=log_admin
POSTGRES_PASSWORD=YourActualStrongPasswordForPostgres!
POSTGRES_MAX_CONNECTIONS=6
POSTGRES_IDLE_TIMEOUT_MS=30000

View File

@@ -0,0 +1,132 @@
-- ============================================================================
-- 数据库初始化脚本
-- 描述:创建 log_platform 库逻辑参考、room_status 模式及 room_status_moment 分区表
-- 对应项目需求project.md #L57-65
-- ============================================================================
-- 注意:在 PostgreSQL 中CREATE DATABASE 不能在事务块中执行。
-- 通常建议先手动创建数据库,然后再执行后续脚本。
-- CREATE DATABASE log_platform;
-- 切换到 log_platform 数据库后执行以下内容:
-- 1. 创建模式
CREATE SCHEMA IF NOT EXISTS room_status;
-- 2. 创建主表 (使用声明式分区)
-- 根据需求 L57-65考虑后期十万级以上数据的扩展按 hotel_id 进行 LIST 分区
CREATE TABLE IF NOT EXISTS room_status.room_status_moment (
-- 基础标识字段
guid UUID NOT NULL,
ts_ms INT8 NOT NULL DEFAULT (EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) * 1000)::BIGINT,
hotel_id INT2 NOT NULL,
room_id TEXT NOT NULL,
device_id TEXT NOT NULL,
-- 设备状态字段
sys_lock_status INT2,
online_status INT2,
launcher_version TEXT,
app_version TEXT,
config_version TEXT,
register_ts_ms INT8,
upgrade_ts_ms INT8,
config_ts_ms INT8,
ip TEXT,
-- 房间业务状态字段
pms_status INT2,
power_state INT2,
cardless_state INT2,
service_mask INT8,
insert_card INT2,
-- 空调相关
air_address TEXT[],
air_state INT2,
air_model INT2,
air_speed INT2,
air_set_temp INT2,
air_now_temp INT2,
air_solenoid_valve INT2,
-- 能耗相关
elec_address TEXT[],
elec_voltage DOUBLE PRECISION,
elec_ampere DOUBLE PRECISION,
elec_power DOUBLE PRECISION,
elec_phase TEXT,
elec_energy DOUBLE PRECISION,
elec_sum_energy DOUBLE PRECISION,
-- 节能与外设
carbon_state INT2,
dev_loops JSONB,
energy_carbon_sum DOUBLE PRECISION,
energy_nocard_sum DOUBLE PRECISION,
external_device JSONB DEFAULT '{}',
faulty_device_count JSONB DEFAULT '{}',
-- 约束:分区表的主键必须包含分区键 (hotel_id)
PRIMARY KEY (hotel_id, room_id, device_id, guid)
) PARTITION BY LIST (hotel_id);
-- 3. 创建索引 (针对高频查询字段)
-- 注意:在分区表上创建索引会自动在所有子表上创建对应的索引
CREATE INDEX IF NOT EXISTS idx_room_status_moment_hotel_room ON room_status.room_status_moment (hotel_id, room_id);
CREATE INDEX IF NOT EXISTS idx_room_status_moment_device_id ON room_status.room_status_moment (device_id);
CREATE INDEX IF NOT EXISTS idx_room_status_moment_sys_lock ON room_status.room_status_moment (sys_lock_status);
CREATE INDEX IF NOT EXISTS idx_room_status_moment_online ON room_status.room_status_moment (online_status);
CREATE INDEX IF NOT EXISTS idx_room_status_moment_pms ON room_status.room_status_moment (pms_status);
CREATE INDEX IF NOT EXISTS idx_room_status_moment_power ON room_status.room_status_moment (power_state);
CREATE INDEX IF NOT EXISTS idx_room_status_moment_cardless ON room_status.room_status_moment (cardless_state);
CREATE INDEX IF NOT EXISTS idx_room_status_moment_insert_card ON room_status.room_status_moment (insert_card);
CREATE INDEX IF NOT EXISTS idx_room_status_moment_carbon ON room_status.room_status_moment (carbon_state);
-- 4. 示例:创建第一个分区 (hotel_id = 1)
-- 实际部署时,可根据 hotel_id 动态创建分区
CREATE TABLE IF NOT EXISTS room_status.room_status_moment_h1
PARTITION OF room_status.room_status_moment
FOR VALUES IN (1);
-- 5. 添加表和字段注释
COMMENT ON TABLE room_status.room_status_moment IS '房间即时状态表 - 记录设备及房间业务的最新实时状态';
COMMENT ON COLUMN room_status.room_status_moment.guid IS '主键 guid uuid 32位无符号UUID';
COMMENT ON COLUMN room_status.room_status_moment.ts_ms IS '最后更新时间';
COMMENT ON COLUMN room_status.room_status_moment.hotel_id IS '酒店';
COMMENT ON COLUMN room_status.room_status_moment.room_id IS '房间';
COMMENT ON COLUMN room_status.room_status_moment.device_id IS '设备编号';
COMMENT ON COLUMN room_status.room_status_moment.sys_lock_status IS '系统锁状态';
COMMENT ON COLUMN room_status.room_status_moment.online_status IS '设备在线状态';
COMMENT ON COLUMN room_status.room_status_moment.launcher_version IS '设备launcher版本';
COMMENT ON COLUMN room_status.room_status_moment.app_version IS '设备App版本';
COMMENT ON COLUMN room_status.room_status_moment.config_version IS '设备配置版本';
COMMENT ON COLUMN room_status.room_status_moment.register_ts_ms IS '最后一次注册时间';
COMMENT ON COLUMN room_status.room_status_moment.upgrade_ts_ms IS '最后一次升级时间';
COMMENT ON COLUMN room_status.room_status_moment.config_ts_ms IS '最后一次下发配置时间';
COMMENT ON COLUMN room_status.room_status_moment.ip IS '当前公网IP地址';
COMMENT ON COLUMN room_status.room_status_moment.pms_status IS 'PMS状态';
COMMENT ON COLUMN room_status.room_status_moment.power_state IS '取电状态';
COMMENT ON COLUMN room_status.room_status_moment.cardless_state IS '有、无人状态';
COMMENT ON COLUMN room_status.room_status_moment.service_mask IS '服务状态';
COMMENT ON COLUMN room_status.room_status_moment.insert_card IS '插卡状态';
COMMENT ON COLUMN room_status.room_status_moment.air_address IS '空调地址';
COMMENT ON COLUMN room_status.room_status_moment.air_state IS '空调状态';
COMMENT ON COLUMN room_status.room_status_moment.air_model IS '空调模型';
COMMENT ON COLUMN room_status.room_status_moment.air_speed IS '空调风速';
COMMENT ON COLUMN room_status.room_status_moment.air_set_temp IS '空调设置温度';
COMMENT ON COLUMN room_status.room_status_moment.air_now_temp IS '房间当前温度';
COMMENT ON COLUMN room_status.room_status_moment.air_solenoid_valve IS '空调电磁阀状态';
COMMENT ON COLUMN room_status.room_status_moment.elec_address IS '能耗表地址';
COMMENT ON COLUMN room_status.room_status_moment.elec_voltage IS '能耗表电压';
COMMENT ON COLUMN room_status.room_status_moment.elec_ampere IS '能耗表电流';
COMMENT ON COLUMN room_status.room_status_moment.elec_power IS '能耗表功率';
COMMENT ON COLUMN room_status.room_status_moment.elec_phase IS '当前相位';
COMMENT ON COLUMN room_status.room_status_moment.elec_energy IS '能耗表能耗';
COMMENT ON COLUMN room_status.room_status_moment.elec_sum_energy IS '能耗表累计能耗';
COMMENT ON COLUMN room_status.room_status_moment.carbon_state IS '碳达人状态';
COMMENT ON COLUMN room_status.room_status_moment.dev_loops IS '回路状态';
COMMENT ON COLUMN room_status.room_status_moment.energy_carbon_sum IS '碳达人节能累计';
COMMENT ON COLUMN room_status.room_status_moment.energy_nocard_sum IS '无卡节能累计';
COMMENT ON COLUMN room_status.room_status_moment.external_device IS '外设设备管理(数组)';
COMMENT ON COLUMN room_status.room_status_moment.faulty_device_count IS '故障设备数量';

View File

@@ -0,0 +1,58 @@
1. 房间即时状态表
- 这张表需要时刻更新,以反映房间的最新状态
- 这张表的查询频率较高,需要建立索引以提高查询效率
- 这张表的写入频率较高,需要考虑写入性能
- 这张表的数据量较大预计会有十万条左右的记录总数可以根据hotel_id进行分片存储
- 这张表可能会被同时查询和写入,需要考虑并发性能
- 这张表的写入操作主要是INSERT和UPDATE操作根据主键进行写入
- 这张表的查询操作主要是SELECT操作根据主键进行查询
- 这张表的写入操作可能会由多个线程同时进行,设计表的时候需要考虑并发性能和写入冲突问题
2. 数据表规划 (如果没有特殊说明,所有字段均为可空)
- 数据库属性:
- 库名log_platform
- 模式room_status
- 表名room_status_moment
- 数据库字段:
- 主键 guid uuid 32位无符号UUID (不可为空)
- 最后更新时间 ts_ms int8 (Unix时间戳ms) (不可为空)
- 酒店 hotel_id int2 (索引) (不可为空)
- 房间 room_id text (索引) (不可为空)
- 设备编号 device_id text (索引) (不可为空)
- 系统锁状态 sys_lock_status int2 (索引)
- 设备在线状态 online_status int2 (索引)
- 设备launcher版本 launcher_version text
- 设备App版本 app_version text
- 设备配置版本 config_version text
- 最后一次注册时间 register_ts_ms int8 (Unix时间戳ms)
- 最后一次升级时间 upgrade_ts_ms int8 (Unix时间戳ms)
- 最后一次下发配置时间 config_ts_ms int8 (Unix时间戳ms)
- 当前公网IP地址 ip text
- PMS状态 pms_status int2 (索引)
- 取电状态 power_state int2 (索引)
- 有、无人状态 cardless_state int2 (索引)
- 服务状态 service_mask int8
- 插卡状态 insert_card int2 (索引)
- 空调地址 air_address text[]
- 空调状态 air_state int2
- 空调模型 air_model int2
- 空调风速 air_speed int2
- 空调设置温度 air_set_temp int2
- 房间当前温度 air_now_temp int2
- 空调电磁阀状态 air_solenoid_valve int2
- 能耗表地址 elec_address text[]
- 能耗表电压 elec_voltage double precision
- 能耗表电流 elec_ampere double precision
- 能耗表功率 elec_power double precision
- 当前相位 elec_phase text
- 能耗表能耗 elec_energy double precision
- 能耗表累计能耗 elec_sum_energy double precision
- 碳达人状态 carbon_state int2 (索引)
- 回路状态 dev_loops jsonb
- 碳达人节能累计 energy_carbon_sum double precision
- 无卡节能累计 energy_nocard_sum double precision
- 外设设备管理(数组) external_device jsonb 预留字段暂时为空json
- 故障设备数量 faulty_device_count jsonb 预留字段暂时为空json
主键hotel_id, room_id, device_id, guid