负责人反馈「下拉选择缺少视频筛不出数据」,查库发现 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:
@@ -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"
|
||||
|
||||
@@ -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 把表结构升级到最新。
|
||||
|
||||
Reference in New Issue
Block a user