Files
zcglxt/app/utils/asset_code.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

98 lines
2.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
资产编码生成工具
使用PostgreSQL Advisory Lock保证并发安全
"""
from datetime import datetime
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.config import settings
async def generate_asset_code(db: AsyncSession) -> str:
"""
生成资产编码
格式: AS + YYYYMMDD + 流水号(4位)
示例: AS202501240001
使用PostgreSQL Advisory Lock保证并发安全
Args:
db: 数据库会话
Returns:
资产编码
"""
# 获取当前日期字符串
date_str = datetime.now().strftime("%Y%m%d")
prefix = f"AS{date_str}"
# 使用Advisory Lock保证并发安全
# 使用日期作为锁ID避免不同日期的锁冲突
lock_id = int(date_str)
try:
# 获取锁
await db.execute(text(f"SELECT pg_advisory_lock({lock_id})"))
# 查询今天最大的序号
result = await db.execute(
text("""
SELECT CAST(SUBSTRING(asset_code FROM 13 FOR 4) AS INTEGER) as max_seq
FROM assets
WHERE asset_code LIKE :prefix
AND deleted_at IS NULL
ORDER BY asset_code DESC
LIMIT 1
"""),
{"prefix": f"{prefix}%"}
)
row = result.fetchone()
max_seq = row[0] if row and row[0] else 0
# 生成新序号
new_seq = max_seq + 1
seq_str = f"{new_seq:04d}" # 补零到4位
# 组合编码
asset_code = f"{prefix}{seq_str}"
return asset_code
finally:
# 释放锁
await db.execute(text(f"SELECT pg_advisory_unlock({lock_id})"))
def validate_asset_code(asset_code: str) -> bool:
"""
验证资产编码格式
Args:
asset_code: 资产编码
Returns:
是否有效
"""
if not asset_code or len(asset_code) != 14:
return False
# 检查前缀
if not asset_code.startswith("AS"):
return False
# 检查日期部分
date_str = asset_code[2:10]
try:
datetime.strptime(date_str, "%Y%m%d")
except ValueError:
return False
# 检查序号部分
seq_str = asset_code[10:]
if not seq_str.isdigit():
return False
return True