From c50e3367926fd43eaa4b472538f02f467c2ea6cc Mon Sep 17 00:00:00 2001 From: zizi Date: Tue, 16 Jun 2026 10:24:13 +0000 Subject: [PATCH] =?UTF-8?q?feat(studio):=20feed=20=E5=8D=96=E7=9B=B8?= =?UTF-8?q?=E6=89=93=E7=A3=A8=E2=80=94=E2=80=94=E4=BA=92=E5=8A=A8=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E7=8E=BB=E7=92=83=E8=B4=A8=E6=84=9F=20+=20=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E5=B0=81=E9=9D=A2"=E6=97=A0=E5=9B=BE=E4=B9=9F?= =?UTF-8?q?=E5=A5=BD=E7=9C=8B"(=E8=AF=84=E5=AE=A1=20V-1/V-2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - V-1 互动按钮(InteractBar):深蓝实底 rgba(16,21,34,.6)→半透白 rgba(255,255,255,.10)+backdrop-filter blur(8px)+box-shadow,抖音式悬浮玻璃;图标/计数/点赞态行为不变 - V-2 卡片封面(GameCard+新增 utils/coverGradient.ts):纯确定性 FNV-1a hash→5套渐变主题(青绿/森系/青紫/暖/冷)+3套装饰,无封面卡按 title 分化渐变+柔光点+波形(无图也好看);真实封面优先逻辑不变 - verify:vue-tsc 类型门逮修一处真类型问题(computed 早返回{});build双绿;真机 :4173 CDP 实算样式(bg rgba(255,255,255,.1)/blur8)+截图(9卡按title渐变各异)双证 Co-Authored-By: Claude Opus 4.8 (1M context) --- game-studio/src/components/GameCard.vue | 80 +++++++++++++- game-studio/src/components/InteractBar.vue | 12 ++- game-studio/src/utils/coverGradient.ts | 120 +++++++++++++++++++++ 3 files changed, 205 insertions(+), 7 deletions(-) create mode 100644 game-studio/src/utils/coverGradient.ts diff --git a/game-studio/src/components/GameCard.vue b/game-studio/src/components/GameCard.vue index 83d71b92..3b7ab0e1 100644 --- a/game-studio/src/components/GameCard.vue +++ b/game-studio/src/components/GameCard.vue @@ -7,6 +7,7 @@ */ import { computed } from 'vue' import type { FeedCard } from '../api/types' +import { resolveCoverStyle } from '../utils/coverGradient' const props = defineProps<{ /** 游戏流卡片数据(严格贴契约 FeedCard) */ @@ -33,6 +34,26 @@ const hasCover = computed(() => { const url = props.card.coverUrl return !!url && !PLACEHOLDER_COVER_RE.test(url) }) + +/** + * 无封面时的确定性渐变兜底样式(spec §3.3 V-2):按 title(兜底 gameId)算稳定 hash, + * 取 ≥3 套青绿/青紫/暖色系渐变 + 柔光点 + 波形装饰之一,让无图卡也有辨识度、不千篇一律。 + * 仅在 !hasCover 时计算并下发到 CSS 变量(有真封面时为 null,不渲染兜底装饰)。 + */ +const coverFallback = computed(() => (hasCover.value ? null : resolveCoverStyle(props.card))) +/** 兜底底纹的内联 CSS 变量(渐变/柔光色/波形色/柔光落位);有真封面时返回空对象。 */ +const fallbackVars = computed>(() => { + const f = coverFallback.value + const vars: Record = {} + if (!f) return vars + vars['--cover-grad'] = f.theme.gradient + vars['--cover-glow'] = f.theme.glow + vars['--cover-wave'] = f.theme.wave + vars['--cover-glow-top'] = f.decor.glowTop + vars['--cover-glow-right'] = f.decor.glowRight + // 波形相位不走 CSS 变量,改用模板上的 --wave{N} 类切换 clip-path(见 template :class) + return vars +})