Files
v6ole f1f8518985 ```
feat(auth): 添加用户权限获取接口并完善JWT令牌角色信息

- 在JWT令牌中添加用户角色信息
- 新增get_my_permissions接口用于获取当前用户权限码列表
- 重构认证回调逻辑,增加错误日志记录
- 更新用户信息获取接口使用Authorization头验证
```
2026-04-06 00:40:08 +08:00

239 lines
7.0 KiB
Python

"""库存管理 Pydantic 模式"""
from typing import Optional, List, Any
from datetime import date, datetime
from decimal import Decimal
from pydantic import BaseModel
# ── 物料分类 ──────────────────────────────────────────────────────────────────
class CategoryCreate(BaseModel):
name: str
code: str
description: Optional[str] = None
class CategoryResponse(BaseModel):
id: int
name: str
code: str
description: Optional[str] = None
created_at: Optional[datetime] = None
class Config:
from_attributes = True
# ── 物料 ──────────────────────────────────────────────────────────────────────
class MaterialCreate(BaseModel):
category_id: int
name: str
model: Optional[str] = None
specification: Optional[str] = None
brand: Optional[str] = None
unit: str = "个"
safe_quantity: int = 0
notes: Optional[str] = None
class MaterialUpdate(BaseModel):
name: Optional[str] = None
model: Optional[str] = None
specification: Optional[str] = None
brand: Optional[str] = None
unit: Optional[str] = None
safe_quantity: Optional[int] = None
notes: Optional[str] = None
class MaterialResponse(BaseModel):
id: int
category_id: int
category_name: Optional[str] = None
name: str
model: Optional[str] = None
specification: Optional[str] = None
brand: Optional[str] = None
unit: str
safe_quantity: int
notes: Optional[str] = None
total_quantity: int = 0
available_quantity: int = 0
created_at: Optional[datetime] = None
class Config:
from_attributes = True
class MaterialListResponse(BaseModel):
total: int
items: List[MaterialResponse]
# ── 库存批次 ──────────────────────────────────────────────────────────────────
class BatchCreate(BaseModel):
material_id: int
batch_no: str
quantity: int
supplier: Optional[str] = None
purchase_date: Optional[date] = None
purchase_price: Optional[Decimal] = None
location: Optional[str] = None
notes: Optional[str] = None
class BatchResponse(BaseModel):
id: int
material_id: int
material_name: Optional[str] = None
batch_no: str
quantity: int
available_quantity: int
supplier: Optional[str] = None
purchase_date: Optional[date] = None
purchase_price: Optional[Decimal] = None
location: Optional[str] = None
status: str
created_at: Optional[datetime] = None
class Config:
from_attributes = True
# ── 序列号设备 ────────────────────────────────────────────────────────────────
class SerialDeviceCreate(BaseModel):
material_id: int
batch_id: Optional[int] = None
serial_no: str
mac_address: Optional[str] = None
asset_no: Optional[str] = None
notes: Optional[str] = None
class SerialDeviceResponse(BaseModel):
id: int
material_id: int
material_name: Optional[str] = None
batch_id: Optional[int] = None
serial_no: str
mac_address: Optional[str] = None
asset_no: Optional[str] = None
status: str
current_location: Optional[str] = None
installed_info: Optional[Any] = None
notes: Optional[str] = None
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
class Config:
from_attributes = True
class SerialDeviceListResponse(BaseModel):
total: int
items: List[SerialDeviceResponse]
# ── 出入库操作 ────────────────────────────────────────────────────────────────
class PurchaseInRequest(BaseModel):
material_id: int
batch_no: str
quantity: int
supplier: Optional[str] = None
purchase_date: Optional[date] = None
purchase_price: Optional[Decimal] = None
location: Optional[str] = None
serial_nos: Optional[List[str]] = None # 高价值设备的序列号列表
notes: Optional[str] = None
class AllocateOutRequest(BaseModel):
serial_device_id: Optional[int] = None # 序列号设备
batch_id: Optional[int] = None # 批次设备
quantity: int = 1
project_name: Optional[str] = None
installation_info: Optional[Any] = None
# 方案三:领用时补录设备标识(适用于批次出库场景)
mac_address: Optional[str] = None # MAC 地址
serial_no: Optional[str] = None # 序列号
asset_no: Optional[str] = None # 资产编号
notes: Optional[str] = None
class ReturnInRequest(BaseModel):
serial_device_id: int
return_type: str # simple, repair, scrap
notes: Optional[str] = None
class TransactionResponse(BaseModel):
id: int
transaction_no: str
transaction_type: str
material_id: int
material_name: Optional[str] = None
quantity: int
from_status: Optional[str] = None
to_status: Optional[str] = None
operator_id: Optional[int] = None
project_name: Optional[str] = None
installation_info: Optional[Any] = None # 包含补录的设备信息
notes: Optional[str] = None
created_at: Optional[datetime] = None
class Config:
from_attributes = True
class TransactionListResponse(BaseModel):
total: int
items: List[TransactionResponse]
# ── 盘点 ──────────────────────────────────────────────────────────────────────
class CheckCreate(BaseModel):
check_date: date
material_id: int
batch_id: Optional[int] = None
actual_quantity: int
reason: Optional[str] = None
class CheckResponse(BaseModel):
id: int
check_no: str
check_date: date
material_id: int
material_name: Optional[str] = None
batch_id: Optional[int] = None
book_quantity: Optional[int] = None
actual_quantity: Optional[int] = None
difference: Optional[int] = None
reason: Optional[str] = None
adjusted: bool
created_at: Optional[datetime] = None
class Config:
from_attributes = True
class CheckListResponse(BaseModel):
total: int
items: List[CheckResponse]
# ── 统计 ──────────────────────────────────────────────────────────────────────
class InventorySummary(BaseModel):
total_materials: int
total_quantity: int
available_quantity: int
allocated_quantity: int
low_stock_count: int
category_stats: List[dict]