12 KiB
12 KiB
2026-08-24 工作日志
品牌弹窗「热门推荐」做成独立 HOT 字母 tab(19:52)
- 用户要求:把品牌弹窗里的「热门推荐」单独做成一个 letter(字母条里的独立 tab),并且打开弹窗默认就选中这个热门字母。
- 范围:仅品牌筛选弹窗的 A-Z 字母条(
showsmodal-az),存在于src/pages/cn/shows.astro与src/components/RunwayLooks.astro(en /en/runway-looks/)。en /shows/ 没这个弹窗(只有侧边栏),未动。 - 改动(两文件一致):
- 字母条最前插入
<button class="az az-hot" @click="modalPickLetter('HOT')">HOT</button>;原 A-Z 不变。 modalPickLetter(l)顶部加if (l === "HOT") { this.modalKeyword=""; await this.modalLoadHot(); return }。modalLoadHot()开头设this.modalLetter = "HOT"(让 HOT 按钮active高亮 + 提示「热门推荐」显示)。openBrandModal()把this.modalLetter = ""改成= "HOT",打开即默认选中热门。- 提示文案
x-show="!modalKeyword && !modalLetter"改为&& modalLetter === 'HOT'(只在 HOT 态显示「热门推荐」)。 - CSS 新增
.showsmodal-az .az-hot { w-auto px-2 font-sans font-bold tracking-[0.12em] text-[9px] }(HOT 是 3 字母,宽于 24px 方块)。
- 字母条最前插入
- 验证:
npm run buildBUILD_EXIT=0;两文件 read_lints 0;dist 的 cn/shows 与 en/runway-looksindex.html均含az-hot+modalPickLetter('HOT')各 1 处;python -m http.server 8088托管 dist/client 预览两页弹窗。 - ⚠️ 假数据 id(
hot-chanel等)仍非真实 hashid,勾选假热门去筛仍返回空,等真实 SSG/api/ssg/brands/popular接通即生效。
删除侧边栏 "Search designer" 搜索框(17:06)
- 用户要求去掉 DESIGNERS 侧边栏的 "Search designer…" 搜索框及相关的 JS。
- 范围:仅侧边栏那个输入框(用
keywordstate 驱动)。品牌弹窗里的"搜索品牌名…"(modalKeyword/modalSearch)是另一套,保留不动。 - 三文件统一改(
src/pages/shows.astroen、src/pages/cn/shows.astro、src/components/RunwayLooks.astro):- 删
<input class="showssearch" ... x-model.debounce.150ms="keyword" />。 - 删
keyword: ""state。 visibleBrandItemsgetter 去掉if (kw) {...} else {...}的 keyword 分支,简化为只走字母分组展示(else 分支)。- reset(
clearAll/resetFilter之类)里删this.keyword = ""。 shows.astro额外把x-show="hasMoreBrands && !keyword"改回x-show="hasMoreBrands"(Show all 链接不再因搜索态隐藏)。- 删
.showssearch死 CSS(该类仅被上述输入框使用)。
- 删
- 验证:
npm run buildBUILD_EXIT=0;三文件read_lints0 错误;(?<![a-zA-Z])keyword(?![A-Za-z])全仓 0 残留(仅留modalKeyword);cn/shows 与 shows 产物Search designer/showssearch各 0 处。
品牌筛选「最多只能选一个」修复
- 用户反馈品牌筛选只能单选。排查发现:仓库里品牌筛选逻辑本就是多选(
selectedBrands数组 +toggleBrand增删),但 DESIGNERS 侧边栏<ul class="showschecks">漏了x-for="item in visibleBrandItems",导致品牌勾选框一行都不渲染——侧边栏品牌列表完全失效,用户只能走弹窗。 - cn 版
src/pages/cn/shows.astro弹窗还硬卡了「最多 5 个」(modalMaxReached+:disabled+toggleModalBrand内>=5 return+ 底部「已选 X / 最多 5 个」)。 - 改动:
src/pages/cn/shows.astro与src/pages/shows.astro(en):补回<ul>上的x-for="item in visibleBrandItems" :key="item.key",让 DESIGNERS 多选列表正常渲染(按字母分组 + checkbox +toggleBrand多选)。- cn 版额外:删除
modalMaxReached计算属性、toggleModalBrand的 5 上限 guard、@change上的:disabled、底部文案改「已选 X 个品牌」——弹窗改为无上限纯多选。
- en 版
shows.astro没有品牌弹窗(只用侧边栏列表 + "Show all N designers" 展开),补 x-for 后即恢复正常多选。 - 验证:
npm run buildBUILD_EXIT=0;产物 HTML 含visibleBrandItems(cn/en 各 1)、modalMaxReached残留 0、最多 5 个残留 0。 - 注意:去掉 5 上限后,若用户勾选大量品牌(如 50+),
getArticles({ brand_ids: [...] })会带长数组请求后端;后端若用IN (...)应无碍,但极端多选需关注接口性能(用户暂未提,先不限制)。
品牌筛选「改成单选」纠正(en 版)
- 纠正:上一笔把品牌筛选做成"多选"是理解反了。用户原话"最多只能选一个"的真实意图是要单选(最多 1 个),且只改 en 版(
src/pages/shows.astro)。 - 改动(仅 en):
toggleBrand(id)由增删数组改为「已选则清空、否则替换为单元素数组」this.selectedBrands = [id]/= []。selectedBrands仍为数组(接口 / pills /:checked绑定都依赖数组形态),只是长度恒 ≤ 1,checkbox 视觉上等同 radio。 - cn 版保持多选(用户说"你就改en的就行"),即 cn/shows.astro 仍是补回 x-for + 去 5 上限的多选状态。⚠️ 现状 en 单选 / cn 多选,两端行为不一致,是用户明确要求的。
- 验证:
npm run buildBUILD_EXIT=0;read_lints0 错误;预览http://localhost:8090/shows/。
品牌筛选「cn 也改单选」纠正(14:36)
- 用户又提"现在品牌的筛选不是最多 5 个吗,我希望最多只能选一个"。说明他认知里 cn 仍是旧"最多 5 个"弹窗(实际上一条我已把 cn 改成无上限多选)。最终意图 = 品牌筛选全局单选(max 1)。
- 这次把 cn 版也改成单选:
src/pages/cn/shows.astro的toggleBrand(侧边栏)+toggleModalBrand(弹窗)都由增删数组改为「已选则清空、否则置单元素数组」;弹窗底部计数文案由「已选 X 个品牌」改为「已选 X / 1 个品牌」明示上限。 - 现状:en + cn 均已单选(max 1),两端一致。en 在上一笔已完成,cn 本笔补齐。
- 验证:
npm run buildBUILD_EXIT=0;read_lints0 错误;预览http://localhost:8090/cn/shows/。
年份筛选改为前端写死(不再调后端 getYears)
- 用户要求年份/季节这类筛选"改成品牌那种的数据,直接写死就好了,因为不会特别多"。
- 排查:Collection(selectedCt: rtw/menswear/couture/resort/pre_fall) 与 Season(selectedSeason: spring/fall) 本就是前端写死的静态
<li>checkbox;只有 Year 是动态的——frontmatter 调getYears(30)从后端拉年份、后端挂了才回落yearSeed=[2026..2021]。 - 改动(3 文件一致:
src/pages/shows.astroen、src/pages/cn/shows.astro、src/components/RunwayLooks.astro):- 删除
import { ... getYears ... }、删除let yearChips/yearSeed/getYearstry-catch 整段。 - frontmatter 新增
const yearOptions = [2026, 2025, 2024, 2023, 2022, 2021, 2020, 2019, 2018, 2017](写死,2026→2017 共 10 个)。 - 渲染
{yearChips.map}→{yearOptions.map},其余(checkbox / x-model=selectedYear / refreshFilter)不变,年份仍为多选。
- 删除
- 验证:
npm run buildBUILD_EXIT=0;getYears|yearChips全仓 0 残留;cn 产物含>2017</>2026</value="2026"。 - ⚠️ 取舍:写死后2005–2016 这批老秀场将无法按年份筛选(网格仍展示,只是筛不出)。当前
yearOptions是一行可编辑数组,要补老年份直接往里加即可。用户未提,先保持 10 年窗口。 - 现状:Collection/Season/Year 三套筛选均为前端写死静态数据;仅 DESIGNERS(品牌)仍由后端
getBrands()拉取(用户未要求改品牌来源)。
年份区间改为"当今年份往前 15 年 + X年前",Collection/Season 换写死示例数据
- 用户纠正:年份应为 2026 往前推 15 年 → 到 2011(之前误写成 2001),并加末项「2011年前」。
- 年份改为动态生成:
const currentYear = new Date().getFullYear(); const yearFloor = currentYear - 15;循环 pushyearFloor..currentYear,末项 push{value:'before'+yearFloor, label: yearFloor+'年前'}。SSR 构建时new Date()取构建年(现 2026),故产物固定 2026→2011 + 「2011年前」共 17 项,selectedYear为 string[](含"before2011"哨兵)。 - Collection / Season 改为写死示例(假)数据数组
collectionOptions/seasonOptions({value,label}),模板map渲染(与 Year 同套路)。Collection 现 8 项(rtw/menswear/womenswear/couture/resort/pre_fall/bridal/swimwear),Season 现 4 项(spring/fall/cruise/holiday)。ctLabel()的 map 在 shows.astro / cn/shows.astro 两处补了 womenswear/bridal/swimwear 标签(RunwayLooks 无 ctLabel)。 - 仍内联渲染(用户 earlier:「数量<10 不用弹窗」):Collection(8)/Season(4) 均 <10 内联;Year 虽 17 项但用户要求「都展示出来」故也内联。
- 验证:
npm run buildBUILD_EXIT=0;read_lints0;cn 产物含2011年前/value="2011"/value="2026"/Womenswear/Cruise/before2011。 - ⚠️ 假数据提醒:Collection 里 womenswear/bridal/swimwear、Season 里 cruise/holiday 是示例占位,后端
collection_type/season未必识别 → 勾这些可能筛不到结果。确认后直接改collectionOptions/seasonOptions数组即可(已加注释说明)。before2011同理需后端支持才能真正筛「2011 年前」,目前仅展示。
其他(同日)
- 上午修 RunwayLooks.astro / shows.astro / cn/shows.astro 三处
<script>块ROUTES/clientHrefts(2304):frontmatter 的 import 无法在客户端<script>作用域使用,需在各自脚本块内重新 import(见 MEMORY.md「Astro frontmatter 与 script 作用域隔离」)。
新增「热门品牌 / HOT」区(SSG 接口 + 假数据回落)
- 用户要求:选择品牌时加一个热门品牌区,进来最先展示热门品牌;数据走 SSG 接口获取,先写假数据看效果。
- 关键架构点:SSG 接口
getSsgPopularBrands()(src/lib/api.ts,调/api/ssg/brands/popular,用BASE_API_SSG8091 内部端口,仅 Node 构建期可用)不能在浏览器端调。所以改为 frontmatter 构建期调getSsgPopularBrands(12),映射成{id,name,article_count},拿不到就回落前端写死的FAKE_HOT_BRANDS(12 个时装屋:Chanel/Dior/Gucci/.../Bottega Veneta),烤进<script id="showshotbrands-data">JSON,Alpine 在alpine:init里getElementById读出hotBrands。 - 三文件改动一致(
src/pages/shows.astroen、src/pages/cn/shows.astro、src/components/RunwayLooks.astro):- import 加
getSsgPopularBrands;frontmatter 加FAKE_HOT_BRANDS常量 +hotBrands抓取/回落;markup 加showshotbrands-dataJSON 脚本(RunwayLooks 额外补了缺失的showsbrands-data脚本——它之前只靠运行时getBrands撑弹窗,allBrands实际为空)。 - Alpine:
alpine:init读hotBrands入组件;pills的 findName 兼容hotBrands(假 id 也能显示名)。 - 侧边栏 HOT 区:shows.astro / cn/shows.astro 的 DESIGNERS
showsg-b顶部插入「HOT · Popular / 热门品牌 · HOT」分组,渲染hotBrands为 chip(checkbox 绑toggleBrand/selectedBrands,含has-[:checked]选中高亮,纯 Tailwind 工具类,无需改<style>)。RunwayLooks 侧边栏品牌列表是注释掉的,故只改弹窗、不插图侧栏 HOT。 - 弹窗热门:
modalLoadHot()由「getBrands({featured:1})」改为「this.hotBrands映射成 modalResults」,进入弹窗即先展示热门("热门推荐" 标题原已存在);搜索/选字母时仍走getBrands拉全量。
- import 加
- 验证:
npm run buildBUILD_EXIT=0;三文件read_lints0;dist 三页(shows/cn/shows/en/runway-looks)均含showshotbrands-data+Chanel/Bottega Veneta。 - ⚠️ 假数据取舍:FAKE id 形如
hot-chanel,非真实 hashid → 勾选假热门品牌去筛选会返回空(后端不认)。等真实 SSG/api/ssg/brands/popular接通后,返回真实 hashid,筛选即生效。RunwayLooks 弹窗modalMaxReached返回>=1(且:disabled据此),实际等同单选——属既有状态,未动。