chore: 重写初始提交(清空历史,整理后全量提交)
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
{extend name="layout" /}
|
||||
{block name="title"}{$author.nickname} 的个人博客 - {$siteConf.site_name|default='博客'}{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="fb-layout">
|
||||
<main class="fb-content">
|
||||
<!-- 个人资料卡 -->
|
||||
<div class="fb-card" style="display:flex;align-items:center;gap:18px;margin-bottom:18px;">
|
||||
<img src="{$avatar}" alt="{$author.nickname}" style="width:72px;height:72px;border-radius:50%;object-fit:cover;border:2px solid var(--theme);">
|
||||
<div>
|
||||
<h2 style="margin:0 0 6px;font-size:20px;color:var(--text);">{$author.nickname}</h2>
|
||||
<p style="margin:0 0 8px;color:var(--text-2);font-size:13px;">{$author.bio|default='这个人很懒,什么都没留下~'}</p>
|
||||
<p style="margin:0;font-size:13px;color:var(--text-3);">
|
||||
<span style="margin-right:16px;">文章 <b style="color:var(--theme);">{$stats.articles}</b></span>
|
||||
<span style="margin-right:16px;">阅读 <b style="color:var(--theme);">{$stats.views}</b></span>
|
||||
<span style="margin-right:16px;">获赞 <b style="color:var(--theme);">{$stats.likes}</b></span>
|
||||
<span>加入于 {$author_join}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="fb-section-title"><h2>他的文章({$articles->total()} 篇)</h2></div>
|
||||
|
||||
{if $articles->isEmpty()}
|
||||
<div class="fb-empty"><p>该用户暂无已发布文章。</p></div>
|
||||
{else}
|
||||
<div class="fb-post-list">
|
||||
{volist name="articles" id="article"}
|
||||
<article class="fb-post">
|
||||
{if $article.cover_image}
|
||||
<a class="thumb" href="{:url('blog/article/detail', ['id' => $article.id])}">
|
||||
<img src="{$article.cover_image}" alt="{$article.title}">
|
||||
</a>
|
||||
{/if}
|
||||
<div class="body">
|
||||
<span class="cat">{$article.category.name|default='默认'}</span>
|
||||
<h3><a href="{:url('blog/article/detail', ['id' => $article.id])}">{$article.title}</a></h3>
|
||||
<p class="summary">{$article.summary|default='(暂无描述)'}</p>
|
||||
<div class="meta">
|
||||
<span class="sp">{$article.create_text}</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{/volist}
|
||||
</div>
|
||||
<div class="fb-pager">{$articles|raw}</div>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
{include file="index/_sidebar" /}
|
||||
</div>
|
||||
{/block}
|
||||
@@ -0,0 +1,159 @@
|
||||
{extend name="layout" /}
|
||||
{block name="title"}{$article.title} - {$siteConf.site_name|default='博客'}{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="fb-layout">
|
||||
<main class="fb-content">
|
||||
<!-- 文章正文 -->
|
||||
<article class="fb-article">
|
||||
<div class="crumb">博文 > <a href="{:url('blog/category', ['id' => $article.cid])}">{$article.category.name|default='默认'}</a></div>
|
||||
<h1>{$article.title}</h1>
|
||||
<div class="post-meta">
|
||||
<a class="author" href="{:url('blog/article/author', ['id' => $article.uid])}">
|
||||
<img src="{$article.user.avatar|default='/static/blog/img/avatar.jpg'}" alt="">
|
||||
{$article.user.nickname|default='佚名'}
|
||||
</a>
|
||||
<span><i class="layui-icon layui-icon-read"></i> {$article.view_count|default=0}</span>
|
||||
<span>{$article.create_text}</span>
|
||||
</div>
|
||||
{if $article.cover_image}
|
||||
<div class="cover"><img src="{$article.cover_image}" alt="{$article.title}"></div>
|
||||
{/if}
|
||||
<div class="content">{$article.content|raw}</div>
|
||||
<div class="action-bar">
|
||||
<button type="button" class="fb-btn like-btn" data-id="{$article.id}"><i class="layui-icon layui-icon-praise"></i> 点赞 (<span id="likeCount">{$article.like_count}</span>)</button>
|
||||
<button type="button" class="fb-btn ghost fav-btn" data-id="{$article.id}"><i class="layui-icon layui-icon-star"></i> 收藏 (<span id="favCount">{$article.favorite_count}</span>)</button>
|
||||
<button type="button" class="fb-btn ghost share-btn"><i class="layui-icon layui-icon-share"></i> 分享</button>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<!-- 评论区 -->
|
||||
<section class="fb-comments">
|
||||
<p class="ct-title">全部留言 <em id="count">{$article.comment_count}</em></p>
|
||||
|
||||
{if $is_login}
|
||||
<div class="fb-cmt-form">
|
||||
<textarea id="LAY-msg-content" placeholder="既然来了,就说几句吧" style="resize:none;"></textarea>
|
||||
<div style="margin-top:10px;display:flex;align-items:center;gap:10px;">
|
||||
<button class="fb-btn" type="button" id="item-btn">发表留言</button>
|
||||
<span class="reply-tip" id="replyTip" style="display:none;color:var(--theme);"></span>
|
||||
<button class="fb-btn ghost" type="button" id="cancelReply" style="display:none;">取消回复</button>
|
||||
</div>
|
||||
</div>
|
||||
{else /}
|
||||
<div style="padding:10px 0;color:var(--text-3);">请 <a href="{:url('auth/login')}" style="color:var(--theme);">登录</a> 后发表留言</div>
|
||||
{/if}
|
||||
|
||||
<ul class="fb-cmt-list" id="LAY-msg-box" style="list-style:none;margin:0;padding:0;">
|
||||
{volist name="comments" id="comment"}
|
||||
<li class="fb-cmt-item" data-id="{$comment.id}">
|
||||
<img src="{$comment.user.avatar|default='/static/blog/img/portrait.jpg'}" alt="">
|
||||
<div class="ci-body">
|
||||
<p style="margin:0;">
|
||||
<span class="ci-name">{$comment.user.nickname|default='佚名'}</span>
|
||||
<span class="ci-time">{$comment.create_text}</span>
|
||||
{if $is_login}<span class="ci-reply" data-id="{$comment.id}" data-name="{$comment.user.nickname}">回复</span>{/if}
|
||||
</p>
|
||||
<p class="ci-text">{$comment.content}</p>
|
||||
<ul class="fb-cmt-children">
|
||||
{volist name="comment.children" id="child"}
|
||||
<li data-id="{$child.id}">
|
||||
<img src="{$child.user.avatar|default='/static/blog/img/portrait.jpg'}" alt="">
|
||||
<div class="ci-body">
|
||||
<p style="margin:0;">
|
||||
<span class="ci-name">{$child.user.nickname|default='佚名'}</span>
|
||||
<span class="ci-time">{$child.create_text}</span>
|
||||
{if $is_login}<span class="ci-reply" data-id="{$comment.id}" data-name="{$comment.user.nickname}">回复</span>{/if}
|
||||
</p>
|
||||
<p class="ci-text">{$child.content}</p>
|
||||
</div>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
<div class="fb-pager">{$comments|raw}</div>
|
||||
</section>
|
||||
|
||||
<!-- 相关文章推荐 -->
|
||||
{if !empty($relatedArticles)}
|
||||
<section class="fb-related">
|
||||
<p class="ct-title">相关推荐</p>
|
||||
<ul class="fb-related-list">
|
||||
{volist name="relatedArticles" id="ra"}
|
||||
<li><a href="{:url('blog/article/detail', ['id' => $ra.id])}">{$ra.title}</a><span>{$ra.category.name|default=''}</span></li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</section>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
{include file="index/_sidebar" /}
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block name="script"}
|
||||
<script>
|
||||
layui.use(['layer', 'jquery'], function(){
|
||||
var layer = layui.layer, $ = layui.$;
|
||||
$('.like-btn').click(function(){
|
||||
var id = $(this).data('id');
|
||||
$.post('{:url("interaction/like")}', { article_id: id }, function(res){
|
||||
if(res.code===1){ $('#likeCount').text(res.count); layer.msg(res.msg,{icon:1}); } else { layer.msg(res.msg,{icon:2}); }
|
||||
});
|
||||
});
|
||||
$('.fav-btn').click(function(){
|
||||
var id = $(this).data('id');
|
||||
$.post('{:url("interaction/favorite")}', { article_id: id }, function(res){
|
||||
if(res.code===1){ $('#favCount').text(res.count); layer.msg(res.msg,{icon:1}); } else { layer.msg(res.msg,{icon:2}); }
|
||||
});
|
||||
});
|
||||
$('.share-btn').click(function(){
|
||||
layer.open({ title:'分享文章', content:'<div style="padding:10px;"><input type="text" value="'+window.location.href+'" class="layui-input" readonly></div>', area:['500px','200px'] });
|
||||
$.post('{:url("interaction/share")}', { article_id: {$article.id} });
|
||||
});
|
||||
|
||||
// ===== 留言 / 回复 =====
|
||||
var replyTo = 0;
|
||||
$(document).on('click', '.ci-reply', function(){
|
||||
if(!$('#LAY-msg-content').length){ return; }
|
||||
replyTo = $(this).data('id');
|
||||
var name = $(this).data('name');
|
||||
$('#replyTip').text('回复 @' + name).show();
|
||||
$('#cancelReply').show();
|
||||
$('#LAY-msg-content').attr('placeholder', '回复 @' + name);
|
||||
$('#LAY-msg-content').focus();
|
||||
$('html,body').animate({ scrollTop: $('.fb-cmt-form').offset().top - 20 }, 300);
|
||||
});
|
||||
$('#cancelReply').on('click', function(){
|
||||
replyTo = 0;
|
||||
$('#replyTip').hide().text('');
|
||||
$(this).hide();
|
||||
$('#LAY-msg-content').attr('placeholder', '既然来了,就说几句吧').val('');
|
||||
});
|
||||
$('#item-btn').on('click', function(){
|
||||
var content = $('#LAY-msg-content').val();
|
||||
if(content.replace(/\s/g,'')==''){ layer.msg('请先输入留言内容'); return; }
|
||||
$.post('{:url("comment/add")}', { article_id: {$article.id}, parent_id: replyTo, content: content }, function(res){
|
||||
if(res.code===1){
|
||||
var d = res.data;
|
||||
var avatar = d.user.avatar || '/static/blog/img/portrait.jpg';
|
||||
if(replyTo > 0){
|
||||
var html = '<li data-id="'+d.id+'"><img src="'+avatar+'"><div class="ci-body"><p style="margin:0;"><span class="ci-name">'+d.user.nickname+'</span><span class="ci-time">'+d.create_text+'</span> <span class="ci-reply" data-id="'+replyTo+'" data-name="'+d.user.nickname+'">回复</span></p><p class="ci-text">'+d.content+'</p></div></li>';
|
||||
$('.fb-cmt-item[data-id="'+replyTo+'"] > .ci-body > .fb-cmt-children').prepend(html);
|
||||
} else {
|
||||
var html = '<li class="fb-cmt-item" data-id="'+d.id+'"><img src="'+avatar+'"><div class="ci-body"><p style="margin:0;"><span class="ci-name">'+d.user.nickname+'</span><span class="ci-time">'+d.create_text+'</span> <span class="ci-reply" data-id="'+d.id+'" data-name="'+d.user.nickname+'">回复</span></p><p class="ci-text">'+d.content+'</p><ul class="fb-cmt-children"></ul></div></li>';
|
||||
$('#LAY-msg-box').prepend(html);
|
||||
}
|
||||
$('#LAY-msg-content').val('');
|
||||
$('#count').text((parseInt($('#count').text())||0) + 1);
|
||||
replyTo = 0; $('#replyTip').hide(); $('#cancelReply').hide();
|
||||
layer.msg(res.msg,{icon:1});
|
||||
} else { layer.msg(res.msg,{icon:2}); }
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
@@ -0,0 +1,47 @@
|
||||
{extend name="layout" /}
|
||||
{block name="title"}文章列表 - {$siteConf.site_name|default='博客'}{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="fb-layout">
|
||||
<main class="fb-content">
|
||||
<div class="fb-section-title"><h2>全部文章</h2></div>
|
||||
{if $articles->isEmpty()}
|
||||
<div class="fb-empty"><p>站点还没有发布文章,敬请期待。</p></div>
|
||||
{else}
|
||||
<div class="fb-post-list">
|
||||
{volist name="articles" id="article"}
|
||||
<article class="fb-post">
|
||||
{if $article.cover_image}
|
||||
<a class="thumb" href="{:url('blog/article/detail', ['id' => $article.id])}">
|
||||
<img src="{$article.cover_image}" alt="{$article.title}">
|
||||
</a>
|
||||
{/if}
|
||||
<div class="body">
|
||||
<span class="cat">{$article.category.name|default='默认'}</span>
|
||||
<h3><a href="{:url('blog/article/detail', ['id' => $article.id])}">{$article.title}</a></h3>
|
||||
<p class="summary">{$article.summary|default='(暂无描述)'}</p>
|
||||
<div class="article-stats" style="margin:2px 0 10px;color:#999;font-size:13px;">
|
||||
<span style="margin-right:12px;"><i class="layui-icon layui-icon-read"></i> {$article.view_count|default=0} 阅读</span>
|
||||
<span style="margin-right:12px;"><i class="layui-icon layui-icon-praise"></i> {$article.like_count|default=0} 点赞</span>
|
||||
<span style="margin-right:12px;"><i class="layui-icon layui-icon-star"></i> {$article.favorite_count|default=0} 收藏</span>
|
||||
<span style="margin-right:12px;"><i class="layui-icon layui-icon-reply"></i> {$article.comment_count|default=0} 评论</span>
|
||||
<span><i class="layui-icon layui-icon-share"></i> {$article.share_count|default=0} 分享</span>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<a class="author" href="{:url('blog/article/author', ['id' => $article.uid])}">
|
||||
<img src="{$article.user.avatar|default='/static/blog/img/avatar.jpg'}" alt="">
|
||||
{$article.user.nickname|default='佚名'}
|
||||
</a>
|
||||
<span class="sp">{$article.create_text}</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{/volist}
|
||||
</div>
|
||||
<div class="fb-pager">{$articles|raw}</div>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
{include file="index/_sidebar" /}
|
||||
</div>
|
||||
{/block}
|
||||
@@ -0,0 +1,52 @@
|
||||
{extend name="layout" /}
|
||||
{assign name="nav_active" value="category"/}
|
||||
{block name="title"}{$category.name|default='全部分类'} - {$siteConf.site_name|default='博客'}{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="fb-layout">
|
||||
<main class="fb-content">
|
||||
{if $category}
|
||||
<div class="fb-section-title"><h2>{$category.name}</h2></div>
|
||||
{if $articles->isEmpty()}
|
||||
<div class="fb-empty"><p>该分类下暂无文章。</p></div>
|
||||
{else}
|
||||
<div class="fb-post-list">
|
||||
{volist name="articles" id="article"}
|
||||
<article class="fb-post">
|
||||
{if $article.cover_image}
|
||||
<a class="thumb" href="{:url('blog/article/detail', ['id' => $article.id])}">
|
||||
<img src="{$article.cover_image}" alt="{$article.title}">
|
||||
</a>
|
||||
{/if}
|
||||
<div class="body">
|
||||
<span class="cat">{$article.category.name|default='默认'}</span>
|
||||
<h3><a href="{:url('blog/article/detail', ['id' => $article.id])}">{$article.title}</a></h3>
|
||||
<p class="summary">{$article.summary|default='(暂无描述)'}</p>
|
||||
<div class="meta">
|
||||
<a class="author" href="{:url('blog/article/author', ['id' => $article.uid])}">
|
||||
<img src="{$article.user.avatar|default='/static/blog/img/avatar.jpg'}" alt="">
|
||||
{$article.user.nickname|default='佚名'}
|
||||
</a>
|
||||
<span class="sp">{$article.create_text}</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{/volist}
|
||||
</div>
|
||||
<div class="fb-pager">{$articles|raw}</div>
|
||||
{/if}
|
||||
{else}
|
||||
<div class="fb-section-title"><h2>全部分类</h2></div>
|
||||
<div class="fb-card">
|
||||
<ul class="fb-catlist">
|
||||
{volist name="categories" id="c"}
|
||||
<li><a href="{:url('blog/category', ['id' => $c.id])}">{$c.name}<span class="cnt">{$c.card_count|default=0}</span></a></li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
{include file="index/_sidebar" /}
|
||||
</div>
|
||||
{/block}
|
||||
@@ -0,0 +1,48 @@
|
||||
<!-- 右侧栏:热门文章 / 分类 / 标签云 / 最新评论(前台共用 fb-aside 风格) -->
|
||||
<aside class="fb-aside">
|
||||
<div class="fb-widget">
|
||||
<h4>热门文章</h4>
|
||||
<ul class="fb-hot">
|
||||
{volist name="hotArticles" id="a"}
|
||||
<li>
|
||||
<span class="rank">{$i}</span>
|
||||
<a href="{:url('blog/article/detail', ['id' => $a.id])}">{$a.title}</a>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fb-widget">
|
||||
<h4>文章分类</h4>
|
||||
<ul class="fb-catlist">
|
||||
{volist name="categories" id="c"}
|
||||
<li><a href="{:url('blog/category/index', ['id' => $c.id])}">{$c.name}<span class="cnt">{$c.card_count|default=0}</span></a></li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fb-widget">
|
||||
<h4>标签云</h4>
|
||||
<div class="fb-tagcloud">
|
||||
{volist name="tags" id="t"}
|
||||
<a href="{:url('blog/tag/index', ['id' => $t.id])}">{$t.name}</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{notempty name="latestComments"}
|
||||
{if !$latestComments->isEmpty()}
|
||||
<div class="fb-widget">
|
||||
<h4>最新评论</h4>
|
||||
<ul class="fb-cmt">
|
||||
{volist name="latestComments" id="cmt"}
|
||||
<li>
|
||||
<span class="who">{$cmt.user.nickname|default='匿名'}</span>:
|
||||
<span class="txt">{$cmt.content}</span>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
{/notempty}
|
||||
</aside>
|
||||
@@ -0,0 +1,22 @@
|
||||
{extend name="layout" /}
|
||||
{assign name="nav_active" value="about"/}
|
||||
{block name="title"}关于我们 - {$siteConf.site_name|default='博客'}{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="fb-layout">
|
||||
<main class="fb-content">
|
||||
<div class="fb-page">
|
||||
<h3>关于我们</h3>
|
||||
<img src="/static/blog/img/portrait.jpg" alt="" style="width:96px;height:96px;border-radius:50%;margin:0 0 16px;border:3px solid var(--theme);">
|
||||
<p class="lead">TP-Blog 是一个基于 ThinkPHP 8 开发的现代化博客系统,致力于提供简洁、高效、安全的博客解决方案。</p>
|
||||
<h3>技术栈</h3>
|
||||
<div class="layui-progress layui-progress-big" lay-showpercent="true" style="margin-bottom:10px;"><em>PHP</em><div class="layui-progress-bar" lay-percent="80%"></div></div>
|
||||
<div class="layui-progress layui-progress-big" lay-showpercent="true" style="margin-bottom:10px;"><em>MySQL</em><div class="layui-progress-bar layui-bg-blue" lay-percent="70%"></div></div>
|
||||
<div class="layui-progress layui-progress-big" lay-showpercent="true"><em>Layui</em><div class="layui-progress-bar layui-bg-orange" lay-percent="90%"></div></div>
|
||||
<h3 style="margin-top:18px;">联系我们</h3>
|
||||
<p>邮箱:admin@example.com<br/>GitHub:https://github.com/yourname/tp-blog</p>
|
||||
</div>
|
||||
</main>
|
||||
{include file="index/_sidebar" /}
|
||||
</div>
|
||||
{/block}
|
||||
@@ -0,0 +1,47 @@
|
||||
{extend name="layout" /}
|
||||
{block name="title"}联系我们 - {$siteConf.site_name|default='博客'}{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="fb-layout">
|
||||
<main class="fb-content">
|
||||
<div class="fb-page">
|
||||
<h3>联系我们</h3>
|
||||
<p>邮箱:admin@example.com</p>
|
||||
<p>工作时间:周一至周五 9:00-18:00</p>
|
||||
<form class="layui-form" onsubmit="return false;">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">姓名</label>
|
||||
<div class="layui-input-block"><input type="text" name="name" required lay-verify="required" placeholder="请输入您的姓名" class="layui-input"></div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">邮箱</label>
|
||||
<div class="layui-input-block"><input type="text" name="email" required lay-verify="required|email" placeholder="请输入您的邮箱" class="layui-input"></div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">留言</label>
|
||||
<div class="layui-input-block"><textarea name="message" required lay-verify="required" placeholder="请输入您的留言" class="layui-textarea"></textarea></div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="fb-btn" lay-submit lay-filter="contactSubmit">提交留言</button>
|
||||
<button type="reset" class="fb-btn ghost">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
{include file="index/_sidebar" /}
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block name="script"}
|
||||
<script>
|
||||
layui.use(['form', 'layer'], function(){
|
||||
var form = layui.form, layer = layui.layer;
|
||||
form.on('submit(contactSubmit)', function(){
|
||||
layer.msg('感谢您的留言,我们会尽快与您联系!');
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
@@ -0,0 +1,124 @@
|
||||
{extend name="layout" /}
|
||||
{block name="title"}{$siteConf.site_name|default='博客'} - 首页{/block}
|
||||
|
||||
{block name="content"}
|
||||
<!-- Hero 推荐 -->
|
||||
{notempty name="recommendedArticles"}
|
||||
{if !$recommendedArticles->isEmpty()}
|
||||
<div class="fb-hero">
|
||||
<div class="fb-hero-grid">
|
||||
{volist name="recommendedArticles" id="rec" offset="0" length="1"}
|
||||
<a class="fb-hero-main" href="{:url('blog/article/detail', ['id' => $rec.id])}">
|
||||
<img src="{$rec.cover_image|default='/static/blog/img/pic.jpg'}" alt="{$rec.title}">
|
||||
<div class="fb-hero-cap">
|
||||
<span class="tag">{$rec.category.name|default='推荐'}</span>
|
||||
<h2>{$rec.title}</h2>
|
||||
</div>
|
||||
</a>
|
||||
{/volist}
|
||||
<div class="fb-hero-sub">
|
||||
{volist name="recommendedArticles" id="rec" offset="1" length="2"}
|
||||
<a class="fb-hero-sub-item" href="{:url('blog/article/detail', ['id' => $rec.id])}">
|
||||
<img src="{$rec.cover_image|default='/static/blog/img/code.jpg'}" alt="{$rec.title}">
|
||||
<div class="fb-hero-cap">
|
||||
<h3>{$rec.title}</h3>
|
||||
</div>
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/notempty}
|
||||
|
||||
<div class="fb-layout">
|
||||
<!-- 左:文章流 -->
|
||||
<main class="fb-content">
|
||||
<div class="fb-section-title"><h2>最新文章</h2></div>
|
||||
{if $articles->isEmpty()}
|
||||
<div class="fb-empty"><p>站点还没有发布文章,敬请期待。</p></div>
|
||||
{else}
|
||||
<div class="fb-post-list">
|
||||
{volist name="articles" id="article"}
|
||||
<article class="fb-post">
|
||||
<a class="thumb" href="{:url('blog/article/detail', ['id' => $article.id])}">
|
||||
<img src="{$article.cover_image|default='/static/blog/img/book.jpg'}" alt="{$article.title}">
|
||||
</a>
|
||||
<div class="body">
|
||||
<span class="cat">{$article.category.name|default='默认'}</span>
|
||||
<h3><a href="{:url('blog/article/detail', ['id' => $article.id])}">{$article.title}</a></h3>
|
||||
<p class="summary">{$article.summary|default='(暂无描述)'}</p>
|
||||
<div class="meta">
|
||||
<a class="author" href="{:url('blog/article/author', ['id' => $article.uid])}">
|
||||
<img src="{$article.user.avatar|default='/static/blog/img/avatar.jpg'}" alt="">
|
||||
{$article.user.nickname|default='佚名'}
|
||||
</a>
|
||||
<span><i class="layui-icon layui-icon-read"></i> {$article.view_count|default=0}</span>
|
||||
<span><i class="layui-icon layui-icon-praise"></i> {$article.like_count|default=0}</span>
|
||||
<span class="sp">{$article.create_text}</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{/volist}
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
<!-- 右:侧栏 -->
|
||||
<aside class="fb-aside">
|
||||
<div class="fb-widget">
|
||||
<div class="fb-stat">
|
||||
<div><div class="num">{$total_articles|default=0}</div><div class="lbl">文章</div></div>
|
||||
<div><div class="num">{$total_categories|default=0}</div><div class="lbl">分类</div></div>
|
||||
<div><div class="num">{$total_views|default=0}</div><div class="lbl">阅读</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="fb-widget">
|
||||
<h4>热门文章</h4>
|
||||
<ul class="fb-hot">
|
||||
{volist name="hotArticles" id="a"}
|
||||
<li>
|
||||
<span class="rank">{$i}</span>
|
||||
<a href="{:url('blog/article/detail', ['id' => $a.id])}">{$a.title}</a>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fb-widget">
|
||||
<h4>文章分类</h4>
|
||||
<ul class="fb-catlist">
|
||||
{volist name="categories" id="c"}
|
||||
<li><a href="{:url('blog/category', ['id' => $c.id])}">{$c.name}<span class="cnt">{$c.card_count|default=0}</span></a></li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fb-widget">
|
||||
<h4>标签云</h4>
|
||||
<div class="fb-tagcloud">
|
||||
{volist name="tags" id="t"}
|
||||
<a href="{:url('blog/tag', ['id' => $t.id])}">{$t.name}</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{notempty name="latestComments"}
|
||||
{if !$latestComments->isEmpty()}
|
||||
<div class="fb-widget">
|
||||
<h4>最新评论</h4>
|
||||
<ul class="fb-cmt">
|
||||
{volist name="latestComments" id="cmt"}
|
||||
<li>
|
||||
<span class="who">{$cmt.user.nickname|default='匿名'}</span>:
|
||||
<span class="txt">{$cmt.content}</span>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
{/notempty}
|
||||
</aside>
|
||||
</div>
|
||||
{/block}
|
||||
@@ -0,0 +1,35 @@
|
||||
{extend name="layout" /}
|
||||
{block name="title"}附近文章{/block}
|
||||
{block name="content"}
|
||||
<div class="main article">
|
||||
<div class="layui-tab layui-tab-brief">
|
||||
<ul class="layui-tab-title"><li class="layui-this">附近文章(半径 {$radius} km)</li></ul>
|
||||
</div>
|
||||
<div id="geo-tip" class="item"><div class="item-content"><h3>正在获取您的位置…</h3></div></div>
|
||||
{if empty($list)}
|
||||
<div class="item"><div class="item-content"><h3>附近暂无文章</h3><p>可在 URL 手动传 ?lat=&lng= 查看</p></div></div>
|
||||
{else}
|
||||
{volist name="list" id="item"}
|
||||
<div class="item">
|
||||
<div class="item-content">
|
||||
<h3><a href="{$item.url}">{$item.title}</a></h3>
|
||||
<p class="meta"><span>{$item.category}</span>{if $item.distance}<span>约 {$item.distance} km</span>{/if}</p>
|
||||
</div>
|
||||
</div>
|
||||
{/volist}
|
||||
{/if}
|
||||
</div>
|
||||
<script>
|
||||
(function(){
|
||||
var tip = document.getElementById('geo-tip');
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(function(p){
|
||||
if (tip) tip.style.display='none';
|
||||
window.location.href = '/blog/nearby?lat='+p.coords.latitude+'&lng='+p.coords.longitude+'&radius=10';
|
||||
}, function(){ if (tip) tip.querySelector('h3').textContent='获取位置失败,可在 URL 手动传 ?lat=&lng='; });
|
||||
} else if (tip) {
|
||||
tip.querySelector('h3').textContent='浏览器不支持定位,请在 URL 手动传 ?lat=&lng=';
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
{/block}
|
||||
@@ -0,0 +1,33 @@
|
||||
{extend name="layout" /}
|
||||
{block name="title"}搜索:{$keyword} - 静谧博客{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="main article">
|
||||
<div class="layui-tab layui-tab-brief">
|
||||
<ul class="layui-tab-title"><li class="layui-this">搜索:{$keyword}</li></ul>
|
||||
</div>
|
||||
{if $articles->isEmpty()}
|
||||
<div class="item"><div class="item-content"><h3>没有找到相关文章</h3><p>尝试更换关键词搜索</p></div></div>
|
||||
{else}
|
||||
{volist name="articles" id="article"}
|
||||
<div class="item">
|
||||
{if $article.cover_image}<img src="{$article.cover_image}" alt="{$article.title}">{/if}
|
||||
<div class="item-content">
|
||||
<h3><a href="{:url('blog/article/detail', ['id' => $article.id])}">{$article.title}</a></h3>
|
||||
<span class="Subtitle">{$article.category.name|default='默认'}</span><br/>
|
||||
<p>{$article.summary}</p>
|
||||
<a href="{:url('blog/article/detail', ['id' => $article.id])}"><button class="layui-btn">阅读全文</button></a>
|
||||
</div>
|
||||
<div class="date-box">
|
||||
<div class="date">
|
||||
<h4>{:date('d', strtotime($article.create_text))}</h4>
|
||||
<span>{:date('Y/m', strtotime($article.create_text))}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/volist}
|
||||
<div id="demo1">{$articles|raw}</div>
|
||||
{/if}
|
||||
</div>
|
||||
{include file="index/_sidebar" /}
|
||||
{/block}
|
||||
@@ -0,0 +1,179 @@
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{block name="title"}{$siteConf.site_name|default='博客'}{/block}</title>
|
||||
<meta name="description" content="{$siteConf.site_description|default=''}" />
|
||||
<link rel="stylesheet" href="/assets/layui/css/layui.css">
|
||||
<link rel="stylesheet" href="/static/blog/css/theme.css">
|
||||
<style>
|
||||
/* 主题色由后台「基本设置」配置,注入 CSS 变量驱动整站配色 */
|
||||
:root { --theme: {$theme_color|default='#2d6cdf'}; }
|
||||
</style>
|
||||
{block name="style"}{/block}
|
||||
</head>
|
||||
<body class="has-tab">
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="fb-nav">
|
||||
<div class="inner">
|
||||
<a href="{:url('blog/index/index')}" class="logo">{$siteConf.site_name|default='博客'}</a>
|
||||
<nav class="menu">
|
||||
<a href="{:url('blog/index/index')}" {if $nav_active=='index'}class="active"{/if}>首页</a>
|
||||
<a href="{:url('category/index')}" {if $nav_active=='category'}class="active"{/if}>分类</a>
|
||||
<a href="{:url('blog/tag/index')}" {if $nav_active=='tag'}class="active"{/if}>标签</a>
|
||||
<a href="{:url('blog/index/about')}" {if $nav_active=='about'}class="active"{/if}>关于</a>
|
||||
</nav>
|
||||
<form class="search" action="{:url('blog/search/index')}" method="get">
|
||||
<input type="text" name="keyword" placeholder="搜索文章..." autocomplete="off">
|
||||
<button type="submit"><i class="layui-icon layui-icon-search"></i></button>
|
||||
</form>
|
||||
<div class="user">
|
||||
{if $is_login}
|
||||
<a href="{:url('blog/article/author', ['id' => $current_uid])}">我的博客</a>
|
||||
<a href="{:url('/user/index/index')}">中心</a>
|
||||
{else}
|
||||
<a href="{:url('auth/login')}">登录</a>
|
||||
{/if}
|
||||
</div>
|
||||
<button class="hamburger" id="fbMenuBtn"><i class="layui-icon layui-icon-more-vertical"></i></button>
|
||||
</div>
|
||||
<div class="drawer" id="fbDrawer">
|
||||
<a href="{:url('index/index')}">首页</a>
|
||||
<a href="{:url('category')}">分类</a>
|
||||
<a href="{:url('/tag')}">标签</a>
|
||||
<a href="{:url('/index/about')}">关于</a>
|
||||
<div class="user">
|
||||
{if $is_login}
|
||||
<a href="{:url('/article/author', ['id' => $current_uid])}">我的博客</a>
|
||||
<a href="{:url('user/index')}">个人中心</a>
|
||||
{else}
|
||||
<a href="{:url('auth/login')}">登录</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主体内容 -->
|
||||
<div class="fb-main">
|
||||
<div class="fb-wrap">
|
||||
{block name="content"}{/block}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 移动端底部 Tab 导航(精简:只保留高频入口,分类/标签移入顶部汉堡菜单) -->
|
||||
<div class="fb-tabbar">
|
||||
<a href="{:url('/blog/index/index')}" {if $nav_active=='index'}class="active"{/if}><i class="layui-icon layui-icon-home"></i>首页</a>
|
||||
{if $is_login}
|
||||
<a href="{:url('/blog/article/author', ['id' => $current_uid])}"><i class="layui-icon layui-icon-username"></i>我的</a>
|
||||
{else}
|
||||
<a href="{:url('auth/login')}"><i class="layui-icon layui-icon-username"></i>我的</a>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<footer class="fb-footer">
|
||||
<p>© {:date('Y')} {$siteConf.site_name|default='博客'}. All Rights Reserved.</p>
|
||||
</footer>
|
||||
|
||||
<script src="/assets/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.use(['element', 'layer', 'form'], function(){
|
||||
var element = layui.element, layer = layui.layer, form = layui.form;
|
||||
window.layer = layer; window.layui = layui;
|
||||
var drawer = document.getElementById('fbDrawer');
|
||||
document.getElementById('fbMenuBtn').addEventListener('click', function(e){
|
||||
e.stopPropagation();
|
||||
drawer.classList.toggle('open');
|
||||
});
|
||||
document.addEventListener('click', function(e){
|
||||
if (!drawer.contains(e.target) && e.target.id !== 'fbMenuBtn' && !document.getElementById('fbMenuBtn').contains(e.target)) {
|
||||
drawer.classList.remove('open');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- 全局登录弹窗(前台通用) -->
|
||||
<div id="globalLoginBox" style="display:none; padding: 20px 24px;">
|
||||
<form class="layui-form" id="globalLoginForm" lay-filter="globalLoginForm">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">用户名</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="username" lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" name="password" lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">验证码</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-row layui-col-space10">
|
||||
<div class="layui-col-xs7">
|
||||
<input type="text" name="captcha" lay-verify="required" placeholder="图形验证码" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-col-xs5">
|
||||
<img id="globalLoginCaptcha" src="{:url('user/ajax/verify')}" alt="点击刷新验证码" title="点击刷新验证码" style="height:38px;cursor:pointer;border-radius:2px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="globalLoginSubmit">登 录</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重 置</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
layui.use(['layer', 'form', 'jquery'], function(){
|
||||
var layer = layui.layer, form = layui.form, $ = layui.$;
|
||||
var globalLoginIndex = null;
|
||||
function refreshGlobalCaptcha(){
|
||||
$('#globalLoginCaptcha').attr('src', '{:url(\'member/ajax/verify\')}?t=' + Date.now());
|
||||
}
|
||||
$('#globalLoginCaptcha').on('click', refreshGlobalCaptcha);
|
||||
window.openLogin = function(cb){
|
||||
globalLoginIndex = layer.open({
|
||||
type: 1, title: '用户登录', area: ['480px', 'auto'],
|
||||
content: $('#globalLoginBox'),
|
||||
success: function(){
|
||||
refreshGlobalCaptcha();
|
||||
$('#globalLoginForm')[0].reset();
|
||||
if (typeof cb === 'function') { window.__loginCb = cb; }
|
||||
}
|
||||
});
|
||||
};
|
||||
form.on('submit(globalLoginSubmit)', function(data){
|
||||
$.post('{:url(\'member/login/save\')}', data.field, function(res){
|
||||
if (res.code === 0) {
|
||||
layer.msg(res.message || '登录成功', {icon: 1});
|
||||
setTimeout(function(){
|
||||
if (globalLoginIndex) { layer.close(globalLoginIndex); }
|
||||
if (typeof window.__loginCb === 'function') {
|
||||
var cb = window.__loginCb; window.__loginCb = null; cb();
|
||||
} else { location.reload(); }
|
||||
}, 600);
|
||||
} else {
|
||||
layer.msg(res.message || '登录失败', {icon: 2});
|
||||
refreshGlobalCaptcha();
|
||||
}
|
||||
}, 'json');
|
||||
return false;
|
||||
});
|
||||
$(document).on('click', 'a[href*="auth/login"], a[href*="member/login"]', function(e){
|
||||
if ($(this).attr('target') === '_blank') { return; }
|
||||
e.preventDefault();
|
||||
window.openLogin();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{block name="script"}{/block}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,36 @@
|
||||
{extend name="layout" /}
|
||||
{block name="title"}搜索:{$keyword} - {$siteConf.site_name|default='博客'}{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="fb-layout">
|
||||
<main class="fb-content">
|
||||
<div class="fb-section-title"><h2>搜索:{$keyword}</h2></div>
|
||||
{if $articles->isEmpty()}
|
||||
<div class="fb-empty"><p>没有找到相关文章,尝试更换关键词搜索。</p></div>
|
||||
{else}
|
||||
<div class="fb-post-list">
|
||||
{volist name="articles" id="article"}
|
||||
<article class="fb-post">
|
||||
{if $article.cover_image}
|
||||
<a class="thumb" href="{:url('blog/article/detail', ['id' => $article.id])}">
|
||||
<img src="{$article.cover_image}" alt="{$article.title}">
|
||||
</a>
|
||||
{/if}
|
||||
<div class="body">
|
||||
<span class="cat">{$article.category.name|default='默认'}</span>
|
||||
<h3><a href="{:url('blog/article/detail', ['id' => $article.id])}">{$article.title}</a></h3>
|
||||
<p class="summary">{$article.summary|default='(暂无描述)'}</p>
|
||||
<div class="meta">
|
||||
<span class="sp">{$article.create_text}</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{/volist}
|
||||
</div>
|
||||
<div class="fb-pager">{$articles|raw}</div>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
{include file="index/_sidebar" /}
|
||||
</div>
|
||||
{/block}
|
||||
@@ -0,0 +1,52 @@
|
||||
{extend name="layout" /}
|
||||
{assign name="nav_active" value="tag"/}
|
||||
{block name="title"}{$tag.name|default='全部标签'} - {$siteConf.site_name|default='博客'}{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="fb-layout">
|
||||
<main class="fb-content">
|
||||
{if $tag}
|
||||
<div class="fb-section-title"><h2>标签:{$tag.name}</h2></div>
|
||||
{if $articles->isEmpty()}
|
||||
<div class="fb-empty"><p>该标签下暂无文章。</p></div>
|
||||
{else}
|
||||
<div class="fb-post-list">
|
||||
{volist name="articles" id="article"}
|
||||
<article class="fb-post">
|
||||
{if $article.cover_image}
|
||||
<a class="thumb" href="{:url('blog/article/detail', ['id' => $article.id])}">
|
||||
<img src="{$article.cover_image}" alt="{$article.title}">
|
||||
</a>
|
||||
{/if}
|
||||
<div class="body">
|
||||
<span class="cat">{$article.category.name|default='默认'}</span>
|
||||
<h3><a href="{:url('blog/article/detail', ['id' => $article.id])}">{$article.title}</a></h3>
|
||||
<p class="summary">{$article.summary|default='(暂无描述)'}</p>
|
||||
<div class="meta">
|
||||
<a class="author" href="{:url('blog/article/author', ['id' => $article.uid])}">
|
||||
<img src="{$article.user.avatar|default='/static/blog/img/avatar.jpg'}" alt="">
|
||||
{$article.user.nickname|default='佚名'}
|
||||
</a>
|
||||
<span class="sp">{$article.create_text}</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{/volist}
|
||||
</div>
|
||||
<div class="fb-pager">{$articles|raw}</div>
|
||||
{/if}
|
||||
{else}
|
||||
<div class="fb-section-title"><h2>全部标签</h2></div>
|
||||
<div class="fb-card">
|
||||
<div class="fb-tagcloud">
|
||||
{volist name="tags" id="t"}
|
||||
<a href="{:url('blog/tag', ['id' => $t.id])}">{$t.name}</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
{include file="index/_sidebar" /}
|
||||
</div>
|
||||
{/block}
|
||||
Reference in New Issue
Block a user