Compare commits

..

1 Commits

Author SHA1 Message Date
marco be5e94ed6d fix(alembic): 线性化 f8d3b1e60a27 接 a8c47fc4dc39,消除与 #33 mergepoint 平行的双 head
f8d3b1e60a27 最初基于旧 main(#31 双 head)写、down_revision 指向那对父;但 #33 已用 a8c47fc4dc39 合并那对 head,合入 main 后 a8c47 与 f8d3 平行 → 又成双 head,alembic upgrade head 报 Multiple heads、deploy 迁移会失败。
改 f8d3 的 down_revision 为 a8c47fc4dc39(线性接其后、只加两列),收口单 head。已 SQLite upgrade head 验证整链可 apply。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 15:43:54 +08:00
2 changed files with 21 additions and 38 deletions
@@ -1,18 +1,16 @@
"""add user.debug_trace_enabled + comparison_record.trace_url(并合并既存双 head """add user.debug_trace_enabled + comparison_record.trace_url
调试链接权限功能: 调试链接权限功能:
- user.debug_trace_enabled:运营后台给指定用户开「复制调试链接」权限 - user.debug_trace_enabled:运营后台给指定用户开「复制调试链接」权限
- comparison_record.trace_url:比价记录页「复制调试链接」的数据(pricebot done 帧给, - comparison_record.trace_url:比价记录页「复制调试链接」的数据(pricebot done 帧给,
dir 名含落盘时分秒、前端/server 拼不出,必须落库) dir 名含落盘时分秒、前端/server 拼不出,必须落库)
⚠️ 本迁移 down_revision 是 **tuple**,同时合并了 clone 时 main 上既存的双 head 注:本迁移最初基于旧 main#31,双 head)写、down_revision 曾指向那对父;但 #33 已用
- invite_fingerprint_table #31 被邀请人列表 + 指纹归因 那条线) a8c47fc4dc39 合并了那对双 head,故改为线性接在 a8c47fc4dc39 之后、只负责加两列
- 044dce6e9b1f merge_ad_feed_reward_session + withdraw_safety_indexes (避免与 a8c47fc4dc39 平行再造一个双 head)。
这两个头平行未合并,`alembic upgrade head` 会报 Multiple heads。本迁移顺手收口成单 head。
若想把「合并双 head」与「加列」拆开,可改成:先一个纯 merge 迁移、再一个加列迁移。
Revision ID: f8d3b1e60a27 Revision ID: f8d3b1e60a27
Revises: invite_fingerprint_table, 044dce6e9b1f Revises: a8c47fc4dc39
Create Date: 2026-06-10 02:40:00.000000 Create Date: 2026-06-10 02:40:00.000000
""" """
@@ -24,10 +22,7 @@ import sqlalchemy as sa
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision: str = "f8d3b1e60a27" revision: str = "f8d3b1e60a27"
down_revision: Union[str, Sequence[str], None] = ( down_revision: Union[str, Sequence[str], None] = "a8c47fc4dc39"
"invite_fingerprint_table",
"044dce6e9b1f",
)
branch_labels: Union[str, Sequence[str], None] = None branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None
+15 -27
View File
@@ -62,11 +62,11 @@
<div class="feat">💰 <span>省下的钱看得见,还能<b>赚金币提现</b></span></div> <div class="feat">💰 <span>省下的钱看得见,还能<b>赚金币提现</b></span></div>
</div> </div>
<button class="btn" id="dlbtn">🏪 打开应用商店下载</button> <button class="btn" id="dlbtn">⬇️ 下载安装包</button>
<div class="hint" id="hint">Android 安卓版 · 应用商店安全下载</div> <div class="hint" id="hint">Android 安卓版 · 安装包约 24 MB</div>
<div class="foot"> <div class="foot">
将前往应用商店下载,安全放心<br> 安装时如提示「未知来源」,请允许后继续安装<br>
本页为内部测试页。 本页为内部测试页。
</div> </div>
@@ -82,18 +82,16 @@
<div class="wxsteps"> <div class="wxsteps">
<div><span class="n">1</span>点右上角的 ··· 菜单</div> <div><span class="n">1</span>点右上角的 ··· 菜单</div>
<div><span class="n">2</span>选择「在浏览器打开」</div> <div><span class="n">2</span>选择「在浏览器打开」</div>
<div><span class="n">3</span>在浏览器里按提示去应用商店下载</div> <div><span class="n">3</span>在浏览器里点「下载安装包」</div>
</div> </div>
</div> </div>
<div class="closebar" id="wxclose">我知道了 ✕</div> <div class="closebar" id="wxclose">我知道了 ✕</div>
</div> </div>
<script> <script>
// 应用商店跳转:用包名(App 唯一标识 = 身份证号)定位到傻瓜比价的商店下载页。 // APK 下载地址跟随当前页面 origin:本地测试时页面由笔记本 app-server(LAN:8770)托管 →
// 主:market:// 唤起手机自带应用市场(华为/小米/OV);兜底:应用宝网页(任何浏览器都能开) // 下载也走 LAN;生产由 app-api.shaguabijia.com 托管 → 下载走生产域名。无需按机器改 IP
var PKG = "com.jishisongfu.shaguabijia"; var APK_URL = location.origin + "/media/shaguabijia.apk";
var MARKET_URL = "market://details?id=" + PKG;
var YYB_URL = "https://a.app.qq.com/o/simple.jsp?pkgname=" + PKG;
var ua = navigator.userAgent || ""; var ua = navigator.userAgent || "";
var isWeChat = /MicroMessenger/i.test(ua); var isWeChat = /MicroMessenger/i.test(ua);
var isIOS = /iPhone|iPad|iPod/i.test(ua); var isIOS = /iPhone|iPad|iPod/i.test(ua);
@@ -140,20 +138,12 @@
} }
return Promise.resolve(); return Promise.resolve();
} }
// 跳应用商店:先尝试 market:// 唤起手机自带商店;若 2.5s 内页面没切到后台 // 确保剪贴板写完(或最多等 400ms 兜底,防写入卡住)再触发下载。
//(= 没有商店接管 market://),兜底跳应用宝网页下载页,不让用户卡死。 function startDownload() {
function openStore() { var fired = false;
var jumped = false; function go() { if (!fired) { fired = true; window.location.href = APK_URL; } }
function markJumped() { jumped = true; } // 页面切到后台 = 商店已唤起 copyInviteCode().then(go);
document.addEventListener("visibilitychange", function () { setTimeout(go, 400);
if (document.hidden) jumped = true;
});
window.addEventListener("pagehide", markJumped);
window.addEventListener("blur", markJumped);
window.location.href = MARKET_URL; // 唤起自带应用市场
setTimeout(function () {
if (!jumped) window.location.href = YYB_URL; // 没唤起 → 应用宝网页兜底
}, 2500);
} }
var hint = document.getElementById("hint"); var hint = document.getElementById("hint");
@@ -170,10 +160,8 @@
document.getElementById("dlbtn").addEventListener("click", function(){ document.getElementById("dlbtn").addEventListener("click", function(){
if (isWeChat) { showMask(); return; } // 微信内:引导去浏览器 if (isWeChat) { showMask(); return; } // 微信内:引导去浏览器
if (isIOS) { alert("iOS 版即将上线,请前往 App Store 搜索「傻瓜比价」"); return; } if (isIOS) { alert("iOS 版即将上线,请前往 App Store 搜索「傻瓜比价」"); return; }
// 安卓浏览器:先把邀请码写进剪贴板(legacyCopy 同步写、最可靠),再跳应用商店。 // 普通浏览器:先把邀请码写进剪贴板(写完或 400ms 兜底),再下载 APK(首启读回完成归因)
// 剪贴板供 App 首启归因;链路长易丢时由指纹兜底(已上报 landing-track)接住。 startDownload();
copyInviteCode();
openStore();
}); });
</script> </script>
</body> </body>