$type, 'type' => $type, 'variant' => $variant, 'visible' => $visible, 'props' => $props, ]; }; $row = static function ( string $code, string $name, string $page, array $sections, string $cardScheme = 'clay-edge', string $density = 'regular', string $frame = 'none', string $skin = 'shop', string $family = '', ): array { return [ 'code' => $code, 'name' => $name, 'page' => $page, 'card_scheme' => $cardScheme, 'density' => $density, 'frame' => $frame, 'skin' => $skin, 'family' => $family, 'sections' => $sections, ]; }; $home = [ $row('home-01-classic', '经典轮播宫格', 'home', [ $sec('search', 'bar'), $sec('hero', 'carousel', true, ['height' => 480]), $sec('category', 'grid', true, ['cols' => 3]), $sec('product', 'grid', false), ], 'clay-edge', 'regular', 'none', 'shop', '店面'), $row('home-02-banner-pills', '横幅胶囊', 'home', [ $sec('search', 'pill'), $sec('hero', 'banner', true, ['height' => 280]), $sec('category', 'pills'), $sec('product', 'grid', false), ], 'pearl-line', 'compact', 'none', 'shop', '店面'), $row('home-03-split-card', '对开卡片', 'home', [ $sec('search', 'bar'), $sec('hero', 'split', true, ['height' => 420]), $sec('category', 'card', true, ['cols' => 2]), $sec('product', 'grid', false), ], 'walnut-frame', 'regular', 'inset', 'shop', '店面'), $row('home-04-full-scroll', '全屏横滑', 'home', [ $sec('search', 'bar'), $sec('hero', 'fullscreen', true, ['height' => 640]), $sec('category', 'scroll'), $sec('product', 'waterfall', false), ], 'champagne-foil', 'airy', 'none', 'shop', '店面'), $row('home-05-stack-grid', '堆叠宫格', 'home', [ $sec('search', 'bar'), $sec('hero', 'stack', true, ['height' => 520]), $sec('category', 'grid', true, ['cols' => 3]), $sec('product', 'grid', false), ], 'double-frame', 'regular', 'none', 'shop', '店面'), $row('home-06-coverflow-tile', '封面流瓷砖', 'home', [ $sec('search', 'float'), $sec('hero', 'coverflow', true, ['height' => 480]), $sec('category', 'tile'), $sec('product', 'grid', false), ], 'gold-corner', 'regular', 'inset', 'shop', '店面'), $row('home-07-fade-mosaic', '叠化马赛克', 'home', [ $sec('search', 'bar'), $sec('hero', 'fade', true, ['height' => 500]), $sec('category', 'mosaic'), $sec('product', 'grid', false), ], 'museum-mat', 'airy', 'none', 'shop', '店面'), $row('home-08-peek-featured', '露边首图', 'home', [ $sec('search', 'pill'), $sec('hero', 'peek', true, ['height' => 460]), $sec('category', 'featured'), $sec('product', 'list', false), ], 'cap-rail', 'regular', 'none', 'shop', '店面'), $row('home-09-cube-sidebar', '立方侧栏', 'home', [ $sec('search', 'bar'), $sec('hero', 'cube', true, ['height' => 440]), $sec('category', 'sidebar'), $sec('product', 'grid', false), ], 'l-bracket', 'compact', 'inset', 'shop', '店面'), $row('home-10-caption-grid', '刊名条宫格', 'home', [ $sec('search', 'bar'), $sec('hero', 'caption', true, ['height' => 520]), $sec('category', 'grid', true, ['cols' => 4]), $sec('product', 'grid', false), ], 'thin-rule', 'regular', 'ornament', 'shop', '店面'), $row('home-11-carousel-card', '轮播大卡', 'home', [ $sec('search', 'bar'), $sec('hero', 'carousel', true, ['height' => 400]), $sec('category', 'card', true, ['cols' => 2]), $sec('product', 'waterfall', false), ], 'inset-slot', 'regular', 'none', 'shop', '店面'), $row('home-12-banner-tile', '横幅瓷砖', 'home', [ $sec('search', 'float'), $sec('hero', 'banner', true, ['height' => 240]), $sec('category', 'tile'), $sec('product', 'grid', false), ], 'pearl-bead', 'compact', 'none', 'shop', '店面'), $row('home-13-split-scroll', '对开横滑', 'home', [ $sec('search', 'pill'), $sec('hero', 'split', true, ['height' => 400]), $sec('category', 'scroll'), $sec('product', 'grid', false), ], 'gutter-fold', 'regular', 'none', 'shop', '店面'), $row('home-14-full-pills', '全屏胶囊', 'home', [ $sec('search', 'overlay'), $sec('hero', 'fullscreen', true, ['height' => 680]), $sec('category', 'pills'), $sec('product', 'grid', false), ], 'vignette', 'airy', 'none', 'shop', '店面'), $row('home-15-stack-mosaic', '堆叠马赛克', 'home', [ $sec('search', 'bar'), $sec('hero', 'stack', true, ['height' => 500]), $sec('category', 'mosaic'), $sec('product', 'grid', false), ], 'arch-mat', 'regular', 'inset', 'shop', '店面'), $row('home-16-coverflow-sidebar', '封面流侧栏', 'home', [ $sec('search', 'bar'), $sec('hero', 'coverflow', true, ['height' => 460]), $sec('category', 'sidebar'), $sec('product', 'list', false), ], 'circle-window', 'compact', 'none', 'shop', '店面'), $row('home-17-fade-card', '叠化卡片', 'home', [ $sec('search', 'bar'), $sec('hero', 'fade', true, ['height' => 480]), $sec('category', 'card', true, ['cols' => 2]), $sec('product', 'grid', false), ], 'emboss-plate', 'airy', 'ornament', 'shop', '店面'), $row('home-18-peek-grid', '露边宫格', 'home', [ $sec('search', 'pill'), $sec('hero', 'peek', true, ['height' => 440]), $sec('category', 'grid', true, ['cols' => 3]), $sec('product', 'grid', false), ], 'vert-caption', 'regular', 'none', 'shop', '店面'), $row('home-19-cube-featured', '立方首图', 'home', [ $sec('search', 'bar'), $sec('hero', 'cube', true, ['height' => 460]), $sec('category', 'featured'), $sec('product', 'waterfall', false), ], 'ribbon-bow', 'regular', 'inset', 'shop', '店面'), $row('home-20-caption-scroll', '刊名横滑', 'home', [ $sec('search', 'float'), $sec('hero', 'caption', true, ['height' => 500]), $sec('category', 'scroll'), $sec('product', 'grid', false), ], 'folio-line', 'airy', 'none', 'shop', '店面'), $row('home-21-carousel-mosaic', '轮播马赛克', 'home', [ $sec('search', 'bar'), $sec('hero', 'carousel', true, ['height' => 460]), $sec('category', 'mosaic'), $sec('product', 'grid', false), ], 'washi-tape', 'regular', 'none', 'shop', '店面'), $row('home-22-banner-sidebar', '横幅侧栏', 'home', [ $sec('search', 'bar'), $sec('hero', 'banner', true, ['height' => 260]), $sec('category', 'sidebar'), $sec('product', 'list', false), ], 'botanical', 'compact', 'inset', 'shop', '店面'), $row('home-23-split-pills', '对开胶囊', 'home', [ $sec('search', 'pill'), $sec('hero', 'split', true, ['height' => 400]), $sec('category', 'pills'), $sec('product', 'grid', false), ], 'handwriting', 'regular', 'none', 'shop', '店面'), $row('home-24-stack-tile', '堆叠瓷砖', 'home', [ $sec('search', 'bar'), $sec('hero', 'stack', true, ['height' => 500]), $sec('category', 'tile'), $sec('product', 'grid', false), ], 'torn-edge', 'regular', 'none', 'shop', '店面'), $row('home-25-peek-card', '露边大卡', 'home', [ $sec('search', 'overlay'), $sec('hero', 'peek', true, ['height' => 480]), $sec('category', 'card', true, ['cols' => 2]), $sec('product', 'grid', false), ], 'polaroid', 'airy', 'ornament', 'shop', '店面'), $row('home-26-cube-grid', '立方宫格', 'home', [ $sec('search', 'bar'), $sec('hero', 'cube', true, ['height' => 440]), $sec('category', 'grid', true, ['cols' => 3]), $sec('product', 'grid', false), ], 'stacked-offset', 'regular', 'none', 'shop', '店面'), $row('home-magazine-folio', '刊页封面目录', 'home', [ $sec('search', 'overlay'), $sec('hero', 'caption', true, ['height' => 640]), $sec('category', 'contents'), $sec('product', 'grid', false), ], 'folio-number', 'airy', 'ornament', 'magazine', '刊页'), $row('home-magazine-spread', '刊页对开目录', 'home', [ $sec('search', 'overlay'), $sec('hero', 'split', true, ['height' => 560]), $sec('category', 'contents'), $sec('product', 'grid', false), ], 'folio-line', 'airy', 'ornament', 'magazine', '刊页'), $row('home-magazine-fade', '刊页叠化目录', 'home', [ $sec('search', 'overlay'), $sec('hero', 'fade', true, ['height' => 620]), $sec('category', 'contents'), $sec('product', 'grid', false), ], 'vignette', 'airy', 'ornament', 'magazine', '刊页'), $row('home-magazine-film', '刊页胶片目录', 'home', [ $sec('search', 'overlay'), $sec('hero', 'peek', true, ['height' => 520]), $sec('category', 'contents'), $sec('product', 'grid', false), ], 'film-sprocket', 'airy', 'ornament', 'magazine', '刊页'), ]; $schemes = [ 'clay-edge', 'pearl-line', 'walnut-frame', 'champagne-foil', 'museum-mat', 'double-frame', 'arch-mat', 'circle-window', 'polaroid', 'film-sprocket', ]; /** 图册:10 列表 × 3 顶栏,两套之间至少差列表+顶栏 */ $catalogPairs = []; foreach (['waterfall', 'grid', 'list', 'masonry', 'featured', 'shelf', 'compact', 'airy', 'mosaic', 'duo'] as $list) { foreach (['chip', 'bar', 'sidebar'] as $filter) { $catalogPairs[] = [$list, $filter]; } } $catalogNames = [ '瀑布·分类条', '瀑布·仅搜索', '瀑布·侧栏', '双列·分类条', '双列·仅搜索', '双列·侧栏', '单列·分类条', '单列·仅搜索', '单列·侧栏', '砌石·分类条', '砌石·仅搜索', '砌石·侧栏', '首图·分类条', '首图·仅搜索', '首图·侧栏', '货架·分类条', '货架·仅搜索', '货架·侧栏', '紧凑·分类条', '紧凑·仅搜索', '紧凑·侧栏', '疏朗·分类条', '疏朗·仅搜索', '疏朗·侧栏', '马赛克·分类条', '马赛克·仅搜索', '马赛克·侧栏', '对开·分类条', '对开·仅搜索', '对开·侧栏', ]; $catalog = []; foreach ($catalogPairs as $i => [$list, $filter]) { $n = str_pad((string) ($i + 1), 2, '0', STR_PAD_LEFT); $catalog[] = $row( 'catalog-' . $n . '-' . $list, $catalogNames[$i], 'catalog', [$sec('filter', $filter), $sec('list', $list, true, ['card_scheme' => $schemes[$i % 10]])], $schemes[$i % 10], 'regular', 'none', 'shop', '图册', ); } /** 搜索:10 列表 × 3 搜索条 */ $searchPairs = []; foreach (['waterfall', 'grid', 'list', 'masonry', 'featured', 'shelf', 'compact', 'airy', 'mosaic', 'duo'] as $list) { foreach (['bar', 'pill', 'float'] as $searchVar) { $searchPairs[] = [$list, $searchVar]; } } $searchNames = [ '瀑布·搜索条', '瀑布·胶囊', '瀑布·悬浮', '双列·搜索条', '双列·胶囊', '双列·悬浮', '单列·搜索条', '单列·胶囊', '单列·悬浮', '砌石·搜索条', '砌石·胶囊', '砌石·悬浮', '首图·搜索条', '首图·胶囊', '首图·悬浮', '货架·搜索条', '货架·胶囊', '货架·悬浮', '紧凑·搜索条', '紧凑·胶囊', '紧凑·悬浮', '疏朗·搜索条', '疏朗·胶囊', '疏朗·悬浮', '马赛克·搜索条', '马赛克·胶囊', '马赛克·悬浮', '对开·搜索条', '对开·胶囊', '对开·悬浮', ]; $search = []; foreach ($searchPairs as $i => [$list, $searchVar]) { $n = str_pad((string) ($i + 1), 2, '0', STR_PAD_LEFT); $search[] = $row( 'search-' . $n . '-' . $list, $searchNames[$i], 'search', [$sec('search', $searchVar), $sec('list', $list, true, ['card_scheme' => $schemes[$i % 10]])], $schemes[$i % 10], 'regular', 'none', 'shop', '搜索', ); } /** 详情:30 套互异交叉,spec 与 action 不再锁死同一余数 */ $productCombos = [ ['swiper', 'plain', 'plain', 'inline', 'fixed', '轮播·表·底栏'], ['swiper', 'editorial', 'table', 'card', 'inline', '轮播·编辑表·跟文'], ['stack', 'plain', 'chips', 'inline', 'split', '叠图·芯片·拆开'], ['stack', 'split', 'cards', 'card', 'fixed', '叠图·分栏卡·底栏'], ['fullbleed', 'plain', 'table', 'sticky', 'fixed', '全出血·吸顶表'], ['fullbleed', 'overlay', 'plain', 'sticky', 'split', '全出血·压字·拆开'], ['peek', 'editorial', 'chips', 'inline', 'inline', '露边·编辑芯片'], ['peek', 'split', 'cards', 'card', 'fixed', '露边·分栏卡'], ['fade', 'plain', 'table', 'inline', 'split', '叠化·表·拆开'], ['fade', 'overlay', 'chips', 'sticky', 'fixed', '叠化·压字芯片'], ['coverflow', 'editorial', 'cards', 'card', 'inline', '封面流·编辑卡'], ['coverflow', 'split', 'plain', 'inline', 'fixed', '封面流·分栏表'], ['mosaic', 'plain', 'chips', 'card', 'split', '拼贴·芯片卡'], ['mosaic', 'editorial', 'table', 'sticky', 'inline', '拼贴·编辑吸顶'], ['filmstrip', 'overlay', 'cards', 'inline', 'fixed', '胶卷·压字卡'], ['filmstrip', 'split', 'plain', 'card', 'split', '胶卷·分栏拆开'], ['swiper', 'split', 'cards', 'sticky', 'inline', '轮播·分栏吸顶卡'], ['stack', 'overlay', 'table', 'sticky', 'inline', '叠图·压字吸顶'], ['fullbleed', 'editorial', 'chips', 'card', 'inline', '全出血·编辑芯片'], ['peek', 'plain', 'plain', 'card', 'split', '露边·报价卡拆开'], ['fade', 'editorial', 'cards', 'card', 'fixed', '叠化·编辑卡底栏'], ['coverflow', 'overlay', 'table', 'sticky', 'split', '封面流·压字吸顶'], ['mosaic', 'split', 'plain', 'sticky', 'fixed', '拼贴·分栏吸顶'], ['filmstrip', 'plain', 'table', 'sticky', 'inline', '胶卷·吸顶表'], ['swiper', 'overlay', 'chips', 'inline', 'split', '轮播·压字芯片'], ['stack', 'editorial', 'plain', 'card', 'fixed', '叠图·编辑报价卡'], ['fullbleed', 'split', 'cards', 'inline', 'fixed', '全出血·分栏卡'], ['peek', 'overlay', 'table', 'sticky', 'inline', '露边·压字吸顶'], ['fade', 'split', 'plain', 'card', 'inline', '叠化·分栏报价卡'], ['coverflow', 'plain', 'chips', 'card', 'split', '封面流·芯片拆开'], ]; $product = []; foreach ($productCombos as $i => [$g, $info, $spec, $priceMode, $act, $name]) { $n = str_pad((string) ($i + 1), 2, '0', STR_PAD_LEFT); $product[] = $row( 'product-' . $n . '-' . $g, $name, 'product', [ $sec('gallery', $g), $sec('info', $info), $sec('spec', $spec), $sec('price', $priceMode), $sec('action', $act), ], $schemes[$i % 10], 'regular', 'none', $info === 'overlay' ? 'magazine' : 'shop', '详情', ); } /** 清单:6 形态各出现一次主结构,再用 5 组不同卡片方案拉开,避免同形态连号克隆 */ $cartModes = [ ['card', '卡片陈列'], ['table', '表格清单'], ['timeline', '时间线'], ['compact', '紧凑条'], ['ticket', '票根'], ['stacked', '层叠'], ]; $cart = []; for ($i = 0; $i < 30; $i++) { $n = str_pad((string) ($i + 1), 2, '0', STR_PAD_LEFT); [$mode, $label] = $cartModes[$i % 6]; $scheme = $schemes[intdiv($i, 6) % 10]; $cart[] = $row( 'cart-' . $n . '-' . $mode, $label . ' · ' . ['素胚', '珠贝', '胡桃', '香槟', '卡纸'][intdiv($i, 6) % 5], 'cart', [$sec('list', $mode)], $scheme, 'regular', 'none', 'shop', '清单', ); } /** 我的:5 头 × 5 菜单 = 25 互异,后 5 套刊页皮肤换菜单 */ $minePairs = []; foreach (['gradient', 'image', 'plain', 'split', 'editorial'] as $h) { foreach (['grid', 'list', 'card', 'tile', 'compact'] as $m) { $minePairs[] = [$h, $m, 'shop']; } } $minePairs[] = ['editorial', 'list', 'magazine']; $minePairs[] = ['plain', 'tile', 'magazine']; $minePairs[] = ['split', 'card', 'magazine']; $minePairs[] = ['image', 'compact', 'magazine']; $minePairs[] = ['gradient', 'grid', 'magazine']; $mineLabels = [ 'gradient' => '渐变', 'image' => '头图', 'plain' => '素底', 'split' => '分栏', 'editorial' => '编辑', ]; $menuLabels = [ 'grid' => '宫格', 'list' => '列表', 'card' => '卡片', 'tile' => '瓷砖', 'compact' => '紧凑', ]; $mine = []; foreach ($minePairs as $i => [$h, $m, $skin]) { $n = str_pad((string) ($i + 1), 2, '0', STR_PAD_LEFT); $mine[] = $row( 'mine-' . $n . '-' . $h, ($mineLabels[$h] ?? $h) . '·' . ($menuLabels[$m] ?? $m) . ($skin === 'magazine' ? '·刊页' : ''), 'mine', [$sec('header', $h), $sec('menu', $m)], $schemes[$i % 10], 'regular', $skin === 'magazine' ? 'ornament' : 'none', $skin, '我的', ); } /** 每页最前一条可选「默认」,详情钉在底部 */ array_unshift($home, $row('home-00-default', '默认', 'home', [ $sec('search', 'bar'), $sec('hero', 'carousel', true, ['height' => 480]), $sec('category', 'grid', true, ['cols' => 3]), $sec('product', 'grid', false), ], 'clay-edge', 'regular', 'none', 'shop', '默认')); array_unshift($catalog, $row('catalog-00-default', '默认', 'catalog', [ $sec('filter', 'chip'), $sec('list', 'waterfall', true, ['card_scheme' => 'clay-edge']), ], 'clay-edge', 'regular', 'none', 'shop', '默认')); array_unshift($search, $row('search-00-default', '默认', 'search', [ $sec('search', 'bar'), $sec('list', 'waterfall', true, ['card_scheme' => 'clay-edge']), ], 'clay-edge', 'regular', 'none', 'shop', '默认')); array_unshift($product, $row('product-00-default', '默认', 'product', [ $sec('gallery', 'swiper'), $sec('info', 'plain'), $sec('spec', 'plain'), $sec('price', 'inline'), $sec('action', 'fixed'), ], 'clay-edge', 'regular', 'none', 'shop', '默认')); array_unshift($cart, $row('cart-00-default', '默认', 'cart', [ $sec('list', 'card'), ], 'clay-edge', 'regular', 'none', 'shop', '默认')); array_unshift($mine, $row('mine-00-default', '默认', 'mine', [ $sec('header', 'gradient'), $sec('menu', 'list'), ], 'clay-edge', 'regular', 'none', 'shop', '默认')); // 旧首页预设没有套餐段,插在分类后面,避免初始化预设把热门套餐漏掉 foreach ($home as &$homeRow) { $sections = $homeRow['sections'] ?? []; $has = false; foreach ($sections as $section) { if (($section['type'] ?? '') === 'package') { $has = true; break; } } if ($has) { continue; } $next = []; foreach ($sections as $section) { $next[] = $section; if (($section['type'] ?? '') === 'category') { $next[] = $sec('package', 'card'); } } $homeRow['sections'] = $next; } unset($homeRow); $package = [ $row('package-00-default', '默认', 'package', [$sec('search', 'bar'), $sec('list', 'card')], 'clay-edge', 'regular', 'none', 'shop', '默认'), $row('package-01-card', '封面卡片', 'package', [$sec('search', 'bar'), $sec('list', 'card')], 'champagne-foil', 'regular', 'none', 'shop', '套餐'), $row('package-02-featured', '首图通栏', 'package', [$sec('search', 'bar'), $sec('list', 'featured')], 'walnut-frame', 'regular', 'inset', 'shop', '套餐'), $row('package-03-magazine', '刊名目录', 'package', [$sec('search', 'pill'), $sec('list', 'magazine')], 'thin-rule', 'airy', 'ornament', 'magazine', '套餐'), $row('package-04-list', '单列图文', 'package', [$sec('search', 'bar'), $sec('list', 'list')], 'pearl-line', 'compact', 'none', 'shop', '套餐'), ]; return [ 'home' => $home, 'catalog' => $catalog, 'search' => $search, 'product' => $product, 'cart' => $cart, 'mine' => $mine, 'package' => $package, ];