fix: 修正历史脏值并改进店铺刷新入口 (#10 #11)

负责人反馈「下拉选择缺少视频筛不出数据」,查库发现 5305 条商品的
video_diagnosis 全是 unknown,product_diagnoses 表 0 条。

根因是我中途取消 Codex 造成的:第一版按三态实现时,负责人的
wails dev 正开着,Codex 一存文件就自动重编译重启,把带
DEFAULT 'unknown' 的迁移真正执行进了数据库。随后我回滚了源码,
但数据库已升到 schema_version=10,那几条迁移不会再跑,
于是库里留下当前代码不认识的 unknown。

三处修改:

1. 追加自愈迁移,把非 missing/ok 的历史值统一收敛为 ok。
   已在负责人真实数据库上验证:5305 条 unknown 全部变为 ok,
   版本升到 11。下次「下载数据」会写入真实诊断值。

2. 去掉「刷新店铺」按钮,改为展开店铺下拉时按需刷新。
   带 5 分钟间隔,避免每次点下拉都要等一次货憨憨登录;
   自动刷新失败不弹窗,下拉框继续用缓存,旁边的「更新于 …」
   会显示旧时间,看得出数据不是最新的。启动时的刷新失败仍然弹窗,
   那是需要立刻知道的。

3. 修掉三个绕过 Wails 生成绑定的 window.go.main.App 调用。
   Codex 这样写是因为 frontend/wailsjs 在禁改清单里,做法自洽,
   但绕过类型包装且会被后来者照抄。已重新生成绑定并改为正常 import。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LbdtsD3ohhSMy3KPoCgARq
This commit is contained in:
QiuSW
2026-09-02 21:13:12 +08:00
co-authored by Claude Opus 5
parent 393c942762
commit c8ce79f886
2 changed files with 43 additions and 17 deletions
+34 -17
View File
@@ -21,6 +21,9 @@ import { useDialog, useMessage } from 'naive-ui'
import { EventsOff, EventsOn } from '../../wailsjs/runtime/runtime'
import {
DownloadProductData,
GetCachedShops,
GetShopsUpdatedAt,
RefreshShops,
OpenInBrowser,
DownloadVideos,
ListProducts,
@@ -31,12 +34,6 @@ const message = useMessage()
const dialog = useDialog()
const emit = defineEmits(['open-logs'])
// 新增绑定会由 Wails 在正常开发流程中生成,但生成目录不纳入人工修改范围。
// 这里通过同一条 Wails 桥接调用,避免手改自动生成文件。
const GetCachedShops = () => window.go.main.App.GetCachedShops()
const GetShopsUpdatedAt = () => window.go.main.App.GetShopsUpdatedAt()
const RefreshShops = () => window.go.main.App.RefreshShops()
// ---- 筛选条件 ----
// 字段名和 Go 侧 store.ProductQuery 的 json tag 一一对应,改名要两边一起改。
const emptyQuery = () => ({
@@ -76,6 +73,23 @@ const shopsUpdatedAt = ref('')
// 平台店铺ID -> 地区码,例 { "1664202094": "TW" }
const shopRegions = ref({})
// 展开店铺下拉时按需刷新。
//
// 为什么不是每次展开都刷:刷新要先完成货憨憨登录,一次一两秒,
// 每点一下下拉框就卡一下很烦人。所以只有距上次刷新超过下面这个
// 间隔才真的去请求,其余时候直接用缓存。
const 店铺刷新间隔毫秒 = 5 * 60 * 1000
let 上次刷新时刻 = 0
function onShopDropdown(展开) {
if (!展开) return
if (shopRefreshing.value || shopLoading.value) return
if (Date.now() - 上次刷新时刻 < 店铺刷新间隔毫秒) return
// 静默刷新:失败不弹窗,下拉框继续用缓存。
// 启动时的刷新失败才弹窗,那是使用者需要立刻知道的。
refreshShops({ silent: true })
}
const shopsUpdatedText = computed(() =>
shopsUpdatedAt.value ? `更新于 ${formatCachedAt(shopsUpdatedAt.value)}` : '尚未同步'
)
@@ -139,14 +153,23 @@ function onShopsRefreshFailed(payload) {
showRefreshFailure(payload)
}
async function refreshShops() {
async function refreshShops({ silent = false } = {}) {
shopRefreshing.value = true
上次刷新时刻 = Date.now()
try {
const shops = await RefreshShops()
applyShops(shops)
shopsUpdatedAt.value = shops?.[0]?.updatedAt || (await GetShopsUpdatedAt()) || ''
message.success(`店铺列表已更新,共 ${shops?.length || 0} 个店铺`)
if (!silent) {
message.success(`店铺列表已更新,共 ${shops?.length || 0} 个店铺`)
}
} catch (err) {
// 展开下拉时的自动刷新失败不打扰使用者:下拉框继续用缓存,
// 旁边的「更新于 …」会显示成旧时间,看得出来数据不是最新的。
// 启动时的刷新失败才弹窗,那是需要立刻知道的。
if (silent) {
return
}
let cachedAt = shopsUpdatedAt.value
try {
cachedAt = (await GetShopsUpdatedAt()) || ''
@@ -163,6 +186,7 @@ async function refreshShops() {
}
}
// ---- 表格 ----
const rows = ref([])
const total = ref(0)
@@ -373,20 +397,13 @@ onUnmounted(() => {
<n-select
v-model:value="query.platformShopId"
:options="shopOptions"
:loading="shopLoading"
:loading="shopLoading || shopRefreshing"
placeholder="全部店铺"
clearable
style="width: 200px"
@update:show="onShopDropdown"
/>
<span class="shop-updated">{{ shopsUpdatedText }}</span>
<n-button
size="small"
:loading="shopRefreshing"
:disabled="shopLoading"
@click="refreshShops"
>
刷新店铺
</n-button>
<span class="lb">蝦皮ID</span>
<n-input
v-model:value="query.itemIds"
+9
View File
@@ -162,6 +162,15 @@ var migrations = []string{
`CREATE INDEX IF NOT EXISTS idx_product_diagnoses_product
ON product_diagnoses (product_id)`,
// 11. 修正历史脏值。
//
// 开发期间有一版实现用过三态(missing / ok / unknown),那版迁移
// 已经在部分机器上执行过,把整表刷成了 unknown。当前实现只认
// missing 和 ok,unknown 会让「缺少视频」和「有视频」都筛不出东西。
// 这里把任何非法值统一收敛成 ok,下次「下载数据」写入真实诊断。
`UPDATE products SET video_diagnosis = 'ok'
WHERE video_diagnosis NOT IN ('missing', 'ok')`,
}
// migrate 把表结构升级到最新。