2
0

TemplateService.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. namespace App\Services\Template;
  3. use App\Services\Template\TemplateParser;
  4. use App\Services\Template\Renderers\RendererFactory;
  5. use App\Services\Template\TemplateRegistry;
  6. use Illuminate\Support\Facades\Cache;
  7. use Illuminate\Support\Facades\Log;
  8. class TemplateService
  9. {
  10. private TemplateParser $parser;
  11. private bool $cacheEnabled;
  12. private int $cacheTtl;
  13. public function __construct(bool $cacheEnabled = true, int $cacheTtl = 3600)
  14. {
  15. $this->parser = new TemplateParser();
  16. $this->cacheEnabled = $cacheEnabled;
  17. $this->cacheTtl = $cacheTtl;
  18. }
  19. /**
  20. * 解析并渲染内容
  21. */
  22. public function parseAndRender(string $content, string $format = 'json'): array
  23. {
  24. try {
  25. // 生成缓存键
  26. $cacheKey = $this->generateCacheKey($content, $format);
  27. if ($this->cacheEnabled && Cache::has($cacheKey)) {
  28. return Cache::get($cacheKey);
  29. }
  30. // 解析内容
  31. $document = $this->parser->parse($content);
  32. // 渲染内容
  33. $renderer = RendererFactory::create($format);
  34. $renderedContent = $renderer->render($document);
  35. $result = [
  36. 'data' => $format === 'json' ? json_decode($renderedContent, true) : $renderedContent,
  37. 'meta' => $document->meta
  38. ];
  39. // 缓存结果
  40. if ($this->cacheEnabled) {
  41. Cache::put($cacheKey, $result, $this->cacheTtl);
  42. }
  43. return $result;
  44. } catch (\Exception $e) {
  45. Log::error('Template parsing failed', [
  46. 'content' => substr($content, 0, 200),
  47. 'format' => $format,
  48. 'error' => $e->getMessage()
  49. ]);
  50. throw $e;
  51. }
  52. }
  53. /**
  54. * 仅解析,不渲染
  55. */
  56. public function parse(string $content): ParsedDocument
  57. {
  58. return $this->parser->parse($content);
  59. }
  60. /**
  61. * 仅渲染已解析的文档
  62. */
  63. public function render(ParsedDocument $document, string $format): string
  64. {
  65. $renderer = RendererFactory::create($format);
  66. return $renderer->render($document);
  67. }
  68. /**
  69. * 注册新模板
  70. */
  71. public function registerTemplate(string $name, array $config): void
  72. {
  73. $registry = $this->parser->getRegistry();
  74. $registry->registerTemplate($name, $config);
  75. // 清除相关缓存
  76. if ($this->cacheEnabled) {
  77. $this->clearTemplateCache($name);
  78. }
  79. }
  80. /**
  81. * 获取可用模板列表
  82. */
  83. public function getAvailableTemplates(): array
  84. {
  85. $registry = $this->parser->getRegistry();
  86. $templates = [];
  87. // 这里需要添加一个方法来获取所有模板
  88. // 为了示例,我们返回一些基本信息
  89. $basicTemplates = ['note', 'info', 'warning'];
  90. foreach ($basicTemplates as $templateName) {
  91. $template = $registry->getTemplate($templateName);
  92. if ($template) {
  93. $templates[$templateName] = [
  94. 'name' => $templateName,
  95. 'config' => $template,
  96. 'example' => $this->generateTemplateExample($templateName, $template)
  97. ];
  98. }
  99. }
  100. return $templates;
  101. }
  102. /**
  103. * 生成模板使用示例
  104. */
  105. private function generateTemplateExample(string $name, array $config): string
  106. {
  107. $params = [];
  108. $defaultParams = $config['defaultParams'] ?? [];
  109. foreach ($defaultParams as $index => $paramName) {
  110. $params[] = $paramName . '=示例值' . ($index + 1);
  111. }
  112. return '{{' . $name . '|' . implode('|', $params) . '}}';
  113. }
  114. /**
  115. * 生成缓存键
  116. */
  117. private function generateCacheKey(string $content, string $format): string
  118. {
  119. return 'template_' . $format . '_' . md5($content);
  120. }
  121. /**
  122. * 清除模板相关缓存
  123. */
  124. private function clearTemplateCache(string $templateName): void
  125. {
  126. // 这里可以实现更精确的缓存清除逻辑
  127. Cache::flush(); // 简单起见,清除所有缓存
  128. }
  129. /**
  130. * 批量处理内容
  131. */
  132. public function batchProcess(array $contents, string $format = 'json'): array
  133. {
  134. $results = [];
  135. foreach ($contents as $index => $content) {
  136. try {
  137. $results[$index] = $this->parseAndRender($content, $format);
  138. } catch (\Exception $e) {
  139. $results[$index] = [
  140. 'success' => false,
  141. 'error' => $e->getMessage()
  142. ];
  143. }
  144. }
  145. return $results;
  146. }
  147. /**
  148. * 验证模板语法
  149. */
  150. public function validateSyntax(string $content): array
  151. {
  152. $errors = [];
  153. try {
  154. $document = $this->parser->parse($content);
  155. // 检查是否有未知模板
  156. foreach ($document->content as $node) {
  157. if ($node instanceof TemplateNode) {
  158. $registry = $this->parser->getRegistry();
  159. if (!$registry->hasTemplate($node->name)) {
  160. $errors[] = [
  161. 'type' => 'unknown_template',
  162. 'template' => $node->name,
  163. 'position' => $node->position,
  164. 'message' => "Unknown template: {$node->name}"
  165. ];
  166. }
  167. }
  168. }
  169. } catch (\Exception $e) {
  170. $errors[] = [
  171. 'type' => 'parse_error',
  172. 'message' => $e->getMessage()
  173. ];
  174. }
  175. return $errors;
  176. }
  177. }