Files
links/application/index/controller/Split.php
T

85 lines
2.5 KiB
PHP
Raw Normal View History

2026-06-05 04:22:29 +08:00
<?php
declare(strict_types=1);
namespace app\index\controller;
use app\common\controller\Frontend;
use app\common\service\SplitLinkCodeService;
use app\common\service\SplitVisitPageService;
use think\exception\HttpException;
use think\exception\HttpResponseException;
/**
* 分流链接公开落地页(/s/{link_code}
*/
class Split extends Frontend
{
private const PATCH_VIEW_DIR = 'patches/application/index/view/split/';
/** @var string[] */
protected $noNeedLogin = ['visit'];
/** @var string[] */
protected $noNeedRight = ['visit'];
protected $layout = '';
/**
* 访问分流短链:解析号码并输出 JS 跳转页
*
* @param string $link_code 路由参数:9 位小写字母链接码
*/
public function visit(string $link_code = ''): string
{
$code = SplitLinkCodeService::normalize($link_code);
if (!SplitLinkCodeService::isValidFormat($code)) {
$this->abortNotFound();
}
$page = SplitVisitPageService::build(
$code,
(string) $this->request->ip(),
(string) $this->request->server('HTTP_USER_AGENT', ''),
(string) $this->request->url(true)
);
if ($page === null) {
$this->abortNotFound();
}
$this->view->assign('redirect_url', $page['redirect_url']);
$this->view->assign('redirect_url_json', $page['redirect_url_json']);
$this->view->assign('pixel_head_html', $page['pixel_head_html']);
$this->view->assign('pixel_body_html', $page['pixel_body_html']);
$this->view->assign('orchestrator_html', $page['orchestrator_html']);
return $this->fetchPatch('visit');
}
/**
* 渲染模板(优先 patches 视图,回退 application
*/
private function fetchPatch(string $template): string
{
$patchFile = ROOT_PATH . self::PATCH_VIEW_DIR . $template . '.html';
$appFile = APP_PATH . 'index/view/split/' . $template . '.html';
if (is_file($patchFile)) {
$file = $patchFile;
} elseif (is_file($appFile)) {
$file = $appFile;
} else {
throw new HttpException(500, 'Template not found');
}
return (string) $this->view->fetch($file);
}
/**
* 404:输出无中文的空白页,避免框架默认中文错误页
*/
private function abortNotFound(): void
{
throw new HttpResponseException(response($this->fetchPatch('not_found'), 404));
}
}