feat: add dual-store actions to price comparison
This commit is contained in:
@@ -402,7 +402,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
|
||||
# ==========================================
|
||||
# 系統版本與路徑
|
||||
# ==========================================
|
||||
SYSTEM_VERSION = "V10.693"
|
||||
SYSTEM_VERSION = "V10.694"
|
||||
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
|
||||
public_url = PUBLIC_URL # 用於模板顯示
|
||||
|
||||
|
||||
@@ -770,3 +770,4 @@ POSTGRES_HOST=momo-db
|
||||
| 2026-06-25 | 全頁價格方向統一為 PChome 成長視角 | V10.691 起 AI Intelligence、Daily Sales、Growth Analysis、Dashboard、Telegram 與 AI 報告 prompt 不再使用「PChome 價格壓力 / MOMO 價格優勢 / MOMO 更便宜 / PChome 有優勢」等易混淆詞;統一為「PChome 價格優勢」與「MOMO 低價壓力」。 |
|
||||
| 2026-06-25 | 候選比較卡與價格語意必須有測試防線 | V10.692 起 `tests/test_pchome_revenue_growth_service.py` 鎖定 `/ai_intelligence` 模板必須提供 PChome/MOMO 雙賣場連結、雙開賣場操作與白話候選理由,且不得再出現 `variant_selection_review`、`focused_exact_identity`、`source_code`、`momo_reference` 或反向價格詞。 |
|
||||
| 2026-06-25 | 成長報表不得把比價內部指標整排丟給使用者 | V10.693 起 `/growth_analysis` 的比價品質區改為「PChome 價格作戰可用度」:只呈現可直接決策、同款覆蓋、價格需刷新、待補/待確認四個訊號,並依資料狀態給下一步建議與今日作戰入口;測試禁止回到「比價資料品質、高信心門檻、未知新鮮度、人工否決」這類工程化列表。 |
|
||||
| 2026-06-25 | 比價頁每筆結果也必須能雙開賣場 | V10.694 起 `/price_comparison` 的結果列在 PChome/MOMO 連結都存在時提供「雙開賣場」操作,Excel 與手動輸入提示改成白話作戰語言,不再顯示「格式說明、欄位、商品名稱,價格」這類工程化提示;`tests/test_frontend_v2_assets.py` 鎖定此行為。 |
|
||||
|
||||
@@ -956,7 +956,7 @@
|
||||
</div>
|
||||
<div class="price-note">
|
||||
<i class="fas fa-info-circle me-1"></i>
|
||||
Excel 需包含「商品名稱」和「售價」欄位。可選包含「商品編號」和「連結」。
|
||||
Excel 至少要有商品名稱與售價;有賣場連結時會一起帶入雙開比對。
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@@ -979,9 +979,8 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="price-note py-2">
|
||||
<i class="fas fa-info-circle me-1"></i>
|
||||
<strong>格式說明:</strong> 每行一筆商品,用<strong>逗號</strong>或 <strong>Tab</strong> 分隔<br>
|
||||
<code>商品名稱,價格</code> 或 <code>商品名稱,價格,商品連結(選填)</code>
|
||||
<i class="fas fa-bullseye me-1"></i>
|
||||
貼上 MOMO 商品、售價與賣場連結;系統會整理成可比價清單。
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">商品資料</label>
|
||||
@@ -1314,7 +1313,7 @@ La Roche-Posay 安得利防曬液 50ml,920
|
||||
parts = line.split('\t');
|
||||
}
|
||||
if (parts.length < 2) {
|
||||
showToast(`第 ${i + 1} 行格式錯誤,請使用「商品名稱,價格」,例如:理膚寶水 B5修復霜,680。`, 'warning');
|
||||
showToast(`第 ${i + 1} 行缺商品名稱或售價,請補齊後再加入比價清單。`, 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1699,10 +1698,20 @@ La Roche-Posay 安得利防曬液 50ml,920
|
||||
// 處理 URL (可能是 url 或 product_url)
|
||||
const pchomeUrl = toSafeUrl(m.pchome?.url || m.pchome?.product_url || '');
|
||||
const momoUrl = toSafeUrl(m.momo?.url || m.momo?.product_url || '');
|
||||
const dualOpenButton = pchomeUrl && momoUrl
|
||||
? `<button type="button"
|
||||
class="btn btn-sm btn-outline-primary mt-2"
|
||||
data-pchome-url="${escapeHtml(pchomeUrl)}"
|
||||
data-momo-url="${escapeHtml(momoUrl)}"
|
||||
onclick="openComparisonStores(this)">
|
||||
<i class="fas fa-up-right-from-square me-1"></i>雙開賣場
|
||||
</button>`
|
||||
: '';
|
||||
|
||||
row.innerHTML = `
|
||||
<td>
|
||||
${actionBadge}
|
||||
${dualOpenButton}
|
||||
</td>
|
||||
<td>
|
||||
<div class="d-flex align-items-start">
|
||||
@@ -1757,6 +1766,22 @@ La Roche-Posay 安得利防曬液 50ml,920
|
||||
document.getElementById('resultSection').style.display = 'block';
|
||||
}
|
||||
|
||||
function openComparisonStores(button) {
|
||||
const pchomeUrl = toSafeUrl(button?.dataset?.pchomeUrl || '');
|
||||
const momoUrl = toSafeUrl(button?.dataset?.momoUrl || '');
|
||||
const opened = [];
|
||||
if (pchomeUrl) opened.push(window.open(pchomeUrl, `pchome_compare_${Date.now()}`));
|
||||
if (momoUrl) opened.push(window.open(momoUrl, `momo_compare_${Date.now()}`));
|
||||
for (const win of opened) {
|
||||
if (win) {
|
||||
try { win.opener = null; } catch (_) {}
|
||||
}
|
||||
}
|
||||
if (opened.some((win) => !win)) {
|
||||
showToast('瀏覽器擋住了其中一個視窗;請用商品旁的 PChome / MOMO 按鈕分別開啟。', 'warning');
|
||||
}
|
||||
}
|
||||
|
||||
function getResultActionBadge(match) {
|
||||
if (match.cheaper_at === 'momo') {
|
||||
return '<span class="price-action-pill is-urgent">檢查售價</span>';
|
||||
|
||||
@@ -572,10 +572,19 @@ def test_price_comparison_page_is_action_oriented_and_plain_chinese():
|
||||
assert "主推曝光" in template
|
||||
assert "PChome 貴" in template
|
||||
assert "PChome 便宜" in template
|
||||
assert "雙開賣場" in template
|
||||
assert "openComparisonStores" in template
|
||||
assert "data-pchome-url" in template
|
||||
assert "data-momo-url" in template
|
||||
assert "Excel 至少要有商品名稱與售價" in template
|
||||
assert "貼上 MOMO 商品、售價與賣場連結" in template
|
||||
assert "resetComparisonResult" in template
|
||||
assert "showToast" in template
|
||||
assert "text.textContent = message" in template
|
||||
assert "toast.innerHTML" not in template
|
||||
assert "格式說明" not in template
|
||||
assert "商品名稱,價格" not in template
|
||||
assert "欄位" not in template
|
||||
assert "Step 1" not in template
|
||||
assert "Step 2" not in template
|
||||
assert "Step 3" not in template
|
||||
|
||||
Reference in New Issue
Block a user