visuddhinanda преди 9 месеца
родител
ревизия
fa0075a6e4

+ 66 - 0
api-v8/app/Services/TemplateRender.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Services;
+
+use App\Services\Templates\TemplateInterface;
+use InvalidArgumentException;
+
+class TemplateRender
+{
+    protected string $templateName;
+    protected array $params = [];
+    protected TemplateInterface $template;
+
+    // 定义默认公共参数
+    protected array $options = [
+        'format' => 'react', // 默认格式为 react
+    ];
+
+    public static function name(string $templateName): self
+    {
+        $instance = new self();
+        $instance->templateName = $templateName;
+
+        return $instance;
+    }
+
+    public function param(array $params): self
+    {
+        $this->params = $params;
+        return $this;
+    }
+    public function options(array $options): self
+    {
+        $this->options = $options;
+        return $this;
+    }
+
+    public function render(): array
+    {
+        // 解析模板类
+        $this->resolveTemplate();
+
+        // 设置参数并渲染
+        return $this->template
+            ->setParams($this->params)
+            ->setOptions($this->options)
+            ->render();
+    }
+
+    protected function resolveTemplate(): void
+    {
+        // 模板名称到类的映射(可以用配置文件替代)
+        $templateMap = [
+            'cf' => \App\Services\Templates\ConfidenceTemplate::class,
+            'nissaya' => \App\Services\Templates\NissayaTemplate::class,
+            'term' => \App\Services\Templates\TermTemplate::class,
+        ];
+
+        if (!isset($templateMap[$this->templateName])) {
+            throw new InvalidArgumentException("Template {$this->templateName} not found.");
+        }
+
+        // 通过服务容器解析模板类
+        $this->template = app($templateMap[$this->templateName]);
+    }
+}

+ 33 - 0
api-v8/app/Services/Templates/AbstractTemplate.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace App\Services\Templates;
+
+abstract class AbstractTemplate implements TemplateInterface
+{
+    protected array $params = [];
+    protected array $options = [];
+
+    public function setParams(array $params): self
+    {
+        $this->params = $params;
+        return $this;
+    }
+    public function setOptions(array $options): self
+    {
+        $this->options = $options;
+        return $this;
+    }
+    protected  function getParam(string $name, int $id, string $default = ''): string
+    {
+        if (isset($this->params[$name])) {
+            return trim($this->params[$name]);
+        } else if (isset($this->params["{$id}"])) {
+            return trim($this->params["{$id}"]);
+        } else {
+            return $default;
+        }
+    }
+
+
+    abstract public function render(): array;
+}

+ 43 - 0
api-v8/app/Services/Templates/ConfidenceTemplate.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace App\Services\Templates;
+
+class ConfidenceTemplate extends AbstractTemplate
+{
+    public function render(): array
+    {
+        // 示例:处理 email 模板的渲染逻辑
+        $value = $this->getParam('value', 1, '0');
+
+        // 根据 format 调整渲染逻辑
+        $props = ['value' => $value];
+        $output = [];
+        switch ($this->options['format']) {
+            case 'react':
+                $output = [
+                    'props' => base64_encode(\json_encode($props)),
+                    'html' => '',
+                    'tag' => 'span',
+                    'tpl' => 'cf',
+                ];
+                break;
+            case 'unity':
+                $output = [
+                    'props' => base64_encode(\json_encode($props)),
+                    'tpl' => 'cf',
+                ];
+                break;
+            case 'markdown':
+                $output = ["`$value`"];
+                break;
+            case 'html':
+                $output = ["<span>{$value}</span>"];
+                break;
+            default:
+                $output = [$value];
+                break;
+        }
+
+        return $output;
+    }
+}

+ 53 - 0
api-v8/app/Services/Templates/NissayaTemplate.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Services\Templates;
+
+use App\Tools\Tools;
+
+class NissayaTemplate extends AbstractTemplate
+{
+    public function render(): array
+    {
+
+        $pali =  $this->getParam("pali", 1);
+        $meaning = $this->getParam("meaning", 2);
+        $innerString = "";
+        $props = [
+            "pali" => $pali,
+            "meaning" => $meaning,
+            "lang" => $this->options['lang'],
+        ];
+        switch ($this->options['format']) {
+            case 'react':
+                $output = [
+                    'props' => base64_encode(\json_encode($props)),
+                    'html' => $innerString,
+                    'tag' => 'span',
+                    'tpl' => 'nissaya',
+                ];
+                break;
+            case 'unity':
+                $output = [
+                    'props' => base64_encode(\json_encode($props)),
+                    'tpl' => 'nissaya',
+                ];
+                break;
+            case 'text':
+                $output = $pali . '၊' . $meaning;
+                break;
+            case 'tex':
+                $output = $pali . '၊' . $meaning;
+                break;
+            case 'simple':
+                $output = $pali . '၊' . $meaning;
+                break;
+            case 'prompt':
+                $output = Tools::MyToRm($pali) . ':' . $meaning;
+                break;
+            default:
+                $output = $pali . '၊' . $meaning;
+                break;
+        }
+        return $output;
+    }
+}

+ 10 - 0
api-v8/app/Services/Templates/TemplateInterface.php

@@ -0,0 +1,10 @@
+<?php
+
+namespace App\Services\Templates;
+
+interface TemplateInterface
+{
+    public function setParams(array $params): self;
+    public function setOptions(array $options): self;
+    public function render(): array;
+}

+ 268 - 0
api-v8/app/Services/Templates/TermTemplate.php

@@ -0,0 +1,268 @@
+<?php
+
+namespace App\Services\Templates;
+
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Str;
+use App\Models\DhammaTerm;
+use App\Models\Channel;
+use App\Http\Api\ChannelApi;
+use App\Http\Api\MdRender;
+
+
+class TermTemplate extends AbstractTemplate
+{
+    protected $glossaryKey = 'glossary';
+
+    public function render(): array
+    {
+        $word = $this->getParam("word", 1);
+
+        $props = $this->getTermProps($word, '');
+
+        $output = $props['word'];
+        switch ($this->options['format']) {
+            case 'react':
+                $output = [
+                    'props' => base64_encode(\json_encode($props)),
+                    'html' => $props['innerHtml'],
+                    'tag' => 'span',
+                    'tpl' => 'term',
+                ];
+                break;
+            case 'unity':
+                $output = [
+                    'props' => base64_encode(\json_encode($props)),
+                    'tpl' => 'term',
+                ];
+                break;
+            case 'html':
+                if (isset($props["meaning"])) {
+                    $GLOBALS[$this->glossaryKey][$props["word"]] = $props['meaning'];
+
+                    $key = 'term-' . $props["word"];
+                    $termHead = "<a href='#'>" . $props['meaning'] . "</a>";
+
+                    if (isset($GLOBALS[$key])) {
+                        $output = $termHead;
+                    } else {
+                        $GLOBALS[$key] = 1;
+                        $output = $termHead . '(<em>' . $props["word"] . '</em>)';
+                    }
+                } else {
+                    $output = $props["word"];
+                }
+                break;
+            case 'text':
+                if (isset($props["meaning"])) {
+                    $key = 'term-' . $props["word"];
+                    if (isset($GLOBALS[$key])) {
+                        $output = $props["meaning"];
+                    } else {
+                        $GLOBALS[$key] = 1;
+                        $output = $props["meaning"] . '(' . $props["word"] . ')';
+                    }
+                } else {
+                    $output = $props["word"];
+                }
+                break;
+            case 'tex':
+                if (isset($props["meaning"])) {
+                    $key = 'term-' . $props["word"];
+                    if (isset($GLOBALS[$key])) {
+                        $output = $props["meaning"];
+                    } else {
+                        $GLOBALS[$key] = 1;
+                        $output = $props["meaning"] . '(' . $props["word"] . ')';
+                    }
+                } else {
+                    $output = $props["word"];
+                }
+                break;
+            case 'simple':
+                if (isset($props["meaning"])) {
+                    $output = $props["meaning"];
+                } else {
+                    $output = $props["word"];
+                }
+                break;
+            case 'markdown':
+                if (isset($props["meaning"])) {
+                    $key = 'term-' . $props["word"];
+                    if (isset($GLOBALS[$key]) && $GLOBALS[$key] === 1) {
+                        $GLOBALS[$key]++;
+                        $output = $props["meaning"];
+                    } else {
+                        $GLOBALS[$key] = 1;
+                        $output = $props["meaning"] . '(' . $props["word"] . ')';
+                    }
+                } else {
+                    $output = $props["word"];
+                }
+                //如果有内容且第一次出现,显示为脚注
+                if (!empty($props["note"]) && $GLOBALS[$key] === 1) {
+                    if (isset($GLOBALS['note_sn'])) {
+                        $GLOBALS['note_sn']++;
+                    } else {
+                        $GLOBALS['note_sn'] = 1;
+                        $GLOBALS['note'] = array();
+                    }
+                    $content = $props["note"];
+                    $output .= '[^' . $GLOBALS['note_sn'] . ']';
+                    $GLOBALS['note'][] = [
+                        'sn' => $GLOBALS['note_sn'],
+                        'trigger' => '',
+                        'content' => $content,
+                    ];
+                }
+                break;
+            default:
+                if (isset($props["meaning"])) {
+                    $output = $props["meaning"];
+                } else {
+                    $output = $props["word"];
+                }
+                break;
+        }
+        return $output;
+    }
+
+    public function getTermProps($word, $tag = null, $channel = null)
+    {
+        if ($channel && !empty($channel)) {
+            $channelId = $channel;
+        } else {
+            if (count($this->channel_id) > 0) {
+                $channelId = $this->channel_id[0];
+            } else {
+                $channelId = null;
+            }
+        }
+
+        if (count($this->channelInfo) === 0) {
+            if (!empty($channel)) {
+                $channelInfo = Channel::where('uid', $channel)->first();
+                if (!$channelInfo) {
+                    unset($channelInfo);
+                }
+            }
+            if (!isset($channelInfo)) {
+                Log::warning('channel is null');
+                $output = [
+                    "word" => $word,
+                    'innerHtml' => '',
+                ];
+                return $output;
+            }
+        } else {
+            $channelInfo = $this->channelInfo[0];
+        }
+
+        if (Str::isUuid($channelId)) {
+            $lang = Channel::where('uid', $channelId)->value('lang');
+            if (!empty($lang)) {
+                $langFamily = explode('-', $lang)[0];
+            } else {
+                $langFamily = 'zh';
+            }
+            $this->info("term:{$word} 先查属于这个channel 的", 'term');
+            $this->info('channel id' . $channelId, 'term');
+            $table = DhammaTerm::where("word", $word)
+                ->where('channal', $channelId);
+            if ($tag && !empty($tag)) {
+                $table = $table->where('tag', $tag);
+            }
+            $tplParam = $table->orderBy('updated_at', 'desc')
+                ->first();
+            $studioId = $channelInfo->owner_uid;
+        } else {
+            $tplParam = false;
+            $lang = '';
+            $langFamily = '';
+            $studioId = $this->studioId;
+        }
+
+        if (!$tplParam) {
+            if (Str::isUuid($studioId)) {
+                /**
+                 * 没有,再查这个studio的
+                 * 按照语言过滤
+                 * 完全匹配的优先
+                 * 语族匹配也行
+                 */
+                Log::debug("没有-再查这个studio的", 'term');
+                $table = DhammaTerm::where("word", $word);
+                if (!empty($tag)) {
+                    $table = $table->where('tag', $tag);
+                }
+                $termsInStudio = $table->where('owner', $channelInfo->owner_uid)
+                    ->orderBy('updated_at', 'desc')
+                    ->get();
+                if (count($termsInStudio) > 0) {
+                    $list = array();
+                    foreach ($termsInStudio as $key => $term) {
+                        if (empty($term->channal)) {
+                            if ($term->language === $lang) {
+                                $list[$term->guid] = 2;
+                            } else if (strpos($term->language, $langFamily) !== false) {
+                                $list[$term->guid] = 1;
+                            }
+                        }
+                    }
+                    if (count($list) > 0) {
+                        arsort($list);
+                        foreach ($list as $key => $one) {
+                            foreach ($termsInStudio as $term) {
+                                if ($term->guid === $key) {
+                                    $tplParam = $term;
+                                    break;
+                                }
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (!$tplParam) {
+            Log::debug("没有,再查社区", 'term');
+            $community_channel = ChannelApi::getSysChannel("_community_term_zh-hans_");
+            $table = DhammaTerm::where("word", $word);
+            if (!empty($tag)) {
+                $table = $table->where('tag', $tag);
+            }
+            $tplParam = $table->where('channal', $community_channel)
+                ->first();
+            if ($tplParam) {
+                $isCommunity = true;
+            } else {
+                Log::debug("查社区没有", 'term');
+            }
+        }
+        $output = [
+            "word" => $word,
+            "parentChannelId" => $channelId,
+            "parentStudioId" => $channelInfo->owner_uid,
+        ];
+        $innerString = $output["word"];
+        if ($tplParam) {
+            $output["id"] = $tplParam->guid;
+            $output["meaning"] = $tplParam->meaning;
+            $output["channel"] = $tplParam->channal;
+            if (!empty($tplParam->note)) {
+                $mdRender = new MdRender(['format' => $this->options['format']]);
+                $output['note'] = $mdRender->convert($tplParam->note, $this->channel_id);
+            }
+            if (isset($isCommunity)) {
+                $output["isCommunity"] = true;
+            }
+            $innerString = "{$output["meaning"]}({$output["word"]})";
+            if (!empty($tplParam->other_meaning)) {
+                $output["meaning2"] = $tplParam->other_meaning;
+            }
+        }
+        $output['innerHtml'] = $innerString;
+        return $output;
+    }
+}