前端分流页功能
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\index\controller;
|
||||
|
||||
/**
|
||||
* 短链入口:/s/{link_code} 由 ThinkPHP 解析为 controller=S、action={link_code},经 _empty 转 visit
|
||||
* (部署 application/route.php 后亦可显式路由到 Split/visit)
|
||||
*/
|
||||
class S extends Split
|
||||
{
|
||||
/**
|
||||
* @param string $link_code 动作名即为 9 位链接码
|
||||
*/
|
||||
public function _empty(string $link_code = ''): string
|
||||
{
|
||||
return $this->visit($link_code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>404</title>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="referrer" content="no-referrer">
|
||||
<title></title>
|
||||
{$pixel_head_html|raw}
|
||||
</head>
|
||||
<body>
|
||||
{$pixel_body_html|raw}
|
||||
{$orchestrator_html|raw}
|
||||
<noscript>
|
||||
<meta http-equiv="refresh" content="0;url={$redirect_url|htmlentities}">
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user