初始化

缺陷:主题配色需要优化整体的同风格
This commit is contained in:
2026-08-14 23:21:21 +08:00
parent 6e2769c528
commit bcf54c2727
152 changed files with 13521 additions and 141 deletions

View File

@@ -62,6 +62,28 @@ return [
]) : [],
],
// 业务表连接:与 mysql 指向同一个库仅前缀不同nl_ 系统表 / cc_ 业务表)
// 业务 Model 需覆盖 protected $connection = 'business';
'business' => [
'driver' => 'mysql',
'url' => env('DB_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'laravel'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => env('DB_CHARSET', 'utf8mb4'),
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
'prefix' => env('DB_BUSINESS_PREFIX', 'cc_'),
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'mariadb' => [
'driver' => 'mariadb',
'url' => env('DB_URL'),

123
config/lgp_menu.php Normal file
View File

@@ -0,0 +1,123 @@
<?php
/**
* LGP 业务菜单声明
*
* nl_menu 的行由 `lgp:menu-sync` name 幂等同步,不要手写 INSERT pid。
* 注意两个取反字段(见 AdminService::menu
* keep_alive 0=开启缓存 1=关闭缓存
* affix_tab 0=固定标签 1=不固定
* 目录节点 component 固定写 BasicLayout叶子节点写去掉 views .vue 的路径。
*/
return [
[
'title' => '商品中心',
'name' => 'Goods',
'path' => '/goods',
'component' => 'BasicLayout',
'icon' => 'lucide:sofa',
'sort' => 100,
'children' => [
['title' => '商品图册', 'name' => 'GoodsCatalogue', 'path' => '/goods/catalogue', 'component' => '/goods/catalogue/index', 'icon' => 'lucide:book-image', 'sort' => 0],
['title' => '商品分类', 'name' => 'GoodsCategory', 'path' => '/goods/category', 'component' => '/goods/category/index', 'icon' => 'lucide:folder-tree', 'sort' => 1],
['title' => '规格报价', 'name' => 'GoodsPriceSheet', 'path' => '/goods/price-sheet', 'component' => '/goods/price-sheet/index', 'icon' => 'lucide:ruler', 'sort' => 2],
['title' => '商品相册', 'name' => 'GoodsImage', 'path' => '/goods/image', 'component' => '/goods/image/index', 'icon' => 'lucide:images', 'sort' => 3],
['title' => '轮播图', 'name' => 'GoodsCarousel', 'path' => '/goods/carousel', 'component' => '/goods/carousel/index', 'icon' => 'lucide:gallery-horizontal', 'sort' => 4],
['title' => '报价单', 'name' => 'GoodsQuote', 'path' => '/goods/quote', 'component' => '/goods/quote/index', 'icon' => 'lucide:file-text', 'sort' => 5],
],
],
[
'title' => '工厂产品',
'name' => 'Factory',
'path' => '/factory',
'component' => 'BasicLayout',
'icon' => 'lucide:factory',
'sort' => 200,
'children' => [
['title' => '工厂管理', 'name' => 'FactoryInfo', 'path' => '/factory/info', 'component' => '/factory/info/index', 'icon' => 'lucide:building-2', 'sort' => 0],
['title' => '工厂分类', 'name' => 'FactoryClass', 'path' => '/factory/class', 'component' => '/factory/class/index', 'icon' => 'lucide:tags', 'sort' => 1],
['title' => '工厂产品图片', 'name' => 'FactoryImage', 'path' => '/factory/image', 'component' => '/factory/image/index', 'icon' => 'lucide:image-plus', 'sort' => 2],
],
],
[
'title' => '色卡管理',
'name' => 'Color',
'path' => '/color',
'component' => 'BasicLayout',
'icon' => 'lucide:palette',
'sort' => 300,
'children' => [
['title' => '公司管理', 'name' => 'ColorCompany', 'path' => '/color/company', 'component' => '/color/company/index', 'icon' => 'lucide:landmark', 'sort' => 0],
['title' => '色卡分类', 'name' => 'ColorCardClass', 'path' => '/color/card-class', 'component' => '/color/card-class/index', 'icon' => 'lucide:layers', 'sort' => 1],
['title' => '色卡列表', 'name' => 'ColorCard', 'path' => '/color/card', 'component' => '/color/card/index', 'icon' => 'lucide:swatch-book', 'sort' => 2],
],
],
[
'title' => '客户中心',
'name' => 'Customer',
'path' => '/customer',
'component' => 'BasicLayout',
'icon' => 'lucide:users',
'sort' => 400,
'children' => [
['title' => '微信用户', 'name' => 'CustomerWxUser', 'path' => '/customer/wx-user', 'component' => '/customer/wx-user/index', 'icon' => 'ic:baseline-wechat', 'sort' => 0],
['title' => '经销商管理', 'name' => 'CustomerDealer', 'path' => '/customer/dealer', 'component' => '/customer/dealer/index', 'icon' => 'lucide:handshake', 'sort' => 1],
['title' => '企业管理', 'name' => 'CustomerEnterprise', 'path' => '/customer/enterprise', 'component' => '/customer/enterprise/index', 'icon' => 'lucide:building', 'sort' => 2],
['title' => '清单管理', 'name' => 'CustomerList', 'path' => '/customer/list', 'component' => '/customer/list/index', 'icon' => 'lucide:clipboard-list', 'sort' => 3],
['title' => '订单管理', 'name' => 'CustomerOrder', 'path' => '/customer/order', 'component' => '/customer/order/index', 'icon' => 'lucide:receipt-text', 'sort' => 4],
],
],
[
'title' => '素材库',
'name' => 'Material',
'path' => '/material',
'component' => '/material/index',
'icon' => 'lucide:folder-open',
'sort' => 500,
],
[
'title' => '小程序',
'name' => 'Wx',
'path' => '/wx',
'component' => 'BasicLayout',
'icon' => 'lucide:smartphone',
'sort' => 600,
'children' => [
['title' => '装修模板', 'name' => 'WxTemplate', 'path' => '/wx/template', 'component' => '/wx/template/index', 'icon' => 'lucide:paintbrush', 'sort' => 0],
['title' => '应用配置', 'name' => 'WxApp', 'path' => '/wx/app', 'component' => '/wx/app/index', 'icon' => 'lucide:settings-2', 'sort' => 1],
],
],
[
'title' => '内容创作',
'name' => 'Media',
'path' => '/media',
'component' => 'BasicLayout',
'icon' => 'lucide:newspaper',
'sort' => 700,
'children' => [
['title' => '公众号账号', 'name' => 'MediaWechatAccount', 'path' => '/media/wechat-account', 'component' => '/media/wechat-account/index', 'icon' => 'ic:baseline-wechat', 'sort' => 0],
['title' => '图文创作', 'name' => 'MediaWechatArticle', 'path' => '/media/wechat-article', 'component' => '/media/wechat-article/index', 'icon' => 'lucide:file-pen-line', 'sort' => 1],
// 图文编辑器是 router.push 进去的详情页,不在菜单里展示,但仍要注册路由
['title' => '图文编辑器', 'name' => 'MediaWechatArticleEdit', 'path' => '/media/wechat-article/editor', 'component' => '/media/wechat-article/editor/index', 'hide_in_menu' => 1, 'sort' => 2],
],
],
[
// 开发工具:代码生成器(单页),挂在根目录下
'title' => '代码生成',
'name' => 'CodeGeneration',
'path' => '/code-generation',
'component' => '/code-generation/index',
'icon' => 'lucide:wand-sparkles',
'sort' => 800,
],
[
// 挂到脚手架自带的「基础管理」下parent 用 name 引用,避免依赖自增 id
'title' => '部门管理',
'name' => 'SystemDepartment',
'path' => '/system/department',
'component' => '/system/department/index',
'icon' => 'lucide:network',
'parent' => 'System',
'sort' => 4,
],
];

48
config/media_refs.php Normal file
View File

@@ -0,0 +1,48 @@
<?php
/*
* 媒体地址字段注册表
*
* 新增任何「存文件地址」的字段后必须登记到这里
*
* 素材库的引用扫描只会去这张表登记过的列里找地址。漏登一个字段,
* 那些正在被使用的文件就会被算成 ref_count = 0,出现在「可回收」列表里,
* 点一下回收就连远端对象一起删掉了 —— 页面上随即是一片裂图,且不可恢复。
* 宁可多登几列(多扫一遍只是慢一点),也不要漏登。
*
* connection config/database.php 里的连接名:业务表 businesscc_ 前缀)、系统表 mysqlnl_ 前缀)
* table 不带前缀的逻辑名,扫描时由 DB::connection($conn)->table($table) 自动补前缀
* field 列名;列还不存在时扫描会自动跳过,所以可以提前登记规划中的字段
* kind single 整个字段就是一个地址
* multi 逗号分隔的多个地址
* rich 富文本 / Markdown需要正则从 src、href、url() ![]() 里抽取
*/
return [
/*
* ---------------- LGP 业务表business 连接cc_ 前缀)----------------
*/
['connection' => 'business', 'table' => 'catalogue', 'field' => 'cover', 'kind' => 'single'],
['connection' => 'business', 'table' => 'catalogue', 'field' => 'pdf', 'kind' => 'single'],
// video 列在部分环境还没上线,扫描时按 hasColumn 跳过,不影响其余字段
['connection' => 'business', 'table' => 'catalogue', 'field' => 'video', 'kind' => 'single'],
['connection' => 'business', 'table' => 'image', 'field' => 'url', 'kind' => 'single'],
['connection' => 'business', 'table' => 'carousel', 'field' => 'url', 'kind' => 'single'],
['connection' => 'business', 'table' => 'category', 'field' => 'url', 'kind' => 'single'],
['connection' => 'business', 'table' => 'colorcard', 'field' => 'cover', 'kind' => 'single'],
['connection' => 'business', 'table' => 'factory_info', 'field' => 'cover', 'kind' => 'single'],
['connection' => 'business', 'table' => 'factory_image', 'field' => 'url', 'kind' => 'single'],
['connection' => 'business', 'table' => 'enterprise', 'field' => 'logo', 'kind' => 'single'],
// 微信头像多数是腾讯 CDN 地址,匹配不上任何素材;登记它是为了兜住
// 「后台替用户换成自己上传的头像」这种情况
['connection' => 'business', 'table' => 'wx_user', 'field' => 'avatar', 'kind' => 'single'],
/*
* ---------------- 系统表mysql 连接nl_ 前缀)----------------
*/
['connection' => 'mysql', 'table' => 'admin', 'field' => 'avatar', 'kind' => 'single'],
['connection' => 'mysql', 'table' => 'wechat_article', 'field' => 'cover_url', 'kind' => 'single'],
// 图文正文是 Markdown图片以 ![](url) 的形式散在全文里
['connection' => 'mysql', 'table' => 'wechat_article', 'field' => 'content_md', 'kind' => 'rich'],
// 版本流水存的是历史正文快照:回退到旧版本要能把图找回来,所以一并算引用
['connection' => 'mysql', 'table' => 'wechat_article_version', 'field' => 'content_md', 'kind' => 'rich'],
];

View File

@@ -23,6 +23,29 @@ return [
*/
'jwt' => [
'secret' => env('JWT_SECRET', 'nl_admin_jwt_secret_key_change_me_32b'),
// token 过期后仍允许续签的宽限期,超过就必须重新登录
'refresh_ttl' => (int) env('JWT_REFRESH_TTL', 7 * 24 * 3600),
],
/*
* 小程序端
*/
'wx' => [
// 小程序不像浏览器那样会主动续签token 有效期给长一点,作废靠后台停用账号
'token_ttl' => (int) env('WX_TOKEN_TTL', 30 * 24 * 3600),
// 单品牌部署兜底:请求头 X-App-Code 为空时用这个 code 查 nl_wx_app
// 双品牌共用进程时仍以表 + 请求头分流为主,这里只是「没带头的默认值」
'default_app_code' => env('WX_DEFAULT_APP_CODE', ''),
// 库表无数据时回落用的 AppID仅公开标识AppSecret 仍必须从库里加密读)
'env_app_id' => env('WX_APP_ID', ''),
// 与 env_app_id 配套的品牌展示名(仅用于日志/默认记录),无业务影响
'env_app_name' => env('WX_APP_NAME', ''),
],
/*
* 自助注册:后台管理端默认关闭,开着等于谁都能给自己开管理员账号
*/
'register' => [
'enabled' => (bool) env('REGISTER_ENABLED', false),
'default_role_id' => (int) env('REGISTER_DEFAULT_ROLE_ID', 2),
],
/*
* 库内敏感字段 AES 密钥(密文前缀 nl_ase_256_读取兼容历史 ***
@@ -44,6 +67,8 @@ return [
'phone' => 'nl_phone_',
'login_out_key' => 'nl_login_out_',
'menu_key' => 'nl_menu_',
// 角色权限码缓存前缀key = 前缀 + roleId
'permission_key' => 'nl_perm_',
// 公众号 stable access_token 缓存前缀key = 前缀 + appidTTL 随微信 expires_in
'wechat_token' => 'nl_wechat_at_',
],
@@ -51,10 +76,39 @@ return [
* api白名单
*/
'api' => [
/*
* 免鉴权路径(不含 /api/ 前缀,中间件规范化后比较)
* 这里是「连 token 都不要求」的接口,注册在 routes/api.php 的免登录组里
*/
'white_list' => [
'/api/admin/login',
'/api/admin/register',
]
'login',
'register',
'logout',
'refresh',
'sql/test-connection',
'sql/start-installation',
],
/*
* 接口级权限
* strict = true 未登记进 nl_api_endpoint 的接口一律拒绝(安全优先,上线前打开)
* strict = false 未登记的接口放行,只拦已登记但未授权的(迁移期默认)
*/
'permission' => [
'strict' => (bool) env('API_PERMISSION_STRICT', false),
// 登录后人人可调、不参与角色授权的接口
'always_allow' => [
'admin/codes',
'admin/menu',
'admin/my-info',
'admin/update-profile',
'admin/change-password',
'admin/login-log',
'admin/op-log',
'upload/image',
'upload/video',
'upload/file',
],
],
],
/*
* 阿里云oss配置

234
config/wx_templates.php Normal file
View File

@@ -0,0 +1,234 @@
<?php
/**
* 小程序装修模板预设20 套)
*
* 每套模板的差异不只是主色:字体族与字号梯度、圆角、阴影、动效时长与曲线、
* 以及首页/详情/清单/我的四个页面的排布都不一样。这里用紧凑的规格描述,
* WxTemplatePresetService 展开成完整令牌,避免 20 份手抄 JSON 互相抄错。
*
* scale/radius/shadow/motion 的取值见 WxTemplatePresetService 里的对应表。
* 首期精修「轻奢」系列(前 4 套),其余先占位可用,后续按期打磨。
*/
return [
[
'code' => 'lux-champagne',
'name' => '轻奢·香槟金',
'style_tag' => '轻奢',
'palette' => ['primary' => '#B08D57', 'accent' => '#8C6A3F', 'bg' => '#FAF7F2', 'surface' => '#FFFFFF', 'text' => '#1C1917', 'border' => '#E7DFD3'],
'scale' => 'serif-elegant',
'radius' => 'soft',
'shadow' => 'airy',
'motion' => 'silk',
'layout' => ['home' => ['hero' => 'fullscreen', 'category' => 'scroll', 'product' => 'magazine'], 'product' => ['gallery' => 'fullbleed', 'price' => 'sticky', 'action' => 'fixed'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'gradient', 'menu' => 'list'], 'effect' => ['transition' => 'fade', 'skeleton' => 'shimmer']],
],
[
'code' => 'lux-ink',
'name' => '轻奢·墨玉',
'style_tag' => '轻奢',
'palette' => ['primary' => '#C9A063', 'accent' => '#E8D5AE', 'bg' => '#14110F', 'surface' => '#1F1B18', 'text' => '#F5F0E8', 'border' => '#332C25'],
'scale' => 'serif-elegant',
'radius' => 'soft',
'shadow' => 'deep',
'motion' => 'silk',
'layout' => ['home' => ['hero' => 'fullscreen', 'category' => 'sidebar', 'product' => 'grid'], 'product' => ['gallery' => 'stack', 'price' => 'card', 'action' => 'fixed'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'image', 'menu' => 'list'], 'effect' => ['transition' => 'fade', 'skeleton' => 'shimmer']],
],
[
'code' => 'lux-pearl',
'name' => '轻奢·珠贝白',
'style_tag' => '轻奢',
'palette' => ['primary' => '#9C8E7E', 'accent' => '#CBBFA8', 'bg' => '#FFFFFF', 'surface' => '#F7F5F1', 'text' => '#2B2724', 'border' => '#EAE5DC'],
'scale' => 'sans-refined',
'radius' => 'sharp',
'shadow' => 'airy',
'motion' => 'silk',
'layout' => ['home' => ['hero' => 'split', 'category' => 'grid', 'product' => 'waterfall'], 'product' => ['gallery' => 'swiper', 'price' => 'inline', 'action' => 'inline'], 'list' => ['style' => 'table'], 'mine' => ['header' => 'plain', 'menu' => 'grid'], 'effect' => ['transition' => 'slide', 'skeleton' => 'shimmer']],
],
[
'code' => 'lux-walnut',
'name' => '轻奢·胡桃木',
'style_tag' => '轻奢',
'palette' => ['primary' => '#6F4E37', 'accent' => '#A9784F', 'bg' => '#F6F1EA', 'surface' => '#FFFDFA', 'text' => '#241B14', 'border' => '#E2D6C7'],
'scale' => 'serif-elegant',
'radius' => 'round',
'shadow' => 'soft',
'motion' => 'gentle',
'layout' => ['home' => ['hero' => 'carousel', 'category' => 'card', 'product' => 'magazine'], 'product' => ['gallery' => 'fullbleed', 'price' => 'card', 'action' => 'fixed'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'gradient', 'menu' => 'list'], 'effect' => ['transition' => 'fade', 'skeleton' => 'pulse']],
],
[
'code' => 'minimal-linen',
'name' => '极简·亚麻',
'style_tag' => '极简',
'palette' => ['primary' => '#3F3F46', 'accent' => '#A1A1AA', 'bg' => '#FAFAF9', 'surface' => '#FFFFFF', 'text' => '#18181B', 'border' => '#E4E4E7'],
'scale' => 'sans-compact',
'radius' => 'sharp',
'shadow' => 'flat',
'motion' => 'snappy',
'layout' => ['home' => ['hero' => 'banner', 'category' => 'grid', 'product' => 'grid'], 'product' => ['gallery' => 'swiper', 'price' => 'inline', 'action' => 'inline'], 'list' => ['style' => 'table'], 'mine' => ['header' => 'plain', 'menu' => 'list'], 'effect' => ['transition' => 'none', 'skeleton' => 'pulse']],
],
[
'code' => 'minimal-mono',
'name' => '极简·黑白',
'style_tag' => '极简',
'palette' => ['primary' => '#000000', 'accent' => '#525252', 'bg' => '#FFFFFF', 'surface' => '#F5F5F5', 'text' => '#0A0A0A', 'border' => '#D4D4D4'],
'scale' => 'sans-wide',
'radius' => 'none',
'shadow' => 'flat',
'motion' => 'snappy',
'layout' => ['home' => ['hero' => 'split', 'category' => 'scroll', 'product' => 'list'], 'product' => ['gallery' => 'stack', 'price' => 'inline', 'action' => 'inline'], 'list' => ['style' => 'table'], 'mine' => ['header' => 'plain', 'menu' => 'list'], 'effect' => ['transition' => 'slide', 'skeleton' => 'none']],
],
[
'code' => 'modern-indigo',
'name' => '现代·靛蓝',
'style_tag' => '现代',
'palette' => ['primary' => '#4F46E5', 'accent' => '#818CF8', 'bg' => '#F8FAFC', 'surface' => '#FFFFFF', 'text' => '#0F172A', 'border' => '#E2E8F0'],
'scale' => 'sans-refined',
'radius' => 'round',
'shadow' => 'soft',
'motion' => 'bouncy',
'layout' => ['home' => ['hero' => 'carousel', 'category' => 'card', 'product' => 'waterfall'], 'product' => ['gallery' => 'swiper', 'price' => 'card', 'action' => 'fixed'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'gradient', 'menu' => 'grid'], 'effect' => ['transition' => 'zoom', 'skeleton' => 'shimmer']],
],
[
'code' => 'modern-teal',
'name' => '现代·青瓷',
'style_tag' => '现代',
'palette' => ['primary' => '#0D9488', 'accent' => '#5EEAD4', 'bg' => '#F0FDFA', 'surface' => '#FFFFFF', 'text' => '#134E4A', 'border' => '#CCFBF1'],
'scale' => 'sans-refined',
'radius' => 'round',
'shadow' => 'soft',
'motion' => 'gentle',
'layout' => ['home' => ['hero' => 'banner', 'category' => 'grid', 'product' => 'grid'], 'product' => ['gallery' => 'swiper', 'price' => 'inline', 'action' => 'fixed'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'gradient', 'menu' => 'grid'], 'effect' => ['transition' => 'fade', 'skeleton' => 'shimmer']],
],
[
'code' => 'warm-terracotta',
'name' => '暖调·陶土',
'style_tag' => '暖调',
'palette' => ['primary' => '#C05621', 'accent' => '#F6AD55', 'bg' => '#FFFAF0', 'surface' => '#FFFFFF', 'text' => '#2D2016', 'border' => '#FBD9B5'],
'scale' => 'sans-compact',
'radius' => 'round',
'shadow' => 'soft',
'motion' => 'bouncy',
'layout' => ['home' => ['hero' => 'carousel', 'category' => 'scroll', 'product' => 'waterfall'], 'product' => ['gallery' => 'swiper', 'price' => 'card', 'action' => 'fixed'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'image', 'menu' => 'grid'], 'effect' => ['transition' => 'slide', 'skeleton' => 'pulse']],
],
[
'code' => 'warm-sand',
'name' => '暖调·沙丘',
'style_tag' => '暖调',
'palette' => ['primary' => '#A16207', 'accent' => '#FDE68A', 'bg' => '#FEFCE8', 'surface' => '#FFFFFF', 'text' => '#292524', 'border' => '#F3E8C8'],
'scale' => 'serif-book',
'radius' => 'soft',
'shadow' => 'airy',
'motion' => 'gentle',
'layout' => ['home' => ['hero' => 'split', 'category' => 'card', 'product' => 'magazine'], 'product' => ['gallery' => 'stack', 'price' => 'inline', 'action' => 'inline'], 'list' => ['style' => 'timeline'], 'mine' => ['header' => 'plain', 'menu' => 'list'], 'effect' => ['transition' => 'fade', 'skeleton' => 'shimmer']],
],
[
'code' => 'cool-slate',
'name' => '冷调·石板',
'style_tag' => '冷调',
'palette' => ['primary' => '#334155', 'accent' => '#94A3B8', 'bg' => '#F1F5F9', 'surface' => '#FFFFFF', 'text' => '#0F172A', 'border' => '#CBD5E1'],
'scale' => 'sans-wide',
'radius' => 'sharp',
'shadow' => 'flat',
'motion' => 'snappy',
'layout' => ['home' => ['hero' => 'banner', 'category' => 'sidebar', 'product' => 'list'], 'product' => ['gallery' => 'swiper', 'price' => 'sticky', 'action' => 'fixed'], 'list' => ['style' => 'table'], 'mine' => ['header' => 'plain', 'menu' => 'list'], 'effect' => ['transition' => 'slide', 'skeleton' => 'pulse']],
],
[
'code' => 'cool-mist',
'name' => '冷调·雾蓝',
'style_tag' => '冷调',
'palette' => ['primary' => '#0369A1', 'accent' => '#7DD3FC', 'bg' => '#F0F9FF', 'surface' => '#FFFFFF', 'text' => '#0C4A6E', 'border' => '#BAE6FD'],
'scale' => 'sans-refined',
'radius' => 'round',
'shadow' => 'airy',
'motion' => 'silk',
'layout' => ['home' => ['hero' => 'carousel', 'category' => 'grid', 'product' => 'grid'], 'product' => ['gallery' => 'swiper', 'price' => 'card', 'action' => 'fixed'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'gradient', 'menu' => 'grid'], 'effect' => ['transition' => 'fade', 'skeleton' => 'shimmer']],
],
[
'code' => 'nature-olive',
'name' => '自然·橄榄',
'style_tag' => '自然',
'palette' => ['primary' => '#4D7C0F', 'accent' => '#BEF264', 'bg' => '#F7FEE7', 'surface' => '#FFFFFF', 'text' => '#1A2E05', 'border' => '#D9F99D'],
'scale' => 'sans-compact',
'radius' => 'soft',
'shadow' => 'soft',
'motion' => 'gentle',
'layout' => ['home' => ['hero' => 'banner', 'category' => 'scroll', 'product' => 'waterfall'], 'product' => ['gallery' => 'swiper', 'price' => 'inline', 'action' => 'inline'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'image', 'menu' => 'grid'], 'effect' => ['transition' => 'fade', 'skeleton' => 'pulse']],
],
[
'code' => 'nature-clay',
'name' => '自然·素坯',
'style_tag' => '自然',
'palette' => ['primary' => '#78716C', 'accent' => '#D6D3D1', 'bg' => '#FAFAF9', 'surface' => '#F5F5F4', 'text' => '#1C1917', 'border' => '#E7E5E4'],
'scale' => 'serif-book',
'radius' => 'soft',
'shadow' => 'flat',
'motion' => 'gentle',
'layout' => ['home' => ['hero' => 'split', 'category' => 'card', 'product' => 'magazine'], 'product' => ['gallery' => 'fullbleed', 'price' => 'inline', 'action' => 'inline'], 'list' => ['style' => 'timeline'], 'mine' => ['header' => 'plain', 'menu' => 'list'], 'effect' => ['transition' => 'fade', 'skeleton' => 'shimmer']],
],
[
'code' => 'bold-crimson',
'name' => '张扬·绛红',
'style_tag' => '浓烈',
'palette' => ['primary' => '#9F1239', 'accent' => '#FB7185', 'bg' => '#FFF1F2', 'surface' => '#FFFFFF', 'text' => '#4C0519', 'border' => '#FECDD3'],
'scale' => 'sans-wide',
'radius' => 'round',
'shadow' => 'deep',
'motion' => 'bouncy',
'layout' => ['home' => ['hero' => 'fullscreen', 'category' => 'card', 'product' => 'grid'], 'product' => ['gallery' => 'stack', 'price' => 'sticky', 'action' => 'fixed'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'gradient', 'menu' => 'grid'], 'effect' => ['transition' => 'zoom', 'skeleton' => 'shimmer']],
],
[
'code' => 'bold-violet',
'name' => '张扬·紫罗兰',
'style_tag' => '浓烈',
'palette' => ['primary' => '#7E22CE', 'accent' => '#D8B4FE', 'bg' => '#FAF5FF', 'surface' => '#FFFFFF', 'text' => '#3B0764', 'border' => '#E9D5FF'],
'scale' => 'sans-refined',
'radius' => 'pill',
'shadow' => 'deep',
'motion' => 'bouncy',
'layout' => ['home' => ['hero' => 'carousel', 'category' => 'scroll', 'product' => 'waterfall'], 'product' => ['gallery' => 'swiper', 'price' => 'card', 'action' => 'fixed'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'gradient', 'menu' => 'grid'], 'effect' => ['transition' => 'zoom', 'skeleton' => 'shimmer']],
],
[
'code' => 'dark-graphite',
'name' => '暗色·石墨',
'style_tag' => '暗色',
'palette' => ['primary' => '#E5E5E5', 'accent' => '#A3A3A3', 'bg' => '#0A0A0A', 'surface' => '#171717', 'text' => '#FAFAFA', 'border' => '#262626'],
'scale' => 'sans-compact',
'radius' => 'sharp',
'shadow' => 'deep',
'motion' => 'snappy',
'layout' => ['home' => ['hero' => 'banner', 'category' => 'grid', 'product' => 'grid'], 'product' => ['gallery' => 'stack', 'price' => 'sticky', 'action' => 'fixed'], 'list' => ['style' => 'table'], 'mine' => ['header' => 'plain', 'menu' => 'list'], 'effect' => ['transition' => 'slide', 'skeleton' => 'pulse']],
],
[
'code' => 'dark-emerald',
'name' => '暗色·祖母绿',
'style_tag' => '暗色',
'palette' => ['primary' => '#34D399', 'accent' => '#065F46', 'bg' => '#04120D', 'surface' => '#0B1F18', 'text' => '#ECFDF5', 'border' => '#14392C'],
'scale' => 'sans-refined',
'radius' => 'round',
'shadow' => 'deep',
'motion' => 'silk',
'layout' => ['home' => ['hero' => 'fullscreen', 'category' => 'sidebar', 'product' => 'waterfall'], 'product' => ['gallery' => 'fullbleed', 'price' => 'card', 'action' => 'fixed'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'image', 'menu' => 'list'], 'effect' => ['transition' => 'fade', 'skeleton' => 'shimmer']],
],
[
'code' => 'retro-cream',
'name' => '复古·奶油',
'style_tag' => '复古',
'palette' => ['primary' => '#92400E', 'accent' => '#FBBF24', 'bg' => '#FFFBEB', 'surface' => '#FEF3C7', 'text' => '#451A03', 'border' => '#FDE68A'],
'scale' => 'serif-book',
'radius' => 'soft',
'shadow' => 'soft',
'motion' => 'gentle',
'layout' => ['home' => ['hero' => 'split', 'category' => 'card', 'product' => 'magazine'], 'product' => ['gallery' => 'swiper', 'price' => 'inline', 'action' => 'inline'], 'list' => ['style' => 'timeline'], 'mine' => ['header' => 'image', 'menu' => 'list'], 'effect' => ['transition' => 'fade', 'skeleton' => 'pulse']],
],
[
'code' => 'retro-ocean',
'name' => '复古·海蓝',
'style_tag' => '复古',
'palette' => ['primary' => '#155E75', 'accent' => '#67E8F9', 'bg' => '#ECFEFF', 'surface' => '#FFFFFF', 'text' => '#083344', 'border' => '#A5F3FC'],
'scale' => 'sans-wide',
'radius' => 'pill',
'shadow' => 'airy',
'motion' => 'bouncy',
'layout' => ['home' => ['hero' => 'carousel', 'category' => 'scroll', 'product' => 'list'], 'product' => ['gallery' => 'swiper', 'price' => 'card', 'action' => 'inline'], 'list' => ['style' => 'card'], 'mine' => ['header' => 'gradient', 'menu' => 'grid'], 'effect' => ['transition' => 'slide', 'skeleton' => 'shimmer']],
],
];