tags: 教程,Joe主题,付费可见,游客支付,一键修复
category: 技术随笔
status: publish
content:
1 问题简述
Joe1.4自带「付费可见」→游客支付成功→仍显示灰色遮罩,刷新也不出来。
2 修复思路(30秒看懂)
①支付时把游客IP写进订单表ip字段
②文章渲染时用当前IP查订单status=1
③命中→直接输出隐藏内容,无需登录
3 一键修复代码(复制即用)
3.1 先执行SQL(这里1.4版本不需要)
ALTER TABLE `typecho_orders` ADD `ip` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '游客支付公网IP' AFTER `user_id`;3.2 全局IP函数(粘贴到function.php顶部)
3.3 替换markdown_hide函数
function markdown_hide($content, $post, $login)
{
// 如果内容中不存在 {hide} 标签,直接返回原内容
if (strpos($content, '{hide') === false) return $content;
// 初始化变量:调用全局的get_visitor_ip()
$showContent = false;
$payment = null;
$visitorIp = get_visitor_ip(); // 直接调用全局函数,无报错
$currentCid = $post->cid;
$db = \Typecho\Db::get();
$prefix = $db->getPrefix();
// 1. 登录用户:用user_id匹配订单
if ($login && isset($GLOBALS['JOE_USER']->uid)) {
$payment = Db::name('orders')->where([
'user_id' => $GLOBALS['JOE_USER']->uid,
'status' => 1,
'content_cid' => $currentCid
])->find();
$showContent = !empty($payment);
}
// 2. 游客:用IP匹配订单(核心修复逻辑)
else {
$payment = Db::name('orders')->where([
'ip' => $visitorIp,
'status' => 1,
'content_cid' => $currentCid
])->find();
$showContent = !empty($payment);
}
// 原有登录/评论可见逻辑:兼容付费优先,非付费时走原逻辑
if ($post->fields->hide != 'pay' && !$showContent) {
if ($post->fields->hide == 'login') {
$showContent = $login;
} else {
$userEmail = $login && isset($GLOBALS['JOE_USER']->mail) ? $GLOBALS['JOE_USER']->mail : $post->remember('mail', true);
$comment = !empty($userEmail) ? Db::name('comments')->where([
'cid' => $currentCid,
'mail' => $userEmail
])->find() : null;
$showContent = !empty($comment);
}
}
// 隐藏内容标签替换:兼容所有{hide*}格式,无多余字符限制
if ($showContent) {
$content = preg_replace('/\{hide[^}]*\}/i', '', $content);
$content = preg_replace('/\{\/hide\}/i', '', $content);
} else {
if (strpos($content, '<br>{hide') !== false || strpos($content, '<p>{hide') !== false) {
$content = preg_replace('/\<br\>\{hide[^}]*\}([\s\S]*?)\{\/hide\}/i', '<br><joe-hide style="display:block"></joe-hide>', $content);
$content = preg_replace('/\<p\>\{hide[^}]*\}([\s\S]*?)\{\/hide\}/i', '<p><joe-hide style="display:block"></joe-hide>', $content);
}
$content = preg_replace('/\{hide[^}]*\}([\s\S]*?){\/hide}/i', '<joe-hide style="display:inline"></joe-hide>', $content);
}
// 付费框显示逻辑:非爬虫才显示,区分付费/免费资源
if ($post->fields->hide == 'pay' && !detectSpider()) {
if ($post->fields->price > 0) {
$pay_box_position = $showContent ? _payPurchased($post, $payment) : _payBox($post);
} else {
$userEmail = $login && isset($GLOBALS['JOE_USER']->mail) ? $GLOBALS['JOE_USER']->mail : $post->remember('mail', true);
$comment = !empty($userEmail) ? Db::name('comments')->where([
'cid' => $currentCid,
'mail' => $userEmail
])->find() : null;
$pay_box_position = _payFreeResources($post, $comment);
}
if (!$post->fields->pay_box_position || $post->fields->pay_box_position == 'top') $content = $pay_box_position . $content;
if ($post->fields->pay_box_position == 'bottom') $content = $content . $pay_box_position;
}
return $content;
}