chore: 重写初始提交(清空历史,整理后全量提交)
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp <admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace addon\seo;
|
||||
|
||||
use think\facade\Db;
|
||||
use ywxapp\AddonBase;
|
||||
use ywxapp\model\BaseModel;
|
||||
|
||||
/**
|
||||
* SEO增强插件
|
||||
*
|
||||
* 安装时框架自动导入 install.sql 建表(wxapp_seo_config / keywords / snapshots);
|
||||
* 卸载按统一前缀清理全部表;升级时经 callAddonHook('upgrade') 收敛表结构。
|
||||
*/
|
||||
class Addon extends addon
|
||||
{
|
||||
/**
|
||||
* 安装钩子(框架自动导入 install.sql 后调用)。
|
||||
*/
|
||||
public function install(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 卸载钩子:清理本插件全部表。
|
||||
* 与 install.sql 表名前缀严格对齐(wxapp_seo_),直接复用统一前缀,
|
||||
* 避免依赖 database.prefix 配置(install.sql 为硬写前缀)。
|
||||
*/
|
||||
public function uninstall(): bool
|
||||
{
|
||||
$prefix = 'wxapp_seo_';
|
||||
$tables = [
|
||||
'config', // SEO 配置表
|
||||
'keywords', // 内链关键词表
|
||||
'snapshots', // 收录排名快照表
|
||||
];
|
||||
foreach ($tables as $t) {
|
||||
try {
|
||||
Db::execute("DROP TABLE IF EXISTS `{$prefix}{$t}`");
|
||||
} catch (\Exception $e) {
|
||||
// 忽略
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 升级时确保全部表存在(读 install.sql,CREATE TABLE IF NOT EXISTS 幂等建表)。
|
||||
* 单一事实源 = install.sql,避免复制 DDL 导致漂移。
|
||||
*/
|
||||
private function ensureTablesFromInstallSql(): void
|
||||
{
|
||||
$sqlFile = __DIR__ . DIRECTORY_SEPARATOR . 'install.sql';
|
||||
if (!is_file($sqlFile)) {
|
||||
return;
|
||||
}
|
||||
$content = (string) file_get_contents($sqlFile);
|
||||
$content = preg_replace('/--.*|\/\*[\s\S]*?\*\//', '', $content);
|
||||
$stmts = array_filter(
|
||||
array_map('trim', explode(';', $content)),
|
||||
function ($s) {
|
||||
return strlen($s) > 5 && preg_match('/^CREATE\s+TABLE/i', $s);
|
||||
}
|
||||
);
|
||||
foreach ($stmts as $sql) {
|
||||
if (preg_match('/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?`?([\w]+)`?/i', $sql, $m)) {
|
||||
BaseModel::ensureTable($m[1], $sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 升级钩子(在线升级 / 后台手动升级均会触发)。
|
||||
*
|
||||
* 在线升级(AddonService::onlineUpgrade)已重导 install.sql 补全表;
|
||||
* 但「已存在表新增列」install.sql 的 CREATE TABLE IF NOT EXISTS 对已有表无效。
|
||||
* 此处作为升级收敛点:确保全部表存在 + 对已知易漂移列做幂等补列兜底。
|
||||
* 未来新增列统一在 $columnFixes 登记(须带 DEFAULT x 或 NULL,保证降级安全),
|
||||
* 避免各控制器/模型重复 ensureColumn/ALTER 导致 DDL 漂移。
|
||||
*
|
||||
* @param string $currentVersion 升级前版本号
|
||||
*/
|
||||
public function upgrade($currentVersion = ''): bool
|
||||
{
|
||||
// 1) 确保全部表存在(幂等,单一事实源 install.sql)
|
||||
$this->ensureTablesFromInstallSql();
|
||||
|
||||
// 2) 补列兜底:'完整表名(含前缀)' => ['列名' => '列定义']
|
||||
// BaseModel::ensureColumn 先探测存在性,重复执行安全。
|
||||
// install.sql 当前已含全部列,故此处留空;新增列在此登记即可。
|
||||
$columnFixes = [
|
||||
// 'wxapp_seo_keywords' => [
|
||||
// 'new_col' => "varchar(50) NOT NULL DEFAULT '' COMMENT '示例'",
|
||||
// ],
|
||||
];
|
||||
foreach ($columnFixes as $table => $cols) {
|
||||
foreach ($cols as $column => $def) {
|
||||
BaseModel::ensureColumn($table, $column, $def);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp <admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace addon\seo\controller;
|
||||
use ywxapp\controller\FrontendBase;
|
||||
|
||||
use think\Response;
|
||||
|
||||
/**
|
||||
* SEO增强前台控制器
|
||||
*
|
||||
* 对外提供站点地图、robots 与状态页。无需登录即可访问。
|
||||
*/
|
||||
class Index extends FrontendBase
|
||||
{
|
||||
protected $noNeedLogin = ['*'];
|
||||
protected $noNeedVerify = ['*'];
|
||||
|
||||
/**
|
||||
* 前台状态页
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// TODO: 前台展示/状态页
|
||||
$this->view->assign('title', 'SEO增强');
|
||||
return $this->view->fetch('index/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* 站点地图(/seo/sitemap.xml)
|
||||
*/
|
||||
public function sitemap()
|
||||
{
|
||||
// TODO: 遍历站点 URL 生成符合 sitemaps.org 规范的 XML
|
||||
$xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
. '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>';
|
||||
return Response::create($xml, 'xml')->contentType('application/xml');
|
||||
}
|
||||
|
||||
/**
|
||||
* robots.txt(/seo/robots.txt)
|
||||
*/
|
||||
public function robots()
|
||||
{
|
||||
// TODO: 读取 wxapp_seo_config.robots 输出;此处为默认兜底
|
||||
$txt = "Member-agent: *\nAllow: /";
|
||||
return Response::create($txt)->contentType('text/plain');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp <admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace addon\seo\controller\api;
|
||||
|
||||
/**
|
||||
* SEO增强对外 API(占位)
|
||||
*
|
||||
* 非市场类插件,遵循框架统一 Result 契约(code=0 成功)。
|
||||
* 如需与中心站市场联动再按 Market 系 code=1 契约调整。
|
||||
*/
|
||||
class Seo
|
||||
{
|
||||
/**
|
||||
* 示例:对外查询接口
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
// TODO: 返回 SEO 配置/关键词等数据
|
||||
return json(['code' => 0, 'msg' => 'ok', 'data' => []]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp <admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace addon\seo\controller\backend;
|
||||
|
||||
/**
|
||||
* SEO增强后台控制器
|
||||
*
|
||||
* 业务占位骨架,四个动作对应 menu.json 的四个菜单项。
|
||||
* 实际逻辑(读写 wxapp_seo_config/keywords/snapshots)在 TODO 处实现。
|
||||
*/
|
||||
class Seo extends SeoBackend
|
||||
{
|
||||
/**
|
||||
* SEO概览:收录/排名/内链数等汇总
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// TODO: 聚合 wxapp_seo_snapshots 与 wxapp_seo_keywords 的数量与概览指标
|
||||
$this->view->assign('title', 'SEO概览');
|
||||
return $this->view->fetch('seo/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* SEO设置:站点标题/关键词/描述模板、robots 等
|
||||
*/
|
||||
public function setting()
|
||||
{
|
||||
// TODO: 读取/保存 wxapp_seo_config(表单提交经 POST 落库)
|
||||
$this->view->assign('title', 'SEO设置');
|
||||
return $this->view->fetch('seo/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* 内链关键词:增删改查
|
||||
*/
|
||||
public function keywords()
|
||||
{
|
||||
// TODO: 内链关键词 CRUD(表 wxapp_seo_keywords)
|
||||
$this->view->assign('title', '内链关键词');
|
||||
return $this->view->fetch('seo/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* 收录统计:搜索引擎收录/排名趋势
|
||||
*/
|
||||
public function stats()
|
||||
{
|
||||
// TODO: 收录排名趋势(表 wxapp_seo_snapshots)
|
||||
$this->view->assign('title', '收录统计');
|
||||
return $this->view->fetch('seo/index');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp <admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace addon\seo\controller\backend;
|
||||
|
||||
use ywxapp\controller\BackendBase;
|
||||
|
||||
/**
|
||||
* SEO增强后台控制器基类
|
||||
*
|
||||
* 说明:addon 后台路由(/seo/backend/...)经全局路由分发落在默认 frontend 应用,
|
||||
* 容器 auth 绑定会解析成前台 Auth(isAdmin=false),后台 token 上下文不匹配会被拒。
|
||||
* AddonBackend::_initialize() 已统一处理:当 $this->auth 非 AdminAuth 时强制还原为
|
||||
* AdminAuth 并 tryInitByToken(),再按子类声明的 noNeedLogin/noNeedVerify 做登录与权限校验。
|
||||
*
|
||||
* 这里仅声明跳过后台细粒度权限校验,避免权限规则未配置时锁死后台;登录仍强制要求。
|
||||
*/
|
||||
class SeoBackend extends BackendBase
|
||||
{
|
||||
/**
|
||||
* 跳过后台细粒度权限校验(权限规则未配置时避免锁死后台)。
|
||||
* 登录要求仍由 AddonBackend::_initialize() 强制(noNeedLogin 默认空=需要登录)。
|
||||
*/
|
||||
protected $noNeedVerify = ['*'];
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'name' => 'seo',
|
||||
'title' => 'SEO增强工具',
|
||||
'intro' => '一站式营销与SEO增强:自动站点地图、robots、内链关键词、收录排名统计与AI伪原创占位。',
|
||||
'author' => 'ywxapp',
|
||||
'website' => 'https://github.com',
|
||||
'version' => '1.0.1',
|
||||
'state' => 0,
|
||||
'url' => '/seo',
|
||||
'license' => '',
|
||||
'licenseto' => 0,
|
||||
'config' => [
|
||||
],
|
||||
'events' => [
|
||||
'bind' =>
|
||||
[
|
||||
],
|
||||
'listen' =>
|
||||
[
|
||||
],
|
||||
'subscribe' =>
|
||||
[
|
||||
],
|
||||
],
|
||||
'middleware' => [
|
||||
'alias' =>
|
||||
[
|
||||
],
|
||||
'priority' =>
|
||||
[
|
||||
],
|
||||
],
|
||||
'services' => [
|
||||
],
|
||||
'install_time' => 0,
|
||||
'update_time' => 1786365219,
|
||||
];
|
||||
@@ -0,0 +1,53 @@
|
||||
-- ============================================================
|
||||
-- addon/seo/install.sql —— SEO增强插件数据表
|
||||
-- 框架约定:插件安装时由 ywxapp\service\AddonService 执行本文件
|
||||
-- (仅允许 CREATE TABLE / INSERT,见 importsql 白名单)。
|
||||
-- 表名须为 __PREFIX__seo_*,与 __PREFIX__addon 等核心表命名一致。
|
||||
-- 注意:种子文案禁用 --(框架会逐行把 -- 起内容当注释删,会砍断字符串)。
|
||||
-- ============================================================
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `__PREFIX__seo_config` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '变量名',
|
||||
`group` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '分组',
|
||||
`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '变量标题',
|
||||
`tip` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '变量描述',
|
||||
`type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '类型:string,text,int,bool',
|
||||
`value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '变量值',
|
||||
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '变量字典数据',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='SEO配置表';
|
||||
|
||||
INSERT INTO `__PREFIX__seo_config` (`id`, `name`, `group`, `title`, `tip`, `type`, `value`) VALUES
|
||||
(1, 'site_title', 'basic', '站点标题模板', '支持变量替换', 'string', '{title} - {name}'),
|
||||
(2, 'site_keywords', 'basic', '默认关键词', '逗号分隔', 'string', ''),
|
||||
(3, 'site_description', 'basic', '默认描述', '首页描述', 'text', ''),
|
||||
(4, 'robots', 'basic', 'robots内容', '留空使用默认', 'text', 'User-agent: * Allow: /');
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `__PREFIX__seo_keywords` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||
`keyword` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '关键词',
|
||||
`url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '内链目标URL',
|
||||
`weight` int DEFAULT '0' COMMENT '权重,越大越优先',
|
||||
`status` tinyint DEFAULT '1' COMMENT '状态:1-启用,0-禁用',
|
||||
`create_at` int DEFAULT NULL COMMENT '创建时间',
|
||||
`update_at` int DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_keyword` (`keyword`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='内链关键词表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `__PREFIX__seo_snapshots` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||
`engine` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '搜索引擎:baidu/google/360/sogou',
|
||||
`url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '被统计页面URL',
|
||||
`indexed` tinyint DEFAULT '0' COMMENT '是否被收录:1-是,0-否',
|
||||
`rank` int DEFAULT '0' COMMENT '排名,0=未进入前100',
|
||||
`snapshot_date` date DEFAULT NULL COMMENT '快照日期',
|
||||
`create_at` int DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_engine` (`engine`),
|
||||
KEY `idx_date` (`snapshot_date`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='收录排名快照表';
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"backend": [
|
||||
{
|
||||
"name": "seo",
|
||||
"title": "SEO增强",
|
||||
"icon": "fa fa-search",
|
||||
"type": 1,
|
||||
"sort": 50,
|
||||
"status": 1,
|
||||
"child": [
|
||||
{ "name": "seo/index", "title": "SEO概览", "icon": "fa fa-dashboard", "type": 2, "sort": 0, "route": "/seo/backend/index" },
|
||||
{ "name": "seo/setting", "title": "SEO设置", "icon": "fa fa-cog", "type": 2, "sort": 1, "route": "/seo/backend/setting" },
|
||||
{ "name": "seo/keywords", "title": "内链关键词", "icon": "fa fa-link", "type": 2, "sort": 2, "route": "/seo/backend/keywords" },
|
||||
{ "name": "seo/stats", "title": "收录统计", "icon": "fa fa-bar-chart", "type": 2, "sort": 3, "route": "/seo/backend/stats" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"member": [],
|
||||
"frontend": []
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\facade\Route;
|
||||
|
||||
// 说明:本文件由 ywxapp/service/AppService::loadAddonRoutes() 在 boot 阶段
|
||||
// include,并统一被外层 Route::group('seo', ...) 包住,因此下面写的都是
|
||||
// 【相对规则】,最终自动加 /seo 前缀:
|
||||
// 顶层规则 -> /seo/*
|
||||
// backend 组 -> /seo/backend/*
|
||||
// api 组 -> /seo/api/*
|
||||
|
||||
// 前台页面 / 接口(最终地址 /seo/index、/seo/sitemap.xml、/seo/robots.txt)
|
||||
Route::rule('index', 'Index/index');
|
||||
Route::rule('sitemap.xml', 'Index/sitemap')->completeMatch(true);
|
||||
Route::rule('robots.txt', 'Index/robots')->completeMatch(true);
|
||||
|
||||
// 后台管理路由(对应 controller/backend/ 下的控制器;最终地址 /seo/backend/*)
|
||||
// 注意:全局 route_complete_match=false 时,裸规则会前缀匹配子路径,故必须
|
||||
// ->completeMatch(true) 强制完整匹配,避免 /seo/backend/setting 被派发到错误动作。
|
||||
Route::group('backend', function () {
|
||||
Route::rule('index', 'backend/Seo/index')->completeMatch(true);
|
||||
Route::rule('setting', 'backend/Seo/setting')->completeMatch(true);
|
||||
Route::rule('keywords', 'backend/Seo/keywords')->completeMatch(true);
|
||||
Route::rule('stats', 'backend/Seo/stats')->completeMatch(true);
|
||||
});
|
||||
|
||||
// 对外 API(最终地址 /seo/api/*,按需启用)
|
||||
Route::group('api', function () {
|
||||
Route::rule('lists', 'api/Seo/lists')->completeMatch(true);
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{$title|default='SEO增强'}</title>
|
||||
<link rel="stylesheet" href="/static/layui/css/layui.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">{$title|default='SEO增强'}</div>
|
||||
<div class="layui-card-body">
|
||||
<blockquote class="layui-elem-quote">
|
||||
骨架占位页 —— 在此实现业务逻辑(SEO概览 / 设置 / 内链关键词 / 收录统计)。
|
||||
</blockquote>
|
||||
<div class="layui-tab">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">概览</li>
|
||||
<li>设置</li>
|
||||
<li>内链关键词</li>
|
||||
<li>收录统计</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">TODO:展示收录 / 排名 / 内链汇总指标。</div>
|
||||
<div class="layui-tab-item">TODO:站点标题 / 关键词 / 描述模板、robots 配置表单(表 wxapp_seo_config)。</div>
|
||||
<div class="layui-tab-item">TODO:内链关键词增删改查(表 wxapp_seo_keywords)。</div>
|
||||
<div class="layui-tab-item">TODO:收录排名趋势(表 wxapp_seo_snapshots)。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/static/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.use('element', function () {
|
||||
var element = layui.element;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{$title|default='SEO增强'}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{$title|default='SEO增强'}</h1>
|
||||
<p>SEO增强插件前台占位页。访问 /seo/sitemap.xml 与 /seo/robots.txt 查看对外接口。</p>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user