feat: 完善代理商端业务逻辑与前后端框架

主要更新:
- 更新代理商端文档,明确项目由品牌方分配流程
- 新增Brief配置详情页(已配置)设计稿
- 完善工作台紧急待办中品牌新任务功能
- 整理Pencil设计文件中代理商端页面顺序
- 新增后端FastAPI框架及核心API
- 新增前端Next.js页面和组件库
- 添加.gitignore排除构建和缓存文件

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-02-05 19:27:31 +08:00
co-authored by Claude Opus 4.5
parent d52509d630
commit e4959d584f
132 changed files with 58539 additions and 21353 deletions
+9
View File
@@ -0,0 +1,9 @@
"""
工具模块
"""
from app.utils.crypto import encrypt_api_key, decrypt_api_key
__all__ = [
"encrypt_api_key",
"decrypt_api_key",
]
+84
View File
@@ -0,0 +1,84 @@
"""
加密工具
API Key 加解密
"""
import base64
import os
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from app.config import settings
def _get_fernet() -> Fernet:
"""
获取 Fernet 加密器
使用应用的 SECRET_KEY 派生加密密钥
"""
# 使用 PBKDF2 从 SECRET_KEY 派生 32 字节密钥
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=b"miaosi-api-key-salt", # 固定 salt,生产环境应配置为环境变量
iterations=100000,
)
key = base64.urlsafe_b64encode(
kdf.derive(settings.SECRET_KEY.encode())
)
return Fernet(key)
def encrypt_api_key(api_key: str) -> str:
"""
加密 API Key
Args:
api_key: 明文 API Key
Returns:
加密后的 Base64 字符串
"""
if not api_key:
return ""
fernet = _get_fernet()
encrypted = fernet.encrypt(api_key.encode())
return encrypted.decode()
def decrypt_api_key(encrypted: str) -> str:
"""
解密 API Key
Args:
encrypted: 加密的 API Key
Returns:
明文 API Key
"""
if not encrypted:
return ""
fernet = _get_fernet()
decrypted = fernet.decrypt(encrypted.encode())
return decrypted.decode()
def mask_api_key(api_key: str) -> str:
"""
脱敏 API Key
Args:
api_key: API Key(明文或加密均可)
Returns:
脱敏后的字符串,如 "sk-1234****5678"
"""
if not api_key:
return ""
if len(api_key) <= 8:
return "****"
return f"{api_key[:4]}****{api_key[-4:]}"