登录经销商专属 template_code > 品牌配置 template_code * > 该品牌默认模板 > 通用默认模板 > 内置预设 */ public function current(string $code = ''): array { $appCode = WxAppService::getInstance()->currentCode(); $template = null; if ($code !== '') { $template = WxTemplateModel::where('code', $code)->where('deleted_at', 0)->where('status', 0)->first(); } // 已登录经销商:可用专属模板覆盖品牌默认(未登录则 userInfo 为空,跳过) if (empty($template) && (int) ($this->userInfo['is_p'] ?? 0) === 1) { $userCode = trim((string) ($this->userInfo['template_code'] ?? '')); if ($userCode === '' && !empty($this->userInfo['id'])) { $userCode = (string) (WxUserModel::where('id', $this->userInfo['id']) ->where('deleted_at', 0) ->value('template_code') ?? ''); } if ($userCode !== '') { $template = WxTemplateModel::where('code', $userCode) ->where('deleted_at', 0)->where('status', 0)->first(); } } if (empty($template) && $appCode !== '') { $bound = (string) (WxAppModel::where('code', $appCode) ->where('deleted_at', 0) ->value('template_code') ?? ''); if ($bound !== '') { $template = WxTemplateModel::where('code', $bound)->where('deleted_at', 0)->where('status', 0)->first(); } } if (empty($template) && $appCode !== '') { $template = WxTemplateModel::where('app_code', $appCode) ->where('is_default', 1)->where('deleted_at', 0)->where('status', 0)->first(); } if (empty($template)) { $template = WxTemplateModel::where('app_code', '') ->where('is_default', 1)->where('deleted_at', 0)->where('status', 0)->first(); } $schema = WxTemplateSchemaService::getInstance(); if (empty($template)) { $preset = WxTemplatePresetService::getInstance()->all()[0] ?? []; $tokens = $preset['tokens'] ?? []; $layout = $preset['layout'] ?? []; return $this->packTheme( (string) ($preset['code'] ?? 'lux-champagne'), (string) ($preset['name'] ?? '轻奢·香槟金'), (string) ($preset['style_tag'] ?? '轻奢'), 0, $tokens, $layout, $schema, true, ); } $template = $template->toArray(); $tokens = is_array($template['tokens']) ? $template['tokens'] : []; $layout = is_array($template['layout']) ? $template['layout'] : []; return $this->packTheme( (string) $template['code'], (string) $template['name'], (string) $template['style_tag'], (int) $template['version'], $tokens, $layout, $schema, false, ); } /** * 组装主题包:令牌 + 布局 + 本模板引用到的卡片方案 */ private function packTheme( string $code, string $name, string $styleTag, int $version, array $tokens, array $layout, WxTemplateSchemaService $schema, bool $fallback, ): array { return [ 'code' => $code, 'name' => $name, 'style_tag' => $styleTag, 'version' => $version, 'tokens' => $tokens, 'layout' => $layout, 'css_vars' => $schema->toCssVariables($tokens), 'card_schemes' => WxCardSchemeService::mapByCodes($this->collectSchemeCodes($layout)), 'features' => [ 'package_enabled' => WxAppService::getInstance()->packageEnabled(), 'subscribe_pay_tpl' => $this->subscribeTpl('subscribe_pay_tpl'), 'subscribe_ship_tpl' => $this->subscribeTpl('subscribe_ship_tpl'), ], 'fallback' => $fallback, ]; } /** * 从根 card_scheme、页级 pages.*.card_scheme、区块 props.card_scheme 收集引用 * * @return array */ private function collectSchemeCodes(array $layout): array { $codes = []; if (!empty($layout['card_scheme'])) { $codes[] = (string) $layout['card_scheme']; } foreach ((array) ($layout['pages'] ?? []) as $page) { $pageScheme = (string) ($page['card_scheme'] ?? ''); if ($pageScheme !== '') { $codes[] = $pageScheme; } foreach ((array) ($page['sections'] ?? []) as $section) { $code = (string) ($section['props']['card_scheme'] ?? ''); if ($code !== '') { $codes[] = $code; } } } return $codes; } /** * 可选风格列表,用于小程序里让用户自己换肤 */ public function gallery(): mixed { $appCode = WxAppService::getInstance()->currentCode(); return WxTemplateModel::where('deleted_at', 0) ->where('status', 0) ->when($appCode !== '', fn ($query) => $query->whereIn('app_code', ['', $appCode])) ->orderBy('sort', 'asc') ->get(['code', 'name', 'style_tag', 'preview']); } /** * 当前品牌的订阅模板 ID,给小程序 requestSubscribeMessage 用 */ private function subscribeTpl(string $field): string { try { $app = WxAppService::getInstance()->current(); return trim((string) ($app[$field] ?? '')); } catch (\Throwable) { return ''; } } }