安全(P0) - 发布包签名:新增 scripts/package_keygen.php、scripts/package_verify.php、 ywxapp\service\PackageVerifier;FrameworkService::apply() 解压前强制验签 (ywxapp.framework_package_verify,默认开启) - JWT 收紧:config/jwt.php 移除公开默认密钥,JwtService::assertStrongSecret() 校验非空 / 长度≥32 / 已知弱值;.env.production.example 键名由 JWT_SECRET_KEY 修正为 JWT_SECRET - /api/v1/Article:免登录白名单收窄为只读接口,写操作字段白名单 + assertOwner() 越权校验 - 开发者令牌:查找接口不再回显明文、统一失败文案 + 限流 - TemplateInstaller:文件名白名单 + realpath 归一化 + 目录内断言,修复 Zip Slip;补 use ZipArchive - 后台登录:接入验证码、失败锁定与登录限流(config/ratelimit.php) - 缓存 / Session 驱动可由 .env 覆盖(CACHE_DRIVER / SESSION_TYPE),集群部署改 redis - paycenter 支付日志开关改为 PAY_LOG,不再跟随 APP_DEBUG 工程化 / 交付 - 新增 CHANGELOG.md 与 .env.production.example;composer.lock 入库锁定依赖版本 - 插件离线安装 CLI 增加 --uid,后台上传安装透传 uid,付费插件授权校验可通过 - 授权拒绝文案区分「未携带 uid」与「未找到有效授权」,便于排障 - .gitignore 放行 .env.production.example / .env.addon.example / .gitattributes / public/.htaccess 结构 - appmall 由 addon/appmall 迁移为独立应用 app/appmall(市场 / 开发者中心 / 审核 / 分润)
108 lines
4.4 KiB
HTML
108 lines
4.4 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>{$info.title|default='网址分类'} - {$seo.title|default='网址导航'}</title>
|
||
<meta name="keywords" content="{$info.keywords | default='网址导航,分类'}">
|
||
<meta name="description" content="{$info.description | default='网址导航分类'}">
|
||
{notempty name="info"}<link rel="canonical" href="{$siteUrl|default=''}/haonav/category/{$info.id}.html">{/notempty}
|
||
{include file="public/styles" /}
|
||
<link rel="stylesheet" href="/static/haonav/css/nav-page-category.css">
|
||
</head>
|
||
|
||
<body>
|
||
{assign name="navActive" value="" /}
|
||
{assign name="navSearch" value="site" /}
|
||
{assign name="navUser" value="1" /}
|
||
{include file="public/navbar" /}
|
||
|
||
<div class="main-content">
|
||
<div class="section-title">
|
||
<h2>📋 {$info.title}</h2>
|
||
</div>
|
||
|
||
{if $mode == 'group'}
|
||
<!-- 顶级分类:按二级子分类分组展示 -->
|
||
{volist name="info.children" id="sub"}
|
||
<div class="sub-category">
|
||
<div class="sub-title"><span>{$sub.title}</span></div>
|
||
<div class="website-list">
|
||
{volist name="sub.sub_links" id="link"}
|
||
<a href="{:url('[haonav_site]',['id'=>$link.id])}" class="website-item">
|
||
<span class="website-item-icon"><img src="{$link.show_icon}" loading="lazy" alt="{$link.title}"></span>
|
||
<span class="website-item-info">
|
||
<h3>{$link.title}</h3>
|
||
<p>{$link.description|default='暂无描述'}</p>
|
||
</span>
|
||
<span class="qr-btn js-qr" data-url="{$link.url}" title="二维码">▦</span>
|
||
</a>
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
{/volist}
|
||
|
||
<!-- 未细分二级的常用链接(sub_cid=0) -->
|
||
{notempty name="others"}
|
||
<div class="sub-category">
|
||
<div class="sub-title"><span>常用</span></div>
|
||
<div class="website-list">
|
||
{volist name="others" id="link"}
|
||
<a href="{:url('[haonav_site]',['id'=>$link.id])}" class="website-item">
|
||
<span class="website-item-icon"><img src="{$link.show_icon}" loading="lazy" alt="{$link.title}"></span>
|
||
<span class="website-item-info">
|
||
<h3>{$link.title}</h3>
|
||
<p>{$link.description|default='暂无描述'}</p>
|
||
</span>
|
||
<span class="qr-btn js-qr" data-url="{$link.url}" title="二维码">▦</span>
|
||
</a>
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{else /}
|
||
<!-- 二级/叶子分类:直接列出该分类下的全部链接 -->
|
||
<div class="sub-category">
|
||
<div class="sub-title"><span>{$info.title}</span></div>
|
||
<div class="website-list">
|
||
{volist name="links" id="link"}
|
||
<a href="{:url('[haonav_site]',['id'=>$link.id])}" class="website-item">
|
||
<span class="website-item-icon"><img src="{$link.show_icon}" loading="lazy" alt="{$link.title}"></span>
|
||
<span class="website-item-info">
|
||
<h3>{$link.title}</h3>
|
||
<p>{$link.description|default='暂无描述'}</p>
|
||
</span>
|
||
<span class="qr-btn js-qr" data-url="{$link.url}" title="二维码">▦</span>
|
||
</a>
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
{/if}
|
||
</div>
|
||
|
||
<div class="footer">
|
||
<p>© 2026 网址导航 - 让上网更简单</p>
|
||
</div>
|
||
|
||
<div class="qr-mask" id="qrMask">
|
||
<div class="qr-box">
|
||
<img id="qrImg" src="" alt="二维码">
|
||
<p id="qrText"></p>
|
||
<span class="close">关闭</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 登录 / 注册 弹层由全局组件 auth.js 自动注入 -->
|
||
|
||
<script src="/static/haonav/js/nav-core.js"></script>
|
||
<script src="/static/haonav/js/nav-theme.js"></script>
|
||
<script src="/static/haonav/js/nav-festival.js"></script>
|
||
<script src="/static/haonav/js/nav-fav.js"></script>
|
||
<script src="/static/haonav/js/nav-search.js"></script>
|
||
<script src="/static/haonav/js/nav-widgets.js"></script>
|
||
<script src="/static/haonav/js/auth.js"></script>
|
||
</body>
|
||
|
||
</html>
|