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

108
app/schemas/statistics.py Normal file
View File

@@ -0,0 +1,108 @@
"""
统计分析相关的Pydantic Schema
"""
from typing import Optional, List, Dict, Any
from datetime import datetime, date
from decimal import Decimal
from pydantic import BaseModel, Field
class StatisticsOverview(BaseModel):
"""总览统计Schema"""
total_assets: int = Field(..., description="资产总数")
total_value: Decimal = Field(..., description="资产总价值")
in_stock_count: int = Field(..., description="库存中数量")
in_use_count: int = Field(..., description="使用中数量")
maintenance_count: int = Field(..., description="维修中数量")
scrapped_count: int = Field(..., description="已报废数量")
today_purchase_count: int = Field(..., description="今日采购数量")
this_month_purchase_count: int = Field(..., description="本月采购数量")
organization_count: int = Field(..., description="机构网点数")
supplier_count: int = Field(..., description="供应商数")
class PurchaseStatistics(BaseModel):
"""采购统计Schema"""
total_purchase_count: int = Field(..., description="总采购数量")
total_purchase_value: Decimal = Field(..., description="总采购金额")
monthly_trend: List[Dict[str, Any]] = Field(default_factory=list, description="月度趋势")
supplier_distribution: List[Dict[str, Any]] = Field(default_factory=list, description="供应商分布")
category_distribution: List[Dict[str, Any]] = Field(default_factory=list, description="分类分布")
class DepreciationStatistics(BaseModel):
"""折旧统计Schema"""
total_depreciation_value: Decimal = Field(..., description="总折旧金额")
average_depreciation_rate: Decimal = Field(..., description="平均折旧率")
depreciation_by_category: List[Dict[str, Any]] = Field(default_factory=list, description="分类折旧")
assets_near_end_life: List[Dict[str, Any]] = Field(default_factory=list, description="接近使用年限的资产")
class ValueStatistics(BaseModel):
"""价值统计Schema"""
total_value: Decimal = Field(..., description="资产总价值")
net_value: Decimal = Field(..., description="资产净值")
depreciation_value: Decimal = Field(..., description="累计折旧")
value_by_category: List[Dict[str, Any]] = Field(default_factory=list, description="分类价值")
value_by_organization: List[Dict[str, Any]] = Field(default_factory=list, description="网点价值")
high_value_assets: List[Dict[str, Any]] = Field(default_factory=list, description="高价值资产")
class TrendAnalysis(BaseModel):
"""趋势分析Schema"""
asset_trend: List[Dict[str, Any]] = Field(default_factory=list, description="资产数量趋势")
value_trend: List[Dict[str, Any]] = Field(default_factory=list, description="资产价值趋势")
purchase_trend: List[Dict[str, Any]] = Field(default_factory=list, description="采购趋势")
maintenance_trend: List[Dict[str, Any]] = Field(default_factory=list, description="维修趋势")
allocation_trend: List[Dict[str, Any]] = Field(default_factory=list, description="调拨趋势")
class MaintenanceStatistics(BaseModel):
"""维修统计Schema"""
total_maintenance_count: int = Field(..., description="总维修次数")
total_maintenance_cost: Decimal = Field(..., description="总维修费用")
pending_count: int = Field(..., description="待维修数量")
in_progress_count: int = Field(..., description="维修中数量")
completed_count: int = Field(..., description="已完成数量")
monthly_trend: List[Dict[str, Any]] = Field(default_factory=list, description="月度趋势")
type_distribution: List[Dict[str, Any]] = Field(default_factory=list, description="维修类型分布")
cost_by_category: List[Dict[str, Any]] = Field(default_factory=list, description="分类维修费用")
class AllocationStatistics(BaseModel):
"""分配统计Schema"""
total_allocation_count: int = Field(..., description="总分配次数")
pending_count: int = Field(..., description="待审批数量")
approved_count: int = Field(..., description="已批准数量")
rejected_count: int = Field(..., description="已拒绝数量")
monthly_trend: List[Dict[str, Any]] = Field(default_factory=list, description="月度趋势")
by_organization: List[Dict[str, Any]] = Field(default_factory=list, description="网点分配统计")
transfer_statistics: List[Dict[str, Any]] = Field(default_factory=list, description="调拨统计")
class StatisticsQueryParams(BaseModel):
"""统计查询参数"""
start_date: Optional[date] = Field(None, description="开始日期")
end_date: Optional[date] = Field(None, description="结束日期")
organization_id: Optional[int] = Field(None, description="网点ID")
device_type_id: Optional[int] = Field(None, description="设备类型ID")
group_by: Optional[str] = Field(None, description="分组字段")
class ExportStatisticsRequest(BaseModel):
"""导出统计请求"""
report_type: str = Field(..., description="报表类型")
start_date: Optional[date] = Field(None, description="开始日期")
end_date: Optional[date] = Field(None, description="结束日期")
organization_id: Optional[int] = Field(None, description="网点ID")
device_type_id: Optional[int] = Field(None, description="设备类型ID")
format: str = Field(default="xlsx", description="导出格式")
include_charts: bool = Field(default=False, description="是否包含图表")
class ExportStatisticsResponse(BaseModel):
"""导出统计响应"""
file_url: str = Field(..., description="文件URL")
file_name: str = Field(..., description="文件名")
file_size: int = Field(..., description="文件大小(字节)")
record_count: int = Field(..., description="记录数量")