你想要在迅睿CMS的内容模块中实现付费阅读功能,也就是将文章的部分内容隐藏,用户付费后才能查看完整内容。这是内容变现的常见需求,我会为你提供一套完整、可落地的实现方案。 ## 实现思路 实现付费阅读的核心逻辑分为三步: 1. 在内容模型中新增字段,用于存储需要付费查看的隐藏内容 2. 在前台模板中做逻辑判断:未付费用户只显示免费内容,付费用户显示全部内容 3. 对接迅睿CMS的支付接口,完成付费行为的验证和权限控制 ## 具体实现步骤 ### 1. 新增内容模型字段 首先需要在你的内容模型中添加专门存储付费内容的字段: 1. 登录迅睿CMS后台,进入【内容】→【模型管理】 2. 编辑你要添加付费阅读的模型(如文章模型) 3. 添加新字段: - 字段标识:`pay_content` - 字段名称:`付费内容` - 字段类型:`富文本编辑器` - 其他设置保持默认,保存字段 ### 2. 模板文件修改(核心) 找到你网站前台的内容详情页模板(通常在 `template/你的模板名/show.html`),替换原有内容展示部分为以下代码: ```php {extend name="public/base" /} {block name="main"} <div class="article-detail"> <!-- 文章标题 --> <h1>{$title}</h1> <!-- 发布信息等 --> <div class="article-meta"> 发布时间:{$updatetime|date='Y-m-d H:i'} | 作者:{$author} </div> <!-- 免费内容区域 --> <div class="article-free-content"> {$content} </div> <!-- 付费内容区域 --> {php} // 获取当前用户ID和文章ID $user_id = dr_get_member_id(); $id = $id; // 文章ID $pay_price = 10; // 付费金额(元),也可以设置为字段,从后台配置 // 检查用户是否已购买该文章 $is_paid = false; if ($user_id) { // 查询订单表,判断是否有已支付的记录 $order = db('pay_order')->where([ 'uid' => $user_id, 'module' => 'content', 'action' => 'read', 'tid' => $id, 'status' => 1 // 1表示已支付 ])->find(); $is_paid = !empty($order); } {/php} {if $is_paid} <!-- 已付费用户显示完整内容 --> <div class="article-pay-content"> {$pay_content} </div> {else} <!-- 未付费用户显示付费提示 --> <div class="article-pay-tips"> <div class="pay-mask"> <div class="pay-box"> <h3>该内容需要付费阅读</h3> <p>付费金额:<span class="price">¥{$pay_price}</span></p> <button id="pay-btn" class="btn-pay" data-id="{$id}" data-price="{$pay_price}">立即支付</button> <p class="tips">支付后即可查看完整内容,永久有效</p> </div> </div> </div> {/if} </div> <!-- 支付弹窗(可以用layer等弹窗插件) --> <div id="pay-modal" style="display:none;"> <div class="pay-method"> <p>请选择支付方式:</p> <div class="pay-type"> <label><input type="radio" name="pay_type" value="wechat" checked> 微信支付</label> <label><input type="radio" name="pay_type" value="alipay"> 支付宝</label> </div> <button id="confirm-pay" class="btn-confirm">确认支付</button> </div> </div> <!-- JS支付逻辑 --> <script src="{$public_path}static/js/jquery.min.js"></script> <script src="{$public_path}static/plugin/layer/layer.js"></script> <script> $(function() { // 点击支付按钮 $('#pay-btn').click(function() { var id = $(this).data('id'); var price = $(this).data('price'); // 检查是否登录 {if !$user_id} layer.msg('请先登录后再进行支付', {icon: 2}); setTimeout(function() { _window.location.href = '{:url("member/login/index")}?redirect=' + encodeURIComponent_(window.location.href); }, 1500); return false; {/if} // 显示支付弹窗 layer.open({ type: 1, title: '支付确认', content: $('#pay-modal'), area: ['300px', '200px'], btn: false, success: function(layero, index) { // 确认支付 $('#confirm-pay').click(function() { var pay_type = $('input[name="pay_type"]:checked').val(); // 发起支付请求 $.ajax({ url: '{:url("pay/content_pay")}', type: 'post', data: { id: id, price: price, pay_type: pay_type, _token: '{:dr_csrf_token()}' }, dataType: 'json', success: function(res) { if (res.code == 1) { // 跳转到支付页面或生成支付二维码 if (res.data.pay_url) { _window.location.href = res.data.pay_url; } else if (res.data.qrcode) { // 显示二维码 layer.open({ type: 1, title: '扫码支付', content: '<div style="padding:20px;text-align:center;"><img src="'+res.data.qrcode+'" alt="支付二维码"><p>请使用'+(pay_type=='wechat'?'微信':'支付宝')+'扫码支付</p></div>', area: ['300px', '350px'], btn: ['支付完成'], yes: function(index) { // 检查支付状态 checkPayStatus(id, index); } }); } } else { layer.msg(res.msg, {icon: 2}); } }, error: function() { layer.msg('支付请求失败,请重试', {icon: 2}); } }); }); } }); }); // 检查支付状态 function checkPayStatus(id, layerIndex) { $.ajax({ url: '{:url("pay/check_pay")}', type: 'post', data: { id: id, _token: '{:dr_csrf_token()}' }, dataType: 'json', success: function(res) { if (res.code == 1) { layer.msg('支付成功!正在刷新页面...', {icon: 1}); setTimeout(function() { _window.location.reload(); }, 1500); } else { layer.msg('尚未支付,请完成支付后再点击', {icon: 2}); } } }); } }); </script> {/block} ``` ### 3. 后台控制器开发 在迅睿CMS中创建支付相关的控制器(`application/pay/controller/ContentPay.php`): ```php <?php namespace app\pay\controller; use think\Controller; use think\Db; class ContentPay extends Controller { // 发起内容支付 public function index() { if (!$this->request->isPost()) { return json(['code' => 0, 'msg' => '非法请求']); } $id = input('id/d', 0); $price = input('price/f', 0); $pay_type = input('pay_type/s', 'wechat'); // 验证参数 if (!$id || $price <= 0) { return json(['code' => 0, 'msg' => '参数错误']); } // 获取当前用户ID $uid = session('member.id', 0); if (!$uid) { return json(['code' => 0, 'msg' => '请先登录']); } // 检查是否已购买 $exists = Db::name('pay_order')->where([ 'uid' => $uid, 'module' => 'content', 'action' => 'read', 'tid' => $id, 'status' => 1 ])->find(); if ($exists) { return json(['code' => 0, 'msg' => '你已购买该内容,无需重复购买']); } // 创建订单 $order_sn = 'CONT' . date('YmdHis') . rand(1000, 9999); $order_id = Db::name('pay_order')->insertGetId([ 'order_sn' => $order_sn, 'uid' => $uid, 'module' => 'content', 'action' => 'read', 'tid' => $id, 'money' => $price, 'pay_type' => $pay_type, 'status' => 0, // 0-未支付 1-已支付 'create_time' => time(), 'update_time' => time() ]); if (!$order_id) { return json(['code' => 0, 'msg' => '创建订单失败']); } // 调用迅睿支付接口(这里需要对接你实际的支付通道) // 以下为示例代码,需根据你使用的支付插件调整 $pay_config = get_pay_config($pay_type); // 获取支付配置 $pay_data = [ 'out_trade_no' => $order_sn, 'total_amount' => $price, 'subject' => '文章付费阅读-' . $id, 'return_url' => url('pay/ContentPay/notify', '', true, true), 'notify_url' => url('pay/ContentPay/callback', '', true, true), ]; // 生成支付链接/二维码 $pay_result = create_pay_order($pay_type, $pay_data, $pay_config); if ($pay_result['code'] == 1) { return json([ 'code' => 1, 'msg' => '创建支付订单成功', 'data' => [ 'pay_url' => $pay_result['data']['pay_url'] ?? '', 'qrcode' => $pay_result['data']['qrcode'] ?? '' ] ]); } else { return json(['code' => 0, 'msg' => $pay_result['msg']]); } } // 检查支付状态 public function checkPay() { $id = input('id/d', 0); $uid = session('member.id', 0); if (!$id || !$uid) { return json(['code' => 0, 'msg' => '参数错误']); } $order = Db::name('pay_order')->where([ 'uid' => $uid, 'module' => 'content', 'action' => 'read', 'tid' => $id, 'status' => 1 ])->find(); if ($order) { return json(['code' => 1, 'msg' => '支付成功']); } else { return json(['code' => 0, 'msg' => '未支付']); } } // 支付回调处理 public function callback() { // 接收支付平台的回调数据 $data = file_get_contents('php://input'); // 验证签名(根据支付平台要求实现) $verify = verify_pay_sign($data); if (!$verify) { exit('fail'); } // 解析回调数据 $pay_data = parse_pay_callback($data); $order_sn = $pay_data['out_trade_no']; // 更新订单状态 Db::name('pay_order')->where('order_sn', $order_sn)->update([ 'status' => 1, 'pay_time' => time(), 'trade_no' => $pay_data['trade_no'] ?? '', 'update_time' => time() ]); exit('success'); } } ``` ### 4. 数据库表创建 创建支付订单表(可通过迅睿CMS后台的数据库管理执行): ```sql CREATE TABLE `dr_pay_order` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `order_sn` varchar(32) NOT NULL COMMENT '订单编号', `uid` int(11) NOT NULL COMMENT '用户ID', `module` varchar(32) NOT NULL COMMENT '模块名称', `action` varchar(32) NOT NULL COMMENT '操作类型', `tid` int(11) NOT NULL COMMENT '目标ID(文章ID)', `money` decimal(10,2) NOT NULL COMMENT '支付金额', `pay_type` varchar(16) NOT NULL COMMENT '支付方式', `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0-未支付 1-已支付', `trade_no` varchar(64) DEFAULT '' COMMENT '支付平台订单号', `pay_time` int(11) DEFAULT '0' COMMENT '支付时间', `create_time` int(11) NOT NULL COMMENT '创建时间', `update_time` int(11) NOT NULL COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `order_sn` (`order_sn`), KEY `uid` (`uid`), KEY `tid` (`tid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='内容付费订单表'; ``` ## 补充说明 1. **支付接口对接**:上述代码中的 `create_pay_order`、`verify_pay_sign` 等函数需要你根据实际使用的支付插件(微信支付、支付宝)进行实现 2. **价格灵活配置**:可以将付费金额也做成内容模型的字段,在后台发布文章时单独设置每篇文章的价格 3. **权限控制**:除了文章详情页,还需要确保用户无法通过其他途径(如接口)获取付费内容 4. **样式美化**:示例中的CSS样式需要你根据自己的网站风格进行调整 5. **权限验证**:建议在控制器中也增加权限验证,防止用户直接访问付费内容接口 ### 总结 1. 核心是在内容模型中新增`pay_content`字段存储付费内容,通过模板判断用户付费状态来展示不同内容 2. 需要创建支付订单表记录用户的付费行为,对接支付接口完成交易流程 3. 关键逻辑是:未付费显示免费内容+付费提示,已付费显示完整内容,支付成功后更新订单状态并刷新页面 这套方案是基于迅睿CMS的标准开发规范实现的,兼容性好,也方便后续扩展(如会员免费、按次付费、按时间付费等)。
文章声明:以上内容(如有图片或视频亦包括在内)除非注明,否则均为 爱分享原创文章,转载或复制请以超链接形式并注明出处。 地址:/index.php?c=show&id=25