Anyon e634118a22 refactor(plugin): 迁移 v8 插件化组件体系
将 v6 中直接放在本地 app 的后台与微信能力迁移为 v8 插件组件,并把运行时基础能力沉淀到独立插件包。

主要内容:

- 新增 think-library、system、worker、static、install 等基础插件包。

- 新增 account、payment、wechat-client、wechat-service、wemall、wuma 等业务插件包。

- 移除 v6 的 app/admin 与 app/wechat 本地应用实现,改由插件分发接管。

- 将 Helper 能力彻底并入 System,统一为 plugin\system\helper\* 命名空间。

- 同步插件迁移发布清单与根 route 占位,保证安装发布流程可复现。
2026-05-08 15:30:46 +08:00

120 lines
4.2 KiB
PHP

<?php
declare(strict_types=1);
namespace think\admin\builder\form\render;
use think\admin\builder\base\render\InlineScriptRenderer;
use think\admin\builder\base\render\JsonScriptRenderer;
use think\admin\builder\page\render\PageHeaderRenderer;
/**
* 表单根容器渲染器.
* @class FormShellRenderer
*/
class FormShellRenderer
{
/**
* @param array<string, mixed> $attrs
* @param array<int, array<string, mixed>> $content
* @param array<int, string> $fields
* @param array<int, string> $headerButtons
* @param array<int, string> $buttons
*/
public function render(
array $attrs,
array $bodyAttrs,
array $content,
array $fields,
array $headerButtons,
array $buttons,
array $schema,
array $scripts,
FormNodeRenderContext $context
): string {
$isPage = strval($schema['mode'] ?? '') === 'page';
if ($isPage) {
return $this->renderPageShell($attrs, $bodyAttrs, $content, $fields, $headerButtons, $buttons, $schema, $scripts, $context);
}
$html = sprintf('<form %s>', $context->attrs($attrs));
$html .= "\n\t" . sprintf('<div %s>', $context->attrs($bodyAttrs));
if (count($content) > 0) {
$html .= $context->renderChildren($content);
} else {
$html .= join("\n", $fields);
if (count($buttons) > 0) {
$html .= "\n\t\t";
$html .= (new FormActionBarRenderer())->render([
'type' => 'actions',
'attrs' => ['class' => 'layui-form-item text-center'],
'children' => array_map(static fn(string $button): array => ['type' => 'button', 'html' => $button], $buttons),
], $context);
}
}
if ($schemaScript = (new JsonScriptRenderer())->render($schema, 'form-builder-schema')) {
$html .= "\n\t\t" . $schemaScript;
}
$html .= "\n\t" . '</div>';
return $html . "\n</form>" . (new InlineScriptRenderer())->render($scripts);
}
private function renderPageShell(
array $attrs,
array $bodyAttrs,
array $content,
array $fields,
array $headerButtons,
array $buttons,
array $schema,
array $scripts,
FormNodeRenderContext $context
): string {
$header = (new PageHeaderRenderer())->render(strval($schema['title'] ?? ''), $headerButtons);
$form = sprintf('<form %s>', $context->attrs($attrs));
$form .= "\n\t\t\t\t" . sprintf('<div %s>', $context->attrs($bodyAttrs));
if (count($content) > 0) {
$form .= "\n\t\t\t\t\t" . $context->renderChildren($content);
} else {
$form .= "\n\t\t\t\t\t" . join("\n", $fields);
if (count($buttons) > 0) {
$form .= "\n\t\t\t\t\t";
$form .= (new FormActionBarRenderer())->render([
'type' => 'actions',
'attrs' => ['class' => 'layui-form-item text-center'],
'children' => array_map(static fn(string $button): array => ['type' => 'button', 'html' => $button], $buttons),
], $context);
}
}
if ($schemaScript = (new JsonScriptRenderer())->render($schema, 'form-builder-schema')) {
$form .= "\n\t\t\t\t\t" . $schemaScript;
}
$form .= "\n\t\t\t\t" . '</div>';
$form .= "\n\t\t\t" . '</form>';
$form .= (new InlineScriptRenderer())->render($scripts);
$html = sprintf(
'<div class="layui-card" data-builder-scope="page" data-builder-preset="%s">',
htmlentities(strval($schema['preset'] ?? 'page-form'), ENT_QUOTES, 'UTF-8')
);
if ($header !== '') {
$html .= "\n\t" . $header;
$html .= "\n\t" . '<div class="layui-card-line"></div>';
}
$html .= "\n\t" . '<div class="layui-card-body">';
$html .= "\n\t\t" . '<div class="layui-card-table">';
$html .= "\n\t\t\t" . '<div class="think-box-shadow">';
$html .= "\n\t\t\t\t" . $form;
$html .= "\n\t\t\t" . '</div>';
$html .= "\n\t\t" . '</div>';
$html .= "\n\t" . '</div>';
return $html . "\n</div>";
}
}