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));
|
|||
|
|
}
|
|||
|
|
}
|