config.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. from pydantic_settings import BaseSettings
  2. from typing import Optional
  3. from pathlib import Path
  4. import os
  5. class Settings(BaseSettings):
  6. """应用配置"""
  7. # 应用基础配置
  8. APP_NAME: str = "陇耘鲜达"
  9. DEBUG: bool = True
  10. API_V1_PREFIX: str = "/api"
  11. # 数据库配置
  12. DATABASE_URL: str = "mysql+pymysql://root:password@localhost:3306/sanqiang"
  13. # JWT配置
  14. SECRET_KEY: str = "your-secret-key-change-in-production-please-use-random-string"
  15. ALGORITHM: str = "HS256"
  16. ACCESS_TOKEN_EXPIRE_MINUTES: int = 30 * 24 # 30天
  17. # CORS配置
  18. BACKEND_CORS_ORIGINS: list = [
  19. "http://localhost:5173", # art-design-pro 开发服务器
  20. "http://localhost:8080",
  21. "http://localhost:8081", # uni-app H5 端口被占用时常用
  22. "http://localhost:8082",
  23. "http://127.0.0.1:5173",
  24. "http://127.0.0.1:8080",
  25. "http://127.0.0.1:8081",
  26. "http://127.0.0.1:8082",
  27. "http://localhost:3000", # Web开发
  28. "http://localhost:3006", # web-admin 默认端口
  29. "http://localhost:3007", # web-admin 端口被占用时
  30. "http://127.0.0.1:3000",
  31. "http://127.0.0.1:3006",
  32. "http://127.0.0.1:3007",
  33. ]
  34. # 文件存储配置
  35. STORAGE_TYPE: str = "local" # local, qiniu, oss, minio
  36. # 本地存储配置
  37. LOCAL_UPLOAD_DIR: str = "uploads"
  38. LOCAL_STORAGE_URL: str = "/uploads"
  39. # Redis 配置(用于登录会话与 refreshToken 吊销)
  40. # 未配置 REDIS_HOST 时,后端会保持兼容:仍然只校验 JWT,不强制会话吊销。
  41. REDIS_HOST: str = ""
  42. REDIS_PORT: int = 6379
  43. REDIS_DB: int = 0
  44. REDIS_PASSWORD: str = ""
  45. REDIS_TIMEOUT_SEC: int = 30
  46. REDIS_SSL_ENABLED: bool = False
  47. # 七牛云存储配置 (生产环境推荐)
  48. QINIU_ACCESS_KEY: str = ""
  49. QINIU_SECRET_KEY: str = ""
  50. QINIU_BUCKET: str = ""
  51. QINIU_DOMAIN: str = ""
  52. # 阿里云OSS配置 (可选)
  53. OSS_ACCESS_KEY_ID: str = ""
  54. OSS_ACCESS_KEY_SECRET: str = ""
  55. OSS_BUCKET: str = ""
  56. OSS_ENDPOINT: str = ""
  57. OSS_DOMAIN: str = ""
  58. # MinIO配置
  59. MINIO_ENDPOINT: str = ""
  60. MINIO_ACCESS_KEY: str = ""
  61. MINIO_SECRET_KEY: str = ""
  62. MINIO_BUCKET: str = ""
  63. MINIO_SECURE: bool = False
  64. MINIO_BASE_URL: str = ""
  65. # 微信支付配置 (生产环境必需)
  66. WXPAY_MCHID: str = "" # 商户号
  67. WXPAY_APPID: str = "" # 公众号AppID
  68. WXPAY_MINI_APPID: str = "" # 小程序AppID
  69. WXPAY_API_KEY: str = "" # API密钥 (V2)
  70. WXPAY_SANDBOX: bool = False # 是否使用沙箱环境
  71. WXPAY_NOTIFY_URL: str = "https://your-domain.com/api/payment/notify" # 支付回调地址
  72. WXPAY_REFUND_NOTIFY_URL: str = "https://your-domain.com/api/payment/refund-notify" # 退款回调地址
  73. # V3 API 证书配置
  74. WXPAY_CERT_PATH: str = "" # API证书(apiclient_cert.pem)路径
  75. WXPAY_PRIVATE_KEY_PATH: str = "" # API私钥(apiclient_key.pem)路径
  76. WXPAY_SERIAL_NO: str = "" # 证书序列号
  77. # SSL证书配置 (退款必需)
  78. WXPAY_SSL_CERT: str = "" # SSL证书路径
  79. WXPAY_SSL_KEY: str = "" # SSL私钥路径
  80. # 微信小程序配置
  81. WXPAY_SECRET: str = "" # 小程序Secret
  82. # 微信模板消息ID配置
  83. WX_TEMPLATE_ORDER_STATUS: str = "" # 订单状态通知模板ID
  84. WX_TEMPLATE_DELIVERY_NOTICE: str = "" # 配送通知模板ID
  85. WX_TEMPLATE_PAYMENT_SUCCESS: str = "" # 支付成功通知模板ID
  86. WX_TEMPLATE_REFUND_RESULT: str = "" # 退款结果通知模板ID
  87. WX_TEMPLATE_DELIVERY_WARNING: str = "" # 配送时效预警模板ID
  88. # 登录 RSA:私钥 PEM(多实例/负载均衡须配置同一私钥;留空则进程启动时临时生成,仅适合单机开发)
  89. LOGIN_RSA_PRIVATE_KEY_PEM: str = ""
  90. # 是否允许明文 username/password 登录(仅建议本地排障临时开启;生产务必 false)
  91. LOGIN_ALLOW_PLAINTEXT_LOGIN: bool = False
  92. # 加密载荷内时间戳允许偏差(秒),防简单重放
  93. LOGIN_ENCRYPT_TS_SKEW_SEC: int = 300
  94. # 临时文件目录
  95. TEMP_FILE_DIR: str = "temp_files"
  96. # 全量 API 请求日志(中间件写入 sys_api_request_log)
  97. API_REQUEST_LOG_ENABLED: bool = True
  98. API_REQUEST_LOG_MAX_BODY: int = 65536
  99. API_REQUEST_LOG_MAX_BODY_BYTES: int = 131072
  100. # Web API 请求/响应加密配置
  101. API_ENCRYPT_ENABLED: bool = False
  102. API_ENCRYPT_FAIL_OPEN: bool = True
  103. API_ENCRYPT_FIXED_SECRET: str = ""
  104. API_ENCRYPT_TS_SKEW_SEC: int = 300
  105. API_ENCRYPT_NONCE_TTL_SEC: int = 300
  106. API_ENCRYPT_EXCLUDE_PATHS: str = (
  107. "/,"
  108. "/health,"
  109. "/docs,"
  110. "/openapi.json,"
  111. "/api/web/auth/login-rsa-public-key,"
  112. "/api/web/auth/login,"
  113. "/api/web/admin/attachment/upload,"
  114. "/api/web/admin/products/upload-image,"
  115. "/api/web/admin/categories/upload-image,"
  116. "/api/web/admin/users/upload-avatar,"
  117. "/api/invoice/download"
  118. )
  119. class Config:
  120. # 支持通过 ENV_FILE 指定环境文件;未指定时回退到 backend/.env
  121. _default_env_file = Path(__file__).resolve().parents[2] / ".env"
  122. env_file = os.getenv("ENV_FILE", str(_default_env_file))
  123. case_sensitive = True
  124. settings = Settings()