feat: 移除PDI和订单号字段,新增设备巡检模块
- 从物料跟踪页面移除订单号列和表单字段 - 从导航菜单移除PDI管理,添加设备巡检 - 新增InspectionLocation和InspectionRecord后端模型和API - 新增设备巡检前端页面(左侧点位列表,右侧设备和历史记录)
This commit is contained in:
7
backend/app/schemas/__init__.py
Normal file
7
backend/app/schemas/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from app.schemas.common import Response, PageResponse, PageParams
|
||||
from app.schemas.user import UserCreate, UserUpdate, UserOut, Token, LoginRequest
|
||||
from app.schemas.material import CoilCreate, CoilUpdate, CoilOut, TrackingCreate, TrackingOut
|
||||
from app.schemas.production import ProductionRecordCreate, ProductionRecordUpdate, ProductionRecordOut
|
||||
from app.schemas.plan import PlanCreate, PlanUpdate, PlanOut
|
||||
from app.schemas.downtime import DowntimeCreate, DowntimeUpdate, DowntimeOut, CategoryCreate, CategoryOut
|
||||
from app.schemas.equipment import EquipmentCreate, EquipmentUpdate, EquipmentOut, MaintenanceCreate, MaintenanceOut
|
||||
30
backend/app/schemas/common.py
Normal file
30
backend/app/schemas/common.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Generic, TypeVar, Optional, List
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class Response(BaseModel, Generic[T]):
|
||||
code: int = 200
|
||||
msg: str = "success"
|
||||
data: Optional[T] = None
|
||||
|
||||
@classmethod
|
||||
def ok(cls, data=None, msg="success"):
|
||||
return cls(code=200, msg=msg, data=data)
|
||||
|
||||
@classmethod
|
||||
def error(cls, msg="error", code=500):
|
||||
return cls(code=code, msg=msg, data=None)
|
||||
|
||||
|
||||
class PageParams(BaseModel):
|
||||
page: int = 1
|
||||
page_size: int = 20
|
||||
|
||||
|
||||
class PageResponse(BaseModel, Generic[T]):
|
||||
total: int
|
||||
page: int
|
||||
page_size: int
|
||||
items: List[T]
|
||||
67
backend/app/schemas/downtime.py
Normal file
67
backend/app/schemas/downtime.py
Normal file
@@ -0,0 +1,67 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class CategoryCreate(BaseModel):
|
||||
code: str
|
||||
name: str
|
||||
category: str
|
||||
description: Optional[str] = None
|
||||
|
||||
|
||||
class CategoryOut(BaseModel):
|
||||
id: int
|
||||
code: str
|
||||
name: str
|
||||
category: str
|
||||
description: Optional[str]
|
||||
is_active: int
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class DowntimeCreate(BaseModel):
|
||||
category_id: Optional[int] = None
|
||||
category_code: Optional[str] = None
|
||||
shift: Optional[str] = None
|
||||
shift_date: Optional[datetime] = None
|
||||
start_time: datetime
|
||||
end_time: Optional[datetime] = None
|
||||
equipment_code: Optional[str] = None
|
||||
fault_desc: Optional[str] = None
|
||||
action_taken: Optional[str] = None
|
||||
root_cause: Optional[str] = None
|
||||
reporter: Optional[str] = None
|
||||
handler: Optional[str] = None
|
||||
is_planned: int = 0
|
||||
|
||||
|
||||
class DowntimeUpdate(BaseModel):
|
||||
end_time: Optional[datetime] = None
|
||||
action_taken: Optional[str] = None
|
||||
root_cause: Optional[str] = None
|
||||
handler: Optional[str] = None
|
||||
fault_desc: Optional[str] = None
|
||||
|
||||
|
||||
class DowntimeOut(BaseModel):
|
||||
id: int
|
||||
category_code: Optional[str]
|
||||
category_name: Optional[str]
|
||||
shift: Optional[str]
|
||||
shift_date: Optional[datetime]
|
||||
start_time: datetime
|
||||
end_time: Optional[datetime]
|
||||
duration: Optional[float]
|
||||
equipment_code: Optional[str]
|
||||
fault_desc: Optional[str]
|
||||
action_taken: Optional[str]
|
||||
reporter: Optional[str]
|
||||
handler: Optional[str]
|
||||
is_planned: int
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
79
backend/app/schemas/equipment.py
Normal file
79
backend/app/schemas/equipment.py
Normal file
@@ -0,0 +1,79 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
from app.models.equipment import EquipmentStatus
|
||||
|
||||
|
||||
class EquipmentCreate(BaseModel):
|
||||
code: str
|
||||
name: str
|
||||
category: Optional[str] = None
|
||||
model: Optional[str] = None
|
||||
manufacturer: Optional[str] = None
|
||||
install_date: Optional[datetime] = None
|
||||
location: Optional[str] = None
|
||||
rated_power: Optional[float] = None
|
||||
remark: Optional[str] = None
|
||||
|
||||
|
||||
class EquipmentUpdate(BaseModel):
|
||||
name: Optional[str] = None
|
||||
category: Optional[str] = None
|
||||
model: Optional[str] = None
|
||||
location: Optional[str] = None
|
||||
status: Optional[EquipmentStatus] = None
|
||||
remark: Optional[str] = None
|
||||
|
||||
|
||||
class EquipmentOut(BaseModel):
|
||||
id: int
|
||||
code: str
|
||||
name: str
|
||||
category: Optional[str]
|
||||
model: Optional[str]
|
||||
manufacturer: Optional[str]
|
||||
install_date: Optional[datetime]
|
||||
location: Optional[str]
|
||||
status: EquipmentStatus
|
||||
rated_power: Optional[float]
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class MaintenanceCreate(BaseModel):
|
||||
equipment_id: int
|
||||
equipment_code: Optional[str] = None
|
||||
maintenance_type: str
|
||||
title: str
|
||||
description: Optional[str] = None
|
||||
start_time: datetime
|
||||
end_time: Optional[datetime] = None
|
||||
duration: Optional[float] = None
|
||||
cost: Optional[float] = None
|
||||
spare_parts: Optional[str] = None
|
||||
technician: Optional[str] = None
|
||||
approver: Optional[str] = None
|
||||
next_maintenance: Optional[datetime] = None
|
||||
result: Optional[str] = None
|
||||
remark: Optional[str] = None
|
||||
|
||||
|
||||
class MaintenanceOut(BaseModel):
|
||||
id: int
|
||||
equipment_id: int
|
||||
equipment_code: Optional[str]
|
||||
maintenance_type: str
|
||||
title: str
|
||||
description: Optional[str]
|
||||
start_time: datetime
|
||||
end_time: Optional[datetime]
|
||||
duration: Optional[float]
|
||||
cost: Optional[float]
|
||||
technician: Optional[str]
|
||||
result: Optional[str]
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
37
backend/app/schemas/inspection.py
Normal file
37
backend/app/schemas/inspection.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class InspectionLocationCreate(BaseModel):
|
||||
code: str
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
sort_order: int = 0
|
||||
|
||||
|
||||
class InspectionLocationOut(InspectionLocationCreate):
|
||||
id: int
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class InspectionRecordCreate(BaseModel):
|
||||
location_id: int
|
||||
equipment_code: Optional[str] = None
|
||||
equipment_name: Optional[str] = None
|
||||
scan_code: Optional[str] = None
|
||||
inspector: str
|
||||
result: str = "normal"
|
||||
notes: Optional[str] = None
|
||||
|
||||
|
||||
class InspectionRecordOut(InspectionRecordCreate):
|
||||
id: int
|
||||
location_name: Optional[str] = None
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
82
backend/app/schemas/material.py
Normal file
82
backend/app/schemas/material.py
Normal file
@@ -0,0 +1,82 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
from app.models.material import CoilStatus
|
||||
|
||||
|
||||
class CoilCreate(BaseModel):
|
||||
coil_no: str
|
||||
order_no: Optional[str] = None
|
||||
steel_grade: Optional[str] = None
|
||||
spec_thickness: Optional[float] = None
|
||||
spec_width: Optional[float] = None
|
||||
target_thickness: Optional[float] = None
|
||||
target_width: Optional[float] = None
|
||||
gross_weight: Optional[float] = None
|
||||
net_weight: Optional[float] = None
|
||||
inner_diameter: Optional[float] = None
|
||||
plan_id: Optional[int] = None
|
||||
remark: Optional[str] = None
|
||||
|
||||
|
||||
class CoilUpdate(BaseModel):
|
||||
order_no: Optional[str] = None
|
||||
steel_grade: Optional[str] = None
|
||||
spec_thickness: Optional[float] = None
|
||||
spec_width: Optional[float] = None
|
||||
target_thickness: Optional[float] = None
|
||||
target_width: Optional[float] = None
|
||||
gross_weight: Optional[float] = None
|
||||
net_weight: Optional[float] = None
|
||||
status: Optional[CoilStatus] = None
|
||||
plan_id: Optional[int] = None
|
||||
remark: Optional[str] = None
|
||||
|
||||
|
||||
class CoilOut(BaseModel):
|
||||
id: int
|
||||
coil_no: str
|
||||
order_no: Optional[str]
|
||||
steel_grade: Optional[str]
|
||||
spec_thickness: Optional[float]
|
||||
spec_width: Optional[float]
|
||||
target_thickness: Optional[float]
|
||||
target_width: Optional[float]
|
||||
gross_weight: Optional[float]
|
||||
net_weight: Optional[float]
|
||||
status: CoilStatus
|
||||
plan_id: Optional[int]
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class TrackingCreate(BaseModel):
|
||||
coil_no: str
|
||||
position: Optional[str] = None
|
||||
event_type: str
|
||||
event_desc: Optional[str] = None
|
||||
actual_thickness: Optional[float] = None
|
||||
actual_width: Optional[float] = None
|
||||
speed: Optional[float] = None
|
||||
tension: Optional[float] = None
|
||||
operator: Optional[str] = None
|
||||
event_time: datetime
|
||||
|
||||
|
||||
class TrackingOut(BaseModel):
|
||||
id: int
|
||||
coil_id: int
|
||||
coil_no: str
|
||||
position: Optional[str]
|
||||
event_type: str
|
||||
event_desc: Optional[str]
|
||||
actual_thickness: Optional[float]
|
||||
actual_width: Optional[float]
|
||||
speed: Optional[float]
|
||||
operator: Optional[str]
|
||||
event_time: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
81
backend/app/schemas/pdi.py
Normal file
81
backend/app/schemas/pdi.py
Normal file
@@ -0,0 +1,81 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
from app.models.pdi import L3Status, L2Status
|
||||
|
||||
|
||||
class PDIRecordCreate(BaseModel):
|
||||
coil_no: str
|
||||
order_no: Optional[str] = None
|
||||
customer: Optional[str] = None
|
||||
steel_grade: Optional[str] = None
|
||||
thickness: Optional[float] = None
|
||||
width: Optional[float] = None
|
||||
target_thickness: Optional[float] = None
|
||||
target_width: Optional[float] = None
|
||||
yield_strength: Optional[float] = None
|
||||
tensile_strength: Optional[float] = None
|
||||
elongation: Optional[float] = None
|
||||
coil_weight: Optional[float] = None
|
||||
inner_diameter: Optional[float] = None
|
||||
outer_diameter: Optional[float] = None
|
||||
process_route: Optional[str] = None
|
||||
priority: Optional[int] = 3
|
||||
l3_status: Optional[L3Status] = L3Status.pending
|
||||
l2_status: Optional[L2Status] = L2Status.pending
|
||||
send_time: Optional[datetime] = None
|
||||
confirm_time: Optional[datetime] = None
|
||||
remark: Optional[str] = None
|
||||
|
||||
|
||||
class PDIRecordUpdate(BaseModel):
|
||||
order_no: Optional[str] = None
|
||||
customer: Optional[str] = None
|
||||
steel_grade: Optional[str] = None
|
||||
thickness: Optional[float] = None
|
||||
width: Optional[float] = None
|
||||
target_thickness: Optional[float] = None
|
||||
target_width: Optional[float] = None
|
||||
yield_strength: Optional[float] = None
|
||||
tensile_strength: Optional[float] = None
|
||||
elongation: Optional[float] = None
|
||||
coil_weight: Optional[float] = None
|
||||
inner_diameter: Optional[float] = None
|
||||
outer_diameter: Optional[float] = None
|
||||
process_route: Optional[str] = None
|
||||
priority: Optional[int] = None
|
||||
l3_status: Optional[L3Status] = None
|
||||
l2_status: Optional[L2Status] = None
|
||||
send_time: Optional[datetime] = None
|
||||
confirm_time: Optional[datetime] = None
|
||||
remark: Optional[str] = None
|
||||
|
||||
|
||||
class PDIRecordOut(BaseModel):
|
||||
id: int
|
||||
coil_no: str
|
||||
order_no: Optional[str]
|
||||
customer: Optional[str]
|
||||
steel_grade: Optional[str]
|
||||
thickness: Optional[float]
|
||||
width: Optional[float]
|
||||
target_thickness: Optional[float]
|
||||
target_width: Optional[float]
|
||||
yield_strength: Optional[float]
|
||||
tensile_strength: Optional[float]
|
||||
elongation: Optional[float]
|
||||
coil_weight: Optional[float]
|
||||
inner_diameter: Optional[float]
|
||||
outer_diameter: Optional[float]
|
||||
process_route: Optional[str]
|
||||
priority: Optional[int]
|
||||
l3_status: Optional[L3Status]
|
||||
l2_status: Optional[L2Status]
|
||||
send_time: Optional[datetime]
|
||||
confirm_time: Optional[datetime]
|
||||
remark: Optional[str]
|
||||
created_at: datetime
|
||||
updated_at: Optional[datetime]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
48
backend/app/schemas/plan.py
Normal file
48
backend/app/schemas/plan.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
from app.models.plan import PlanStatus
|
||||
|
||||
|
||||
class PlanCreate(BaseModel):
|
||||
plan_no: str
|
||||
plan_date: datetime
|
||||
shift: Optional[str] = None
|
||||
plan_quantity: int = 0
|
||||
plan_weight: float = 0
|
||||
steel_grade: Optional[str] = None
|
||||
spec_range: Optional[str] = None
|
||||
priority: int = 5
|
||||
remark: Optional[str] = None
|
||||
|
||||
|
||||
class PlanUpdate(BaseModel):
|
||||
plan_date: Optional[datetime] = None
|
||||
shift: Optional[str] = None
|
||||
plan_quantity: Optional[int] = None
|
||||
plan_weight: Optional[float] = None
|
||||
actual_quantity: Optional[int] = None
|
||||
actual_weight: Optional[float] = None
|
||||
status: Optional[PlanStatus] = None
|
||||
priority: Optional[int] = None
|
||||
remark: Optional[str] = None
|
||||
|
||||
|
||||
class PlanOut(BaseModel):
|
||||
id: int
|
||||
plan_no: str
|
||||
plan_date: datetime
|
||||
shift: Optional[str]
|
||||
plan_quantity: int
|
||||
plan_weight: float
|
||||
actual_quantity: int
|
||||
actual_weight: float
|
||||
status: PlanStatus
|
||||
steel_grade: Optional[str]
|
||||
spec_range: Optional[str]
|
||||
priority: int
|
||||
created_by: Optional[str]
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
57
backend/app/schemas/production.py
Normal file
57
backend/app/schemas/production.py
Normal file
@@ -0,0 +1,57 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class ProductionRecordCreate(BaseModel):
|
||||
coil_no: str
|
||||
plan_id: Optional[int] = None
|
||||
shift: Optional[str] = None
|
||||
shift_date: Optional[datetime] = None
|
||||
start_time: Optional[datetime] = None
|
||||
end_time: Optional[datetime] = None
|
||||
process_length: Optional[float] = None
|
||||
process_weight: Optional[float] = None
|
||||
avg_speed: Optional[float] = None
|
||||
max_speed: Optional[float] = None
|
||||
acid_consumption: Optional[float] = None
|
||||
inlet_thickness: Optional[float] = None
|
||||
outlet_thickness: Optional[float] = None
|
||||
inlet_width: Optional[float] = None
|
||||
quality_grade: Optional[str] = None
|
||||
operator: Optional[str] = None
|
||||
remark: Optional[str] = None
|
||||
|
||||
|
||||
class ProductionRecordUpdate(BaseModel):
|
||||
shift: Optional[str] = None
|
||||
end_time: Optional[datetime] = None
|
||||
process_length: Optional[float] = None
|
||||
process_weight: Optional[float] = None
|
||||
avg_speed: Optional[float] = None
|
||||
acid_consumption: Optional[float] = None
|
||||
quality_grade: Optional[str] = None
|
||||
remark: Optional[str] = None
|
||||
|
||||
|
||||
class ProductionRecordOut(BaseModel):
|
||||
id: int
|
||||
coil_no: str
|
||||
plan_id: Optional[int]
|
||||
shift: Optional[str]
|
||||
shift_date: Optional[datetime]
|
||||
start_time: Optional[datetime]
|
||||
end_time: Optional[datetime]
|
||||
process_length: Optional[float]
|
||||
process_weight: Optional[float]
|
||||
avg_speed: Optional[float]
|
||||
max_speed: Optional[float]
|
||||
acid_consumption: Optional[float]
|
||||
inlet_thickness: Optional[float]
|
||||
outlet_thickness: Optional[float]
|
||||
quality_grade: Optional[str]
|
||||
operator: Optional[str]
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
66
backend/app/schemas/quality.py
Normal file
66
backend/app/schemas/quality.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class QualityRecordCreate(BaseModel):
|
||||
coil_no: str
|
||||
production_record_id: Optional[int] = None
|
||||
thickness_actual: Optional[float] = None
|
||||
width_actual: Optional[float] = None
|
||||
flatness: Optional[float] = None
|
||||
crown: Optional[float] = None
|
||||
surface_defect_type: Optional[str] = None
|
||||
defect_length_m: Optional[float] = None
|
||||
defect_position: Optional[str] = None
|
||||
pi_score: Optional[float] = None
|
||||
surface_score: Optional[float] = None
|
||||
overall_grade: Optional[str] = None
|
||||
acid_residual: Optional[float] = None
|
||||
roughness_ra: Optional[float] = None
|
||||
inspector: Optional[str] = None
|
||||
inspect_time: Optional[datetime] = None
|
||||
is_passed: Optional[bool] = True
|
||||
|
||||
|
||||
class QualityRecordUpdate(BaseModel):
|
||||
thickness_actual: Optional[float] = None
|
||||
width_actual: Optional[float] = None
|
||||
flatness: Optional[float] = None
|
||||
crown: Optional[float] = None
|
||||
surface_defect_type: Optional[str] = None
|
||||
defect_length_m: Optional[float] = None
|
||||
defect_position: Optional[str] = None
|
||||
pi_score: Optional[float] = None
|
||||
surface_score: Optional[float] = None
|
||||
overall_grade: Optional[str] = None
|
||||
acid_residual: Optional[float] = None
|
||||
roughness_ra: Optional[float] = None
|
||||
inspector: Optional[str] = None
|
||||
inspect_time: Optional[datetime] = None
|
||||
is_passed: Optional[bool] = None
|
||||
|
||||
|
||||
class QualityRecordOut(BaseModel):
|
||||
id: int
|
||||
coil_no: str
|
||||
production_record_id: Optional[int]
|
||||
thickness_actual: Optional[float]
|
||||
width_actual: Optional[float]
|
||||
flatness: Optional[float]
|
||||
crown: Optional[float]
|
||||
surface_defect_type: Optional[str]
|
||||
defect_length_m: Optional[float]
|
||||
defect_position: Optional[str]
|
||||
pi_score: Optional[float]
|
||||
surface_score: Optional[float]
|
||||
overall_grade: Optional[str]
|
||||
acid_residual: Optional[float]
|
||||
roughness_ra: Optional[float]
|
||||
inspector: Optional[str]
|
||||
inspect_time: Optional[datetime]
|
||||
is_passed: Optional[bool]
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
41
backend/app/schemas/user.py
Normal file
41
backend/app/schemas/user.py
Normal file
@@ -0,0 +1,41 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class LoginRequest(BaseModel):
|
||||
username: str
|
||||
password: str
|
||||
|
||||
|
||||
class Token(BaseModel):
|
||||
access_token: str
|
||||
token_type: str = "bearer"
|
||||
username: str
|
||||
role: str
|
||||
|
||||
|
||||
class UserCreate(BaseModel):
|
||||
username: str
|
||||
full_name: Optional[str] = None
|
||||
password: str
|
||||
role: str = "operator"
|
||||
|
||||
|
||||
class UserUpdate(BaseModel):
|
||||
full_name: Optional[str] = None
|
||||
role: Optional[str] = None
|
||||
is_active: Optional[bool] = None
|
||||
password: Optional[str] = None
|
||||
|
||||
|
||||
class UserOut(BaseModel):
|
||||
id: int
|
||||
username: str
|
||||
full_name: Optional[str]
|
||||
role: str
|
||||
is_active: bool
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
Reference in New Issue
Block a user