Files
pickling-mes/backend/app/database.py
wangyu 9cf422ef0d feat(plan): 计划详细面板 + 来料重量/外径/分卷重量 + 在线/生产中状态机 + 入口移动 + 上次模板回填
- backend: plan 增加 incoming_weight/incoming_od/split_weights(JSON) 字段及迁移
- backend: GET /plan/last-template 返回最近一条计划的工艺字段用于新增回填(多端共享)
- backend: PATCH /plan/{id}/start 设为 producing,强制单卷在产(其他 producing 回退 online)
- backend: 生成实绩时按卷号自动把对应计划状态置为 produced
- frontend: 新增计划默认状态 online;新增时调用 last-template 自动回填
- frontend: Plan 表格行点击展开 计划详细 面板(按截图布局)
- frontend: Plan 行操作增加「移动」(ready/online → producing)
- frontend: 物料跟踪页加 在线计划队列 + 入口移动按钮,显示当前生产中卷
- frontend: 计划弹窗新增 轧制模式/来料重量/来料外径/1-6#分卷重量
2026-06-21 23:42:22 +08:00

103 lines
5.7 KiB
Python

from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
from sqlalchemy.orm import DeclarativeBase
from app.config import settings
engine = create_async_engine(
settings.DATABASE_URL,
echo=settings.DEBUG,
pool_size=10,
max_overflow=20,
)
AsyncSessionLocal = async_sessionmaker(
engine, class_=AsyncSession, expire_on_commit=False
)
class Base(DeclarativeBase):
pass
async def get_db():
async with AsyncSessionLocal() as session:
try:
yield session
await session.commit()
except Exception:
await session.rollback()
raise
async def init_db():
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
await _run_migrations(conn)
async def _run_migrations(conn):
"""Postgres 专用:为已存在表追加新列(幂等)"""
from sqlalchemy import text
is_pg = engine.dialect.name == "postgresql"
if not is_pg:
return
statements = [
# production_plans 新字段
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS cold_coil_no VARCHAR(30)",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS hot_coil_no VARCHAR(30)",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS incoming_thickness DOUBLE PRECISION",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS product_thickness DOUBLE PRECISION",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS deviation_upper DOUBLE PRECISION",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS deviation_lower DOUBLE PRECISION",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS incoming_width DOUBLE PRECISION",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS product_width DOUBLE PRECISION",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS packaging_req VARCHAR(30)",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS trim_req VARCHAR(30)",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS rolling_mode VARCHAR(30)",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS split_count INTEGER DEFAULT 1",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS coil_diameter DOUBLE PRECISION",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS next_process VARCHAR(30)",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS incoming_weight DOUBLE PRECISION",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS incoming_od DOUBLE PRECISION",
"ALTER TABLE production_plans ADD COLUMN IF NOT EXISTS split_weights JSONB",
# 状态列改为 VARCHAR 以适配新值
"ALTER TABLE production_plans ALTER COLUMN status TYPE VARCHAR(20) USING status::text",
# production_records 新字段
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS sub_coil_no VARCHAR(30)",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS hot_coil_no VARCHAR(30)",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS team VARCHAR(10)",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS steel_grade VARCHAR(30)",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS incoming_thickness DOUBLE PRECISION",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS deviation_upper DOUBLE PRECISION",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS deviation_lower DOUBLE PRECISION",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS incoming_width DOUBLE PRECISION",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS outlet_width DOUBLE PRECISION",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS incoming_weight DOUBLE PRECISION",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS weighed_weight DOUBLE PRECISION",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS packaging_req VARCHAR(30)",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS trim_req VARCHAR(30)",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS surface_quality VARCHAR(30)",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS product_quality DOUBLE PRECISION",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS product_length DOUBLE PRECISION",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS length_per_ton DOUBLE PRECISION",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS offline_time TIMESTAMP",
"ALTER TABLE production_records ADD COLUMN IF NOT EXISTS status VARCHAR(20) DEFAULT 'UNWEIGH'",
# qc_defect 新字段
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS seq_no INTEGER",
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS defect_desc VARCHAR(200)",
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS start_position DOUBLE PRECISION",
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS end_position DOUBLE PRECISION",
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS length_val DOUBLE PRECISION",
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS upper_surface BOOLEAN DEFAULT FALSE",
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS lower_surface BOOLEAN DEFAULT FALSE",
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS side_op BOOLEAN DEFAULT FALSE",
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS side_middle BOOLEAN DEFAULT FALSE",
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS side_drive BOOLEAN DEFAULT FALSE",
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS is_main BOOLEAN DEFAULT FALSE",
"ALTER TABLE qc_defect ADD COLUMN IF NOT EXISTS image_url VARCHAR(255)",
]
for s in statements:
try:
await conn.execute(text(s))
except Exception:
pass