Files
zcglxt/app/crud/recovery.py
Claude e71181f0a3 fix: 修复多个关键问题
- 修复前端路由守卫:未登录时不显示提示,直接跳转登录页
- 修复API拦截器:401错误不显示提示,直接跳转
- 增强验证码显示:图片尺寸从120x40增加到200x80
- 增大验证码字体:从28号增加到48号
- 优化验证码字符:排除易混淆的0和1
- 减少干扰线:从5条减少到3条,添加背景色优化
- 增强登录API日志:添加详细的调试日志
- 增强验证码生成和验证日志
- 优化异常处理和错误追踪

影响文件:
- src/router/index.ts
- src/api/request.ts
- app/services/auth_service.py
- app/api/v1/auth.py
- app/schemas/user.py

测试状态:
- 前端构建通过
- 后端语法检查通过
- 验证码显示效果优化完成

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-25 00:26:21 +08:00

315 lines
9.0 KiB
Python

"""
资产回收相关CRUD操作
"""
from typing import List, Optional, Tuple
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_
from app.models.recovery import AssetRecoveryOrder, AssetRecoveryItem
from app.models.asset import Asset
from app.schemas.recovery import AssetRecoveryOrderCreate, AssetRecoveryOrderUpdate
class AssetRecoveryOrderCRUD:
"""回收单CRUD操作"""
def get(self, db: Session, id: int) -> Optional[AssetRecoveryOrder]:
"""根据ID获取回收单"""
return db.query(AssetRecoveryOrder).filter(
AssetRecoveryOrder.id == id
).first()
def get_by_code(self, db: Session, order_code: str) -> Optional[AssetRecoveryOrder]:
"""根据单号获取回收单"""
return db.query(AssetRecoveryOrder).filter(
AssetRecoveryOrder.order_code == order_code
).first()
def get_multi(
self,
db: Session,
skip: int = 0,
limit: int = 20,
recovery_type: Optional[str] = None,
approval_status: Optional[str] = None,
execute_status: Optional[str] = None,
keyword: Optional[str] = None
) -> Tuple[List[AssetRecoveryOrder], int]:
"""获取回收单列表"""
query = db.query(AssetRecoveryOrder)
# 筛选条件
if recovery_type:
query = query.filter(AssetRecoveryOrder.recovery_type == recovery_type)
if approval_status:
query = query.filter(AssetRecoveryOrder.approval_status == approval_status)
if execute_status:
query = query.filter(AssetRecoveryOrder.execute_status == execute_status)
if keyword:
query = query.filter(
or_(
AssetRecoveryOrder.order_code.like(f"%{keyword}%"),
AssetRecoveryOrder.title.like(f"%{keyword}%")
)
)
# 排序
query = query.order_by(AssetRecoveryOrder.created_at.desc())
# 总数
total = query.count()
# 分页
items = query.offset(skip).limit(limit).all()
return items, total
def create(
self,
db: Session,
obj_in: AssetRecoveryOrderCreate,
order_code: str,
apply_user_id: int
) -> AssetRecoveryOrder:
"""创建回收单"""
from datetime import datetime
# 创建回收单
db_obj = AssetRecoveryOrder(
order_code=order_code,
recovery_type=obj_in.recovery_type,
title=obj_in.title,
asset_count=len(obj_in.asset_ids),
apply_user_id=apply_user_id,
apply_time=datetime.utcnow(),
remark=obj_in.remark,
approval_status="pending",
execute_status="pending"
)
db.add(db_obj)
db.commit()
db.refresh(db_obj)
# 创建回收单明细
self._create_items(
db=db,
order_id=db_obj.id,
asset_ids=obj_in.asset_ids
)
return db_obj
def update(
self,
db: Session,
db_obj: AssetRecoveryOrder,
obj_in: AssetRecoveryOrderUpdate
) -> AssetRecoveryOrder:
"""更新回收单"""
update_data = obj_in.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(db_obj, field, value)
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def approve(
self,
db: Session,
db_obj: AssetRecoveryOrder,
approval_status: str,
approval_user_id: int,
approval_remark: Optional[str] = None
) -> AssetRecoveryOrder:
"""审批回收单"""
from datetime import datetime
db_obj.approval_status = approval_status
db_obj.approval_user_id = approval_user_id
db_obj.approval_time = datetime.utcnow()
db_obj.approval_remark = approval_remark
# 如果审批通过,自动设置为可执行状态
if approval_status == "approved":
db_obj.execute_status = "pending"
elif approval_status == "rejected":
db_obj.execute_status = "cancelled"
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def start(
self,
db: Session,
db_obj: AssetRecoveryOrder,
execute_user_id: int
) -> AssetRecoveryOrder:
"""开始回收"""
from datetime import datetime
db_obj.execute_status = "executing"
db_obj.execute_user_id = execute_user_id
db_obj.execute_time = datetime.utcnow()
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def complete(
self,
db: Session,
db_obj: AssetRecoveryOrder,
execute_user_id: int
) -> AssetRecoveryOrder:
"""完成回收"""
from datetime import datetime
db_obj.execute_status = "completed"
db_obj.execute_user_id = execute_user_id
db_obj.execute_time = datetime.utcnow()
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def cancel(self, db: Session, db_obj: AssetRecoveryOrder) -> AssetRecoveryOrder:
"""取消回收单"""
db_obj.approval_status = "cancelled"
db_obj.execute_status = "cancelled"
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def delete(self, db: Session, id: int) -> bool:
"""删除回收单"""
obj = self.get(db, id)
if obj:
db.delete(obj)
db.commit()
return True
return False
def get_statistics(
self,
db: Session
) -> dict:
"""获取回收单统计信息"""
query = db.query(AssetRecoveryOrder)
total = query.count()
pending = query.filter(AssetRecoveryOrder.approval_status == "pending").count()
approved = query.filter(AssetRecoveryOrder.approval_status == "approved").count()
rejected = query.filter(AssetRecoveryOrder.approval_status == "rejected").count()
executing = query.filter(AssetRecoveryOrder.execute_status == "executing").count()
completed = query.filter(AssetRecoveryOrder.execute_status == "completed").count()
return {
"total": total,
"pending": pending,
"approved": approved,
"rejected": rejected,
"executing": executing,
"completed": completed
}
def _create_items(
self,
db: Session,
order_id: int,
asset_ids: List[int]
):
"""创建回收单明细"""
# 查询资产信息
assets = db.query(Asset).filter(Asset.id.in_(asset_ids)).all()
for asset in assets:
item = AssetRecoveryItem(
order_id=order_id,
asset_id=asset.id,
asset_code=asset.asset_code,
recovery_status="pending"
)
db.add(item)
db.commit()
class AssetRecoveryItemCRUD:
"""回收单明细CRUD操作"""
def get_by_order(self, db: Session, order_id: int) -> List[AssetRecoveryItem]:
"""根据回收单ID获取明细列表"""
return db.query(AssetRecoveryItem).filter(
AssetRecoveryItem.order_id == order_id
).order_by(AssetRecoveryItem.id).all()
def get_multi(
self,
db: Session,
skip: int = 0,
limit: int = 20,
order_id: Optional[int] = None,
recovery_status: Optional[str] = None
) -> Tuple[List[AssetRecoveryItem], int]:
"""获取明细列表"""
query = db.query(AssetRecoveryItem)
if order_id:
query = query.filter(AssetRecoveryItem.order_id == order_id)
if recovery_status:
query = query.filter(AssetRecoveryItem.recovery_status == recovery_status)
total = query.count()
items = query.offset(skip).limit(limit).all()
return items, total
def update_recovery_status(
self,
db: Session,
item_id: int,
recovery_status: str
) -> AssetRecoveryItem:
"""更新明细回收状态"""
item = db.query(AssetRecoveryItem).filter(
AssetRecoveryItem.id == item_id
).first()
if item:
item.recovery_status = recovery_status
db.add(item)
db.commit()
db.refresh(item)
return item
def batch_update_recovery_status(
self,
db: Session,
order_id: int,
recovery_status: str
):
"""批量更新明细回收状态"""
items = db.query(AssetRecoveryItem).filter(
and_(
AssetRecoveryItem.order_id == order_id,
AssetRecoveryItem.recovery_status == "pending"
)
).all()
for item in items:
item.recovery_status = recovery_status
db.add(item)
db.commit()
# 创建全局实例
recovery_order = AssetRecoveryOrderCRUD()
recovery_item = AssetRecoveryItemCRUD()