feat: generate permission sql for stocktake modules and implement single-device login restriction

This commit is contained in:
DXC
2026-03-20 09:11:54 +08:00
parent faea0379da
commit 4223a95f10
6 changed files with 147 additions and 4 deletions

View File

@ -1,10 +1,55 @@
# app/services/auth_service.py
from app.models.system import SysUser, SysRolePermission # <== 引入 SysRolePermission
from app.extensions import db
from app.extensions import db, redis_client
from sqlalchemy import func
from flask_jwt_extended import create_access_token, create_refresh_token
from flask_jwt_extended import create_access_token, create_refresh_token, get_jwt_identity
from flask import current_app
from app.utils.constants import UserRole
from datetime import timedelta
import json
def _store_token_to_redis(user_id, token, token_type='access'):
"""
将 Token 存储到 Redis用于单设备登录互踢
键名: user_token_{user_id}
值: token
过期时间: 与 JWT 过期时间一致
"""
if redis_client is None:
current_app.logger.warning("Redis not available, skipping token storage")
return False
try:
# 获取 JWT 过期时间配置
if token_type == 'access':
expires_delta = current_app.config.get('JWT_ACCESS_TOKEN_EXPIRES', timedelta(hours=2))
else:
expires_delta = current_app.config.get('JWT_REFRESH_TOKEN_EXPIRES', timedelta(days=7))
# 转换为秒数
expires_seconds = int(expires_delta.total_seconds())
# 存储到 Redis
key = f"user_token_{user_id}"
redis_client.setex(key, expires_seconds, token)
return True
except Exception as e:
current_app.logger.error(f"Failed to store token to Redis: {e}")
return False
def _get_token_from_redis(user_id):
"""从 Redis 获取当前有效的 Token"""
if redis_client is None:
return None
try:
key = f"user_token_{user_id}"
return redis_client.get(key)
except Exception as e:
current_app.logger.error(f"Failed to get token from Redis: {e}")
return None
class AuthService:
# 硬编码的超级管理员凭证
@ -80,6 +125,11 @@ class AuthService:
}
)
# 4. 存储 Token 到 Redis (用于单设备登录互踢)
# 使用 str(user_id) 作为 Redis key 的一部分,因为 user_id=0 是超级管理员
_store_token_to_redis(str(user_id), access_token, 'access')
_store_token_to_redis(str(user_id), refresh_token, 'refresh')
return {
'access_token': access_token,
'refresh_token': refresh_token,