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>
This commit is contained in:
Claude
2026-01-25 00:26:21 +08:00
commit e71181f0a3
150 changed files with 39549 additions and 0 deletions

127
app/schemas/maintenance.py Normal file
View File

@@ -0,0 +1,127 @@
"""
维修管理相关的Pydantic Schema
"""
from typing import Optional, List, Dict, Any
from datetime import datetime, date
from decimal import Decimal
from pydantic import BaseModel, Field
# ===== 维修记录Schema =====
class MaintenanceRecordBase(BaseModel):
"""维修记录基础Schema"""
asset_id: int = Field(..., gt=0, description="资产ID")
fault_description: str = Field(..., min_length=1, description="故障描述")
fault_type: Optional[str] = Field(None, description="故障类型(hardware/software/network/other)")
priority: str = Field(default="normal", description="优先级(low/normal/high/urgent)")
maintenance_type: Optional[str] = Field(None, description="维修类型(self_repair/vendor_repair/warranty)")
vendor_id: Optional[int] = Field(None, gt=0, description="维修供应商ID")
maintenance_cost: Optional[Decimal] = Field(None, ge=0, description="维修费用")
maintenance_result: Optional[str] = Field(None, description="维修结果描述")
replaced_parts: Optional[str] = Field(None, description="更换的配件")
images: Optional[str] = Field(None, description="维修图片URL多个逗号分隔")
remark: Optional[str] = Field(None, description="备注")
class MaintenanceRecordCreate(MaintenanceRecordBase):
"""创建维修记录Schema"""
pass
class MaintenanceRecordUpdate(BaseModel):
"""更新维修记录Schema"""
fault_description: Optional[str] = Field(None, min_length=1)
fault_type: Optional[str] = None
priority: Optional[str] = None
maintenance_type: Optional[str] = None
vendor_id: Optional[int] = Field(None, gt=0)
maintenance_cost: Optional[Decimal] = Field(None, ge=0)
maintenance_result: Optional[str] = None
replaced_parts: Optional[str] = None
images: Optional[str] = None
remark: Optional[str] = None
class MaintenanceRecordStart(BaseModel):
"""开始维修Schema"""
maintenance_type: str = Field(..., description="维修类型")
vendor_id: Optional[int] = Field(None, gt=0, description="维修供应商IDvendor_repair时必填")
remark: Optional[str] = Field(None, description="备注")
class MaintenanceRecordComplete(BaseModel):
"""完成维修Schema"""
maintenance_result: str = Field(..., description="维修结果描述")
maintenance_cost: Optional[Decimal] = Field(None, ge=0, description="维修费用")
replaced_parts: Optional[str] = Field(None, description="更换的配件")
images: Optional[str] = Field(None, description="维修图片URL")
asset_status: str = Field(default="in_stock", description="资产维修后状态(in_stock/in_use)")
class MaintenanceRecordInDB(BaseModel):
"""数据库中的维修记录Schema"""
id: int
record_code: str
asset_id: int
asset_code: str
fault_description: str
fault_type: Optional[str]
report_user_id: Optional[int]
report_time: datetime
priority: str
maintenance_type: Optional[str]
vendor_id: Optional[int]
maintenance_cost: Optional[Decimal]
start_time: Optional[datetime]
complete_time: Optional[datetime]
maintenance_user_id: Optional[int]
maintenance_result: Optional[str]
replaced_parts: Optional[str]
status: str
images: Optional[str]
remark: Optional[str]
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class MaintenanceRecordResponse(MaintenanceRecordInDB):
"""维修记录响应Schema"""
pass
class MaintenanceRecordWithRelations(MaintenanceRecordResponse):
"""带关联信息的维修记录响应Schema"""
asset: Optional[Dict[str, Any]] = None
vendor: Optional[Dict[str, Any]] = None
report_user: Optional[Dict[str, Any]] = None
maintenance_user: Optional[Dict[str, Any]] = None
# ===== 查询参数Schema =====
class MaintenanceRecordQueryParams(BaseModel):
"""维修记录查询参数"""
asset_id: Optional[int] = Field(None, gt=0, description="资产ID")
status: Optional[str] = Field(None, description="状态")
fault_type: Optional[str] = Field(None, description="故障类型")
priority: Optional[str] = Field(None, description="优先级")
maintenance_type: Optional[str] = Field(None, description="维修类型")
keyword: Optional[str] = Field(None, description="搜索关键词")
page: int = Field(default=1, ge=1, description="页码")
page_size: int = Field(default=20, ge=1, le=100, description="每页数量")
# ===== 统计Schema =====
class MaintenanceStatistics(BaseModel):
"""维修统计Schema"""
total: int = Field(..., description="总数")
pending: int = Field(..., description="待处理数")
in_progress: int = Field(..., description="维修中数")
completed: int = Field(..., description="已完成数")
cancelled: int = Field(..., description="已取消数")
total_cost: Decimal = Field(..., description="总维修费用")