修复置顶文章问题
This commit is contained in:
浪子 2025-05-24 18:55:25 +08:00
parent a42f5f41ca
commit 1f535bb9d6
3 changed files with 75 additions and 33 deletions

View File

@ -6,8 +6,11 @@
## 更新日志 & 预览
### 0.7.2
- 优化页面加载速度,自动裁切封面,并压缩为`webp`格式,并保存在主题目录`assets`-`images`-`covers`下,使用前必须开启`php`的`GD拓展`和主题目录的写入权限
- 修复了置顶文章和翻页的问题
### 0.7.1
@ -40,7 +43,7 @@
[预览](https://www.imsun.org/)
[预览](https://blog.imsun.org/)
https://www.imsun.org/archives/1640.html

View File

@ -37,7 +37,7 @@
<div class="content">
<h2 class="post--title">
<a href="<?php $this->permalink() ?>">
<?php $this->title() ?>
<?php $this->title() ?><?php if (isset($this->isSticky) && $this->isSticky): ?><?php echo $this->stickyHtml; ?><?php endif; ?>
<?php if((time() - $this->created) < 60*60*24*3): ?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
class="icon--sticky" stroke="currentColor" stroke-width="2" stroke-linecap="round"

View File

@ -1,23 +1,25 @@
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php
/** 文章置顶 */
$sticky = $this->options->sticky; // 置顶的文章id多个用|隔开
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit;
$sticky = $this->options->sticky;
$db = Typecho_Db::get();
$pageSize = $this->options->pageSize;
if ($sticky && !empty(trim($sticky))) {
$sticky_cids = array_filter(explode('|', $sticky)); // 分割文本并过滤空值
$sticky_cids = array_filter(explode('|', $sticky));
if (!empty($sticky_cids)) {
$sticky_html = " <span class='sticky--post'> 置顶 </span> "; // 置顶标题的 html
// 清空原有文章的队列
$sticky_html = " <span class='sticky--post'> 置顶 </span>";
// 保存原始对象状态
$originalRows = $this->row;
$originalStack = $this->stack;
$originalLength = $this->length;
$totalOriginal = $this->getTotal();
// 重置当前对象状态
$this->row = [];
$this->stack = [];
$this->length = 0;
// 获取总数,并排除置顶文章数量
$this->length = 0;
// 关键修改:不再减少总文章数
// 保持原始总数,这样分页逻辑不会受影响
// $this->setTotal(max($totalOriginal - $stickyCount, 0));
if (isset($this->currentPage) && $this->currentPage == 1) {
$totalOriginal = $this->getTotal();
$stickyCount = count($sticky_cids);
$this->setTotal(max($totalOriginal - $stickyCount, 0));
// 构建置顶文章的查询
// 查询置顶文章
$selectSticky = $this->select()->where('type = ?', 'post');
foreach ($sticky_cids as $i => $cid) {
if ($i == 0)
@ -25,29 +27,65 @@ if ($sticky && !empty(trim($sticky))) {
else
$selectSticky->orWhere('cid = ?', $cid);
}
// 获取置顶文章
$stickyPosts = $db->fetchAll($selectSticky);
// 压入置顶文章到文章队列
// 添加置顶文章到结果集
foreach ($stickyPosts as &$stickyPost) {
$stickyPost['title'] .= $sticky_html;
$stickyPost['isSticky'] = true;
$stickyPost['stickyHtml'] = $sticky_html;
$this->push($stickyPost);
}
// 计算当前页应显示的普通文章数量
$standardPageSize = $pageSize - count($stickyPosts);
// 确保第一页不会显示太多文章
if ($standardPageSize <= 0) {
$standardPageSize = 0; // 如果置顶文章已经填满或超过一页,则不显示普通文章
}
} else {
// 非第一页显示正常数量的文章
$standardPageSize = $pageSize;
}
// 构建正常文章查询,排除置顶文章
$selectNormal = $this->select()
->where('type = ?', 'post')
->where('status = ?', 'publish')
->where('created < ?', time())
->order('created', Typecho_Db::SORT_DESC)
->page(isset($this->currentPage) ? $this->currentPage : 1, $standardPageSize);
foreach ($sticky_cids as $cid) {
$selectNormal->where('table.contents.cid != ?', $cid);
}
// 查询普通文章
if ($this->currentPage == 1) {
// 第一页需要排除置顶文章并限制数量
$selectNormal = $this->select()
->where('type = ?', 'post')
->where('status = ?', 'publish')
->where('created < ?', time());
// 排除所有置顶文章
foreach ($sticky_cids as $cid) {
$selectNormal->where('table.contents.cid != ?', $cid);
}
$selectNormal->order('created', Typecho_Db::SORT_DESC)
->limit($standardPageSize)
->offset(0);
} else {
// 非第一页的查询
// 计算正确的偏移量:(当前页码-1) * 每页数量 - 置顶文章数
// 这样可以确保不会漏掉文章
$offset = ($this->currentPage - 1) * $pageSize - count($sticky_cids);
$offset = max($offset, 0); // 确保偏移量不为负
$selectNormal = $this->select()
->where('type = ?', 'post')
->where('status = ?', 'publish')
->where('created < ?', time());
// 排除所有置顶文章
foreach ($sticky_cids as $cid) {
$selectNormal->where('table.contents.cid != ?', $cid);
}
$selectNormal->order('created', Typecho_Db::SORT_DESC)
->limit($pageSize)
->offset($offset);
}
} else {
// 如果sticky_cids为空使用默认查询
// 没有有效的置顶文章ID正常查询
$selectNormal = $this->select()
->where('type = ?', 'post')
->where('status = ?', 'publish')
@ -56,7 +94,7 @@ if ($sticky && !empty(trim($sticky))) {
->page(isset($this->currentPage) ? $this->currentPage : 1, $pageSize);
}
} else {
// 如果没有置顶文章,使用默认查询
// 没有设置置顶文章,正常查询
$selectNormal = $this->select()
->where('type = ?', 'post')
->where('status = ?', 'publish')
@ -64,21 +102,22 @@ if ($sticky && !empty(trim($sticky))) {
->order('created', Typecho_Db::SORT_DESC)
->page(isset($this->currentPage) ? $this->currentPage : 1, $pageSize);
}
// 登录用户显示私密文章
// 添加私有文章查询条件
if ($this->user->hasLogin()) {
$uid = $this->user->uid;
if ($uid) {
$selectNormal->orWhere('authorId = ? AND status = ?', $uid, 'private');
}
}
// 获取普通文章
$normalPosts = $db->fetchAll($selectNormal);
// 如果之前没有清空队列(没有置顶文章的情况),现在清空
// 如果没有置顶文章或在前面的代码中没有重置对象状态,则在这里重置
if (empty($sticky) || empty(trim($sticky)) || empty($sticky_cids)) {
$this->row = [];
$this->stack = [];
$this->length = 0;
}
// 压入正常文章到文章队列
// 将普通文章添加到结果集
foreach ($normalPosts as $normalPost) {
$this->push($normalPost);
}