85 lines
2.5 KiB
PHP
85 lines
2.5 KiB
PHP
<?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));
|
||
}
|
||
}
|