Files
shanxia2.0/backend/app/core/config.py
T
2026-07-15 08:05:38 +08:00

187 lines
6.8 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.
from pydantic_settings import BaseSettings
from typing import Optional
from pathlib import Path
import os
class Settings(BaseSettings):
"""应用配置"""
# 应用基础配置
APP_NAME: str = "shanxia2.0 管理骨架"
DEBUG: bool = True
API_V1_PREFIX: str = "/api"
# 数据库配置
DATABASE_URL: str = "mysql+pymysql://root:password@localhost:3306/sanqiang"
# pymysql 连接/读写超时(秒);远程库或休眠唤醒后避免 SELECT 无限阻塞
DB_CONNECT_TIMEOUT_SEC: int = 10
DB_READ_TIMEOUT_SEC: int = 10
DB_WRITE_TIMEOUT_SEC: int = 10
# 连接池回收周期(秒),宜小于 MySQL wait_timeout / 防火墙 idle 超时
DB_POOL_RECYCLE_SEC: int = 600
DB_POOL_SIZE: int = 5
DB_MAX_OVERFLOW: int = 10
# 后台保活间隔(秒),远程 MySQL 空闲 TCP 被回收时主动 SELECT 1
DB_KEEPALIVE_INTERVAL_SEC: int = 240
# JWT配置
SECRET_KEY: str = "your-secret-key-change-in-production-please-use-random-string"
ALGORITHM: str = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES: int = 30 * 24 # 30天
# CORS配置
BACKEND_CORS_ORIGINS: list = [
"http://localhost:5173", # art-design-pro 开发服务器
"http://localhost:8080",
"http://localhost:8081", # uni-app H5 端口被占用时常用
"http://localhost:8082",
"http://127.0.0.1:5173",
"http://127.0.0.1:8080",
"http://127.0.0.1:8081",
"http://127.0.0.1:8082",
"http://localhost:3000", # Web开发
"http://localhost:3006", # Web开发
"http://127.0.0.1:3000",
"http://127.0.0.1:3006",
]
# 文件存储配置
STORAGE_TYPE: str = "local" # local, qiniu, oss, minio
# 本地存储配置
LOCAL_UPLOAD_DIR: str = "uploads"
LOCAL_STORAGE_URL: str = "/uploads"
# Redis 配置(用于登录会话与 refreshToken 吊销)
# 未配置 REDIS_HOST 时,后端会保持兼容:仍然只校验 JWT,不强制会话吊销。
REDIS_HOST: str = ""
REDIS_PORT: int = 6379
REDIS_DB: int = 0
REDIS_PASSWORD: str = ""
REDIS_TIMEOUT_SEC: int = 5
REDIS_CONNECT_TIMEOUT_SEC: int = 5
REDIS_HEALTH_CHECK_INTERVAL_SEC: int = 30
# asyncio 层 Redis 操作超时(秒),与会话校验/续期一致
REDIS_OP_TIMEOUT_SEC: int = 3
REDIS_SSL_ENABLED: bool = False
# 七牛云存储配置 (生产环境推荐)
QINIU_ACCESS_KEY: str = ""
QINIU_SECRET_KEY: str = ""
QINIU_BUCKET: str = ""
QINIU_DOMAIN: str = ""
# 阿里云OSS配置 (可选)
OSS_ACCESS_KEY_ID: str = ""
OSS_ACCESS_KEY_SECRET: str = ""
OSS_BUCKET: str = ""
OSS_ENDPOINT: str = ""
OSS_DOMAIN: str = ""
# 阿里云 OCR(身份证 / 驾驶证识别)
ALIYUN_OCR_ACCESS_KEY_ID: str = ""
ALIYUN_OCR_ACCESS_KEY_SECRET: str = ""
ALIYUN_OCR_ENDPOINT: str = "ocr-api.cn-hangzhou.aliyuncs.com"
ALIYUN_OCR_MONTHLY_LIMIT: int = 170
# MinIO配置
MINIO_ENDPOINT: str = ""
MINIO_ACCESS_KEY: str = ""
MINIO_SECRET_KEY: str = ""
MINIO_BUCKET: str = ""
MINIO_SECURE: bool = False
MINIO_BASE_URL: str = ""
# 微信支付配置 (生产环境必需)
WXPAY_MCHID: str = "" # 商户号
WXPAY_APPID: str = "" # 公众号AppID
WXPAY_MINI_APPID: str = "" # 小程序AppID
WXPAY_API_KEY: str = "" # API密钥 (V2)
WXPAY_SANDBOX: bool = False # 是否使用沙箱环境
WXPAY_NOTIFY_URL: str = "https://your-domain.com/api/payment/notify" # 支付回调地址
WXPAY_REFUND_NOTIFY_URL: str = "https://your-domain.com/api/payment/refund-notify" # 退款回调地址
# V3 API 证书配置
WXPAY_CERT_PATH: str = "" # API证书(apiclient_cert.pem)路径
WXPAY_PRIVATE_KEY_PATH: str = "" # API私钥(apiclient_key.pem)路径
WXPAY_SERIAL_NO: str = "" # 证书序列号
# SSL证书配置 (退款必需)
WXPAY_SSL_CERT: str = "" # SSL证书路径
WXPAY_SSL_KEY: str = "" # SSL私钥路径
# 微信小程序配置
WXPAY_SECRET: str = "" # 小程序Secret
# 微信模板消息ID配置
WX_TEMPLATE_ORDER_STATUS: str = "" # 订单状态通知模板ID
WX_TEMPLATE_DELIVERY_NOTICE: str = "" # 配送通知模板ID
WX_TEMPLATE_PAYMENT_SUCCESS: str = "" # 支付成功通知模板ID
WX_TEMPLATE_REFUND_RESULT: str = "" # 退款结果通知模板ID
WX_TEMPLATE_DELIVERY_WARNING: str = "" # 配送时效预警模板ID
# 与 docs/sql/shanxia2.0.sql 基线一致:登录按租户 + sys_user.user_no
DEFAULT_TENANT_NO: str = "shanxia2.0"
# 无 user_id 等异常链路的 Web 角色兜底;未绑定 sys_user_role 的用户在 resolve_web_role_for_user 中固定为 admin
WEB_AUTH_DEFAULT_ROLE: str = "admin"
# 登录 RSA:私钥 PEM(多实例/负载均衡须配置同一私钥;留空则进程启动时临时生成,仅适合单机开发)
LOGIN_RSA_PRIVATE_KEY_PEM: str = ""
# 是否允许明文 username/password 登录(仅建议本地排障临时开启;生产务必 false)
LOGIN_ALLOW_PLAINTEXT_LOGIN: bool = False
# 加密载荷内时间戳允许偏差(秒),防简单重放
LOGIN_ENCRYPT_TS_SKEW_SEC: int = 300
# 临时文件目录
TEMP_FILE_DIR: str = "temp_files"
# 司机免登录 H5 页面 Origin(用于拼接 driverUrl)
PUBLIC_WEB_ORIGIN: str = "http://localhost:3006"
# 全量 API 请求日志(中间件写入 sys_api_request_log)
API_REQUEST_LOG_ENABLED: bool = True
API_REQUEST_LOG_MAX_BODY: int = 65536
API_REQUEST_LOG_MAX_BODY_BYTES: int = 131072
API_REQUEST_LOG_EXCLUDE_PATHS: str = ""
# Web API 请求/响应加密配置
API_ENCRYPT_ENABLED: bool = False
API_ENCRYPT_FAIL_OPEN: bool = True
API_ENCRYPT_FIXED_SECRET: str = ""
API_ENCRYPT_TS_SKEW_SEC: int = 300
API_ENCRYPT_NONCE_TTL_SEC: int = 300
API_ENCRYPT_EXCLUDE_PATHS: str = (
"/,"
"/health,"
"/docs,"
"/openapi.json,"
"/api/web/auth/login-rsa-public-key,"
"/api/web/auth/login,"
"/api/web/auth/refresh-token,"
"/api/web/admin/attachment/upload,"
"/api/web/admin/products/upload-image,"
"/api/web/admin/categories/upload-image,"
"/api/web/admin/users/upload-avatar,"
"/api/invoice/download,"
"/api/bx/health,"
"/api/db/health,"
"/api/expense-items,"
"/api/workflows,"
"/api/advances,"
"/api/reimburses,"
"/api/payments,"
"/api/attachments,"
"/api/public/pl/transport,"
"/api/public/pl/site,"
"/api/public/db/inventory"
)
class Config:
# 支持通过 ENV_FILE 指定环境文件;未指定时回退到 backend/.env
_default_env_file = Path(__file__).resolve().parents[2] / ".env"
env_file = os.getenv("ENV_FILE", str(_default_env_file))
case_sensitive = True
settings = Settings()