This commit is contained in:
toom1996
2026-09-17 22:06:11 +08:00
parent 70a3304dc1
commit b04a511b26
6 changed files with 323 additions and 2 deletions

View File

@ -5,7 +5,7 @@
## 架构总览
- 前端 `d:/project/frontend_v2`:Astro(`adapter: node` standalone,SSR 取数)+ Tailwind v4 + Alpine.js。构建 `npm run build`;类型检查 `npm run check`(= `astro check`)。
- 后端 `d:/project/backend_v2`:Go + Gin + GORM(MySQL)。公开引擎 :8090(`/api/v1/public/*`、`/api/v1/auth/*`);SSG 引擎 :8091(仅 127.0.0.1,nginx 不反代)。
- 后端 `d:/project/backend_v2`:Go + Gin + GORM(**PostgreSQL** + **pgvector**)。本地库见 `scripts/pgvector`(Docker 一键,PG16+,容器名 pgvector,库 fashion,账号 fashion/fashion_dev_2026;`initdb` 自动 `CREATE EXTENSION vector`)。公开引擎 :8090(`/api/v1/public/*`、`/api/v1/auth/*`);SSG 引擎 :8091(仅 127.0.0.1,nginx 不反代)。
- 接口 i18n:后端按 `?locale=cn|en` 选列;**语言以 URL 前缀为准**;`prefixDefaultLocale: true`(/en、/cn 都带前缀;根 `/` 由服务端 302 到 /en)。
- **base 地址全在 `src/lib/config/`**:`config.baseApi`(浏览器) / `config.baseApiSsr`(SSR 绝对) / `config.baseApiSsg`(构建期内部端口)。密钥类(SSG_TOKEN)直读 env。
- 后端 Windows 编译:`go build -o server-bin.exe`(非 `server-bin`)。前端 dev 不热加载 `.env`,改 base 后 `astro dev stop`+`--background`+浏览器硬刷新。
@ -61,3 +61,15 @@
- Layout `<head>` 顶部 `is:inline`+`define:vars` 脚本:进首页(path==='/' 或 '/'+defaultLocale)且记住非默认语言时 `location.replace('/'+stored)`。
- 语言切换器 `x-data="langSwitch()"`;`<a>` `@click="open=false; pick('<code>')"`;footer 注册 `langSwitch`(`pick(code){ storeLocale(code) }`)。
- **铁律:只在显式点击切换器时写 localStorage,绝不按页面加载 URL 写**——否则与首页自动跳转冲突(点了英文又被 URL 的 en 覆盖,首页永远跳不回去)。
## 目录约定(用户 2026-09-17 确认)
- **`src/components/views/` 必须保留,勿并入 `src/pages/`,也勿把内容提取摊平。** 原因:本项目 `prefixDefaultLocale: true` → `src/pages/{en,cn}/` 是两套 locale 页面树,每个页面文件只是薄壳(路由 + `export const prerender` + 引入共享视图 + 渲染);`views/*` 是 en/cn 两棵页面树**共用的页面体实现**(语言靠 `Astro.currentLocale` 运行时区分)。并进 pages 会迫使 en/cn 各抄一份,制造重复。
- `views/` 命名与 pages 略撞语义,但目录本身职责明确(跨 locale 共享页面体单一事实源),仅属 cosmetic,非必要不改名。
- 现状 `views/` 成员:Account / Home / Login / RunwayLooks / StreetSnaps / RunwayLooksDetail / StreetSnapsDetail(`RunwayLooksDetail`/`StreetSnapsDetail` 非独立路由,是被 `pages/{en,cn}/{runway-looks,street-snaps}/[id].astro` 复用的详情体;2026-09-17 由 ItemPage 按 `type` 拆成两个,共享脚本抽到 `lib/detailFav.ts` 的 `initDetailFav()`)。
## 图片去重(backend_v2,2026-09-17 落地)
- **三档全上**:Tier1 精确(sha1 内容寻址 + `content_sha1` 部分唯一索引,命中整行跳过不插);Tier2 近重复(`phash` 存 `vector(64)` 二进制串,`bit_hamming_ops` HNSW,`<~> <= 10` 命中标 `IsDuplicate`/`DupOf`,只标不拦);Tier3 语义(`image_embeddings` 表 `embedding vector(512)` + `vector_cosine_ops` HNSW,待 CLIP/DINOv2 接入,当前不写)。
- 关键文件:`internal/pkg/phash/phash.go`(dHash 纯标准库,`ToVectorBits`→`vector(64)` 串,webp 解码失败→0→NULL)、`internal/database/postgres.go`(`ensureDedupSchema` 幂等 DDL + `CREATE EXTENSION IF NOT EXISTS vector`)、`internal/service/ingest_service.go`(`dedupImage`)、`internal/repository/ingest_repository.go`(`ImageExistsBySha1`/`FindNearDuplicateImage`)。
- `phash` 走 `sql.NullString` + `type:vector(64)` text 扫描,规避 pgx 原生类型坑;空串→NULL 不参与近邻检索。
- **索引查取代全表扫**(用户"图片量会很大"痛点):原 `ListImagePHashes` 全表扫 O(N) 已移除。
- 待办:pgvector Docker 实连烟测 GORM 读 `vector(64)` 进 `sql.NullString`;汉明阈值 10 可按样本微调。