57ddcd356b
客户端已删手动兑入口、改「0 点自动兑现金」,服务端补这条批处理: - wallet.exchange_coins_to_cash 加 remark / enforce_min 参数:enforce_min=False(自动兑)只要够 1 分(COIN_PER_CENT)即可,不受手动兑下限约束;remark 可定制。 - 新增 wallet.daily_auto_exchange(db):扫 coin_balance>=100 的用户,到分全额(floor(余额/100)*100) 兑现金,零头留下次;幂等键=当天是否已有 exchange_in 流水(_has_exchange_in_on);逐用户独立事务, 单用户异常 rollback 不中断。 - scripts/daily_auto_exchange.py(--once / --loop):带 .env AUTO_EXCHANGE_ENABLED 开关(false→no-op) + 文件锁防重入;deploy/ 配 systemd service+timer(0 点触发)+ 说明。 - config.AUTO_EXCHANGE_ENABLED(默认 true)+ .env.example。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: OuYingJun1024 <1034284404@qq.com> Reviewed-on: #45 Co-authored-by: ouzhou <ouzhou@wonderable.ai> Co-committed-by: ouzhou <ouzhou@wonderable.ai>
98 lines
4.9 KiB
Bash
98 lines
4.9 KiB
Bash
# ===== 环境 =====
|
|
# dev / prod。dev 模式下若 JG_PRIVATE_KEY_PATH 指向的文件不存在,jverify-login 接口会拒绝调用
|
|
# (而不是 import 时炸进程),并提示用 mock 模式跑通其他链路。
|
|
APP_ENV=dev
|
|
APP_NAME=shaguabijia-app-server
|
|
APP_DEBUG=true
|
|
|
|
# ===== 数据库 =====
|
|
# SQLite 本地文件路径。生产环境用 /opt/shaguabijia-app-server/data.db
|
|
DATABASE_URL=sqlite:///./data/app.db
|
|
|
|
# ===== JWT =====
|
|
# 生产部署务必改成随机长字符串,可用:python -c "import secrets; print(secrets.token_urlsafe(64))"
|
|
JWT_SECRET_KEY=
|
|
JWT_ALGORITHM=HS256
|
|
# access token 有效期(分钟),默认 2 小时
|
|
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=120
|
|
# refresh token 有效期(天),默认 30 天
|
|
JWT_REFRESH_TOKEN_EXPIRE_DAYS=30
|
|
|
|
# ===== 极光一键登录 =====
|
|
# 控制台 → 应用设置 → 应用信息 拿到
|
|
JG_APP_KEY=
|
|
JG_MASTER_SECRET=
|
|
# RSA 私钥路径(本地开发可指到项目里的 secrets/jverify_rsa_private.pem,生产用 /opt 下绝对路径)
|
|
JG_PRIVATE_KEY_PATH=./secrets/jverify_rsa_private.pem
|
|
JG_VERIFY_ENDPOINT=https://api.verification.jpush.cn/v1/web/loginTokenVerify
|
|
JG_REQUEST_TIMEOUT_SEC=15
|
|
|
|
# ===== 短信 (mock 模式) =====
|
|
# mock = true 时,任意 6 位数字均通过,且 /sms/send 不真发短信(只 log)。
|
|
# 后续接阿里云/腾讯云短信时,改成 false 并填供应商相关 key。
|
|
SMS_MOCK=true
|
|
SMS_CODE_TTL_SEC=300
|
|
SMS_SEND_INTERVAL_SEC=60
|
|
|
|
# ===== 美团联盟 CPS =====
|
|
# 美团联盟后台 → 媒体管理 拿到的 appkey 和密钥
|
|
MT_CPS_APP_KEY=
|
|
MT_CPS_APP_SECRET=
|
|
# 默认渠道追踪标识(sid),用于区分不同 app 的 CPS 数据
|
|
MT_CPS_DEFAULT_SID=sgbjia
|
|
# 美团调用走的代理。⚠️ 本机/内网开发直连美团会 SSL EOF,必须填本地代理(如 http://127.0.0.1:7897);
|
|
# 线上国内服务器留空(=直连)。留空且本机直连失败时 /feed、/coupons、/top-sales 会返回空。
|
|
MT_CPS_PROXY=
|
|
|
|
# ===== Pricebot 上游 (领券/比价业务透传目标) =====
|
|
# 客户端调本服务的 /api/v1/coupon/step 等,我们透传到 pricebot-backend。
|
|
# 本地开发用 localhost:8000。生产部署改成内网地址(如 http://pricebot.internal:8000)。
|
|
PRICEBOT_BASE_URL=http://localhost:8000
|
|
# 【多实例】单机多进程部署时,填逗号分隔的实例列表(端口与 pricebot 集群对齐),透传层按
|
|
# trace_id 一致性 hash 选实例 → 同一比价所有帧落同一进程(进程内维护 state,无需 Redis)。
|
|
# 留空 = 单实例(用上面的 PRICEBOT_BASE_URL)。详见 pricebot-backend/docs/并发部署设计.md
|
|
# PRICEBOT_INSTANCES=http://127.0.0.1:8001,http://127.0.0.1:8002,http://127.0.0.1:8003,http://127.0.0.1:8004,http://127.0.0.1:8005,http://127.0.0.1:8006
|
|
# 领券单帧最多 wait 6s,加网络往返,30s 兜底
|
|
PRICEBOT_REQUEST_TIMEOUT_SEC=30
|
|
# 比价(intent/recognize + price/step)透传超时:大上下文 LLM + 逐帧 LLM,给 60s
|
|
PRICEBOT_COMPARE_TIMEOUT_SEC=60
|
|
|
|
# ===== 内部端点 (server→server, pricebot 上报价格观测) =====
|
|
# pricebot 比价 done 后把各平台到手价 POST 到本服务 /internal/price-observation 落库
|
|
# (price_observation 表,比价资产沉淀层),靠共享密钥头 X-Internal-Secret 校验。
|
|
# 必须与 pricebot 侧的 INTERNAL_API_SECRET **同值**;留空 = 内部写端点关闭(返 503)。
|
|
# 启用前两边都填同一高熵串:python -c "import secrets; print(secrets.token_urlsafe(48))"
|
|
INTERNAL_API_SECRET=
|
|
|
|
# ===== CORS =====
|
|
# 逗号分隔,生产留空(只让 app 调,不开放 web)。本地开发可加 http://localhost:5173 之类
|
|
CORS_ALLOW_ORIGINS=
|
|
|
|
# ===== 微信支付(商家转账到零钱 / 提现)=====
|
|
# appid/secret 来自微信开放平台移动应用;mch/序列号/公钥ID 来自微信支付商户平台。
|
|
# 证书 .pem 放 secrets/(已 gitignore)。
|
|
WECHAT_APP_ID=wxxxxxxxxxxxxxxxxx
|
|
WECHAT_APP_SECRET=your_app_secret
|
|
WXPAY_MCH_ID=your_mch_id
|
|
WXPAY_MCH_SERIAL_NO=your_cert_serial_no
|
|
WXPAY_MCH_PRIVATE_KEY_PATH=./secrets/apiclient_key.pem
|
|
WXPAY_PUBLIC_KEY_ID=PUB_KEY_ID_xxxxxxxx
|
|
WXPAY_PUBLIC_KEY_PATH=./secrets/pub_key.pem
|
|
WXPAY_TRANSFER_SCENE_ID=1000
|
|
WXPAY_AUTH_NOTIFY_URL=
|
|
WITHDRAW_AUTO_RECONCILE_ENABLED=false
|
|
WITHDRAW_AUTO_RECONCILE_INTERVAL_SEC=300
|
|
WITHDRAW_AUTO_RECONCILE_OLDER_THAN_MINUTES=15
|
|
# 0 点自动兑金币开关(deploy/daily-exchange.timer 触发的脚本读它;false=脚本 no-op)。默认 true。
|
|
AUTO_EXCHANGE_ENABLED=true
|
|
|
|
# ===== 穿山甲激励视频(服务端发奖回调)=====
|
|
# 看完激励视频后穿山甲服务器 S2S 回调本服务发金币(客户端不参与发奖)。
|
|
# PANGLE_REWARD_SECRET 是穿山甲后台配置的"奖励校验密钥",用于验签,从后台取到后填这里;
|
|
# 配齐并把 ENABLED=true 后,/api/v1/ad/pangle-callback 才受理回调(否则 503)。
|
|
PANGLE_CALLBACK_ENABLED=false
|
|
PANGLE_REWARD_SECRET=
|
|
# ⚠️ 仅本地联调:true 时开放 POST /api/v1/ad/test-grant,让 debug 客户端看完广告直接发奖,
|
|
# 验证"看广告→金币到账"全链路(未部署公网、穿山甲 S2S 打不到本地时用)。生产必须 false(绕过反作弊)。
|
|
AD_REWARD_TEST_GRANT_ENABLED=false
|