import os from pathlib import Path from dotenv import load_dotenv load_dotenv(Path(__file__).parent / ".env", override=True) def _env(name, default=""): return os.environ.get(name, default) WECHAT_APPID = _env("WECHAT_APPID") WECHAT_SECRET = _env("WECHAT_SECRET") JWT_SECRET = _env("JWT_SECRET") JWT_ALGORITHM = "HS256" JWT_TTL_SECONDS = int(_env("JWT_TTL_SECONDS", str(90 * 24 * 3600))) ADMIN_KEY = _env("ADMIN_KEY") MYSQL_HOST = _env("MYSQL_HOST", "localhost") MYSQL_PORT = int(_env("MYSQL_PORT", "3306")) MYSQL_USER = _env("MYSQL_USER", "root") MYSQL_PASSWORD = _env("MYSQL_PASSWORD") MYSQL_DB = _env("MYSQL_DB", "mys_info_v3") SURVEY_DB = _env("SURVEY_DB", "myxhxc") PHONE_HMAC_KEY = _env("PHONE_HMAC_KEY", "MingYuan2026AuthKey") H5_BASE_URL = _env("H5_BASE_URL", "http://127.0.0.1:8001").rstrip("/") FEEDBACK_DIR = _env("FEEDBACK_DIR", "/home/introduction/feedback") COURSE_VOTES_FILE = _env("COURSE_VOTES_FILE", "/home/introduction/test/course_votes.json") # ── 阿里云 OSS:打卡附件 / 头像的对象存储(2026-09-22 新增)───────────── # **图片的唯一存储**。2026-09-22 收口后已无本地磁盘兜底:`PLAN_ATTACH_DIR` / # `AVATAR_DIR` / `STATIC_ROOT` 三个磁盘路径配置项随磁盘读路径一起删掉了。 # 未配置时 oss_store.is_enabled() 为 False:上传接口返回 503、读接口的 # attachment_urls 全为空串(前端干脆不显示图),**不会**退化成读写磁盘。 # 注意反馈模块(FEEDBACK_DIR)的截图仍走磁盘,它不在本次 OSS 化范围内。 # AK/SK 只从环境变量取,**不写进仓库**(.env 历史上有被 git 跟踪过,务必配 .gitignore)。 OSS_ACCESS_KEY_ID = _env("OSS_ACCESS_KEY_ID") OSS_ACCESS_KEY_SECRET = _env("OSS_ACCESS_KEY_SECRET") OSS_ENDPOINT = _env("OSS_ENDPOINT", "oss-cn-shanghai.aliyuncs.com") OSS_BUCKET = _env("OSS_BUCKET", "mingyuan-oss") # 绑了自定义域名就填这里(例:https://oss.muguaclub.cn)。 # 为什么必要:小程序 只能加载「downloadFile 合法域名」里的域名, # *.aliyuncs.com 加不进白名单;且 OSS 默认域名访问图片会强制下载、浏览器无法直接预览。 # 签名 URL 会用这个 host 计算签名(V4 的签名包含 Host),所以它必须和实际访问的域名一致。 OSS_PUBLIC_ENDPOINT = _env("OSS_PUBLIC_ENDPOINT") # 签名 URL 有效期(秒)。OSS 硬上限 604800(7 天),超了报 0002-00000232。 # 默认 5 天(432000):小程序端会把这个 URL 缓存在本地,**URL 稳定**才能让微信 # `` 的「按 URL 缓存图片」命中 —— 后端每次现签的话 Expires 每次都不同, # 微信会当作新图**反复重新下载整个文件**。 # ⚠️ 代价是泄漏窗口变长:拿到 URL 的人在有效期内都能看图,而这个桶里是学员打卡照。 # 若敏感度优先于省流量,把它调小即可 —— 前端缓存会随签名有效期自然失效,不必改代码。 OSS_URL_EXPIRE = int(_env("OSS_URL_EXPIRE", "432000")) # PostObject 表单直传签名的有效期(秒)。默认 10 分钟 —— 从「取到签名」到「传完」 # 通常只要几秒,窗口开太长等于把可写时间放大。 OSS_POST_EXPIRE = int(_env("OSS_POST_EXPIRE", "600"))