半小时给 dedecms 增加会员下载授信额度功能

0、缘起

客户有个 dede 制作的行业网站,提供相关资料下载,作为主要盈利手段的金币充值业务需要接入微信、支付宝等支付方式。但是如果每笔都单独进行支付的话手续费会比较高,因此采用充值某种会员来进行的话会更划算。
dede 本身提供了会员产品,可以通过购买会员产品来达到不同的用户级别。那么我们只需要给相应的用户等级设置对应的下载配额就可以控制这一等级的免费额度了。

业务逻辑上客户要求,用户购买的等级可以每月得到规定的授信次数,用完后继续和正常情况一样充值金币下载。到下个月又重新授信。

1、设置表结构

1.1、用户等级表增加 每月下载授信次数 字段:

ALTER TABLE `dede_arcrank` ADD `download_credit` INT(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '每月下载授信次数' AFTER `scores`;

1.2、 用户表增加当前月授信次数、更新月份、已用次数等字段


ALTER TABLE `dede_member`
ADD `download_month` INT UNSIGNED NOT NULL DEFAULT '0' COMMENT '下载授信月份' AFTER `checkmail`,
ADD `download_counter` INT UNSIGNED NOT NULL DEFAULT '0' COMMENT '下载授信使用次数' AFTER `download_month`,
ADD `download_credit` INT UNSIGNED NOT NULL DEFAULT '0' COMMENT '下载授信次数' AFTER `download_counter`;

2、后台管理界面

后台主要在用户等级管理界面进行调整,增删改查的时候增加响应的界面和处理代码即可,这里贴出修改的上下文,可以自行对应修改

2.1、dede/member_rank.php


//保存更改
 if($dopost=='save')
 {
@@ -25,11 +32,12 @@ if($dopost=='save')
         $rank = ${"rank_".$startID};
         $money = ${"money_".$startID};
         $scores = ${"scores_".$startID};
+        $download_credit = ${"download_credit_".$startID};
         if(isset(${"check_".$startID}))
         {
             if($rank>0)
             {
-                $query = "UPDATE `#@__arcrank` SET membername='$name',money='$money',rank='$rank',scores='$scores' WHERE id='$id' ";
+                $query = "UPDATE `#@__arcrank` SET membername='$name',money='$money',rank='$rank',scores='$scores',download_credit='$download_credit' WHERE id='$id' ";
             }
         }
         else
@@ -42,7 +50,7 @@ if($dopost=='save')
     {
         if($rank_new > 0 && $name_new != '' && $rank_new > 10)
         {
-            $inquery = "INSERT INTO `#@__arcrank`(`rank`,`membername`,`adminrank`,`money`,`scores`,`purviews`) VALUES('$rank_new','$name_new','5','$money_new','$scores',''); ";
+            $inquery = "INSERT INTO `#@__arcrank`(`rank`,`membername`,`adminrank`,`money`,`scores`,`download_credit`,`purviews`) VALUES('$rank_new','$name_new','5','$money_new','$scores', '$download_credit',''); ";
             $dsql->ExecuteNoneQuery($inquery);
         }
     }

2.2、dede/templets/member_rank.htm


@@ -20,6 +20,7 @@
       <td width="18%">会员等级值</td>
       <td width="15%">默认金币</td>
       <td width="15%">默认积分</td>
+      <td width="15%">月免费下载次数</td>
       <td width="16%">类型</td>
       <td width="16%">状态</td>
     </tr>
@@ -29,12 +30,13 @@
        {
          $k++;
        ?>
-
     <tr align="center" bgcolor="#FFFFFF" height="24">
       <td><input type="hidden" name="ID_<?php echo $k?>" value="<?php echo $row->id; ?>"><input name="name_<?php echo $k?>" value="<?php echo $row->membername; ?>" type="text" id="name_<?php echo $k?>" c
lass='autoinput alltxt' /></td>
       <td><input name="rank_<?php echo $k?>" value="<?php echo $row->rank; ?>"  type="text" id="rank_<?php echo $k?>" class='autoinput alltxt' /></td>
       <td><input name="money_<?php echo $k?>"  value="<?php echo $row->money; ?>"  type="text" id="money_<?php echo $k?>" class='autoinput alltxt' /></td>
       <td><input name="scores_<?php echo $k?>"  value="<?php echo $row->scores; ?>"  type="text" id="scores_<?php echo $k?>" class='autoinput alltxt' /></td>
+      <td><input name="download_credit_<?php echo $k?>"  value="<?php echo $row->download_credit; ?>"  type="text" id="download_credit_<?php echo $k?>" class='autoinput alltxt' /></td>
       <td align="center">
       <?php
          if($row->id<=5) { echo "系统"; }
@@ -55,6 +57,7 @@
       <td> 级别值(待审为0,注册会员为10) </td>
       <td> 默认金币 </td>
       <td> 默认积分 </td>
+      <td>默认月免费下载次数</td>
       <td> 操作设置 </td>
       <td>&nbsp;</td>
     </tr>
@@ -63,6 +66,7 @@
       <td><input name="rank_new" type="text" id="rank_new" value='20' class='autoinput alltxt'  /></td>
       <td><input name="money_new" type="text" id="money_new" value='0' class='autoinput alltxt' /></td>
       <td><input name="scores_new" type="text" id="scores_new" value='100' class='autoinput alltxt'  /></td>
+      <td><input name="download_credit_new" type="text" id="download_credit_new" value='0' class='autoinput alltxt'  /></td>
       <td><input name="check_new" type="checkbox" id="check_new" class="np" value="1" checked />
         增加等级 </td>
       <td>&nbsp;</td>

3、前端功能调整

首先用户在自己的控制面板需要能够查看自己的剩余额度,然后在下载的时候优先使用授信额度,使用完毕后如果继续下载则继续充值金币。

3.1、include/memberlogin.class.php

每次实例化当前登录用户信息的时候,都检查以下是否需要更新授信额度,然后在展示用户等级的时候显示已用额度和总额度。

  //间隔一小时更新一次用户登录时间
                 if(time() - $this->M_LoginTime > 3600)
                 {
                     $dsql->ExecuteNoneQuery("update `#@__member` set logintime='".time()."',loginip='".GetIP()."' where mid='".$this->fields['mid']."';");
                     PutCookie("DedeLoginTime",time(),$this->M_KeepTime);
                 }
+                $this->updateDownloadCredit();

             if(!is_array($rs)){
                 if($this->M_Rank>10 && $this->M_HasDay>0) $sta .= " 剩余天数: <font color='red'>".$this->M_HasDay."</font>  天 ";
                 elseif($this->M_Rank>10) $sta .= " <font color='red'>会员升级已经到期</font> ";
+                $sta .= sprintf('月免费下载次数 %d/%d', $this->M_DownloadCounter, $this->M_DownloadCredit);
+
           }
         }
         $sta .= " 拥有金币:{$this->M_Money} 个, 积分:{$this->M_Scores} 分。";
         return $sta;
     }
-
+    function updateDownloadCredit(){
+        global $dsql;
+        $dc_month = date('Ym');
+        $rank = $dsql->GetOne("Select membername,download_credit From `#@__arcrank` where rank='".$this->M_Rank."'");
+        $this->M_DownloadCredit = $rank['download_credit'];
+        $this->M_DownloadMonth = $this->fields['download_month'];
+        if($this->M_DownloadMonth < $dc_month){
+            $dsql->ExecuteNoneQuery("UPDATE `#@__member`
+                SET download_month=$dc_month,
+                download_credit = {$rank['download_credit']}
+                download_counter = 0
+                WHERE mid='".$this->M_ID."'");
+        }
+        $this->M_DownloadCounter = $this->fields['download_counter'];
+        $this->M_DownloadMonth = $dc_month;
+    }

### 3.2、`plus/download.php`
下载时在扣除金币的时候和之前一样,如果已经购买不再重复购买和使用授信额度。当需要购买时,优先使用剩余的授信额度,如果授信额度用完才继续进入购买金币流程。

```diff
@@ -196,25 +196,40 @@ else if($open==2)
             //未购买过此文章
             if( !is_array($row) )
             {
-                //没有足够的金币
-                if( $needMoney > $cfg_ml->M_Money || $cfg_ml->M_Money=='')
-                {
-                    $msgtitle = "你没有权限下载软件:{$arctitle}!";
-                    $moremsg = "这个软件需要 <font color='red'>".$needMoney." 金币</font> 才能下载,你目前拥有金币:<font color='red'>".$cfg_ml->M_Money." 个</font> !";
-                    include_once(DEDETEMPLATE.'/plus/view_msg.htm');
-                    exit(0);
+                // 会员等级有相应的下载授信额度,则直接扣减额度,扣减完毕后才需要购买
+                if($cfg_ml->M_Rank && $cfg_ml->M_DownloadCredit && $cfg_ml->M_DownloadCounter < $cfg_ml->M_DownloadCredit){
+                     $inquery = "INSERT INTO `#@__member_operation`(mid,oldinfo,money,mtime,buyid,product,pname,sta)
+                      VALUES ('".$cfg_ml->M_ID."','$arctitle','$needMoney','".time()."', 'ARCHIVE".$id."', 'archive','下载软件(授信)', 2); ";
+                    //记录定单
+                    if( !$dsql->ExecuteNoneQuery($inquery) )
+                    {
+                        ShowMsg('记录定单失败, 请返回', '-1');
+                        exit(0);
+                    }
+                    //记录已用授信次数
+                    $dsql->ExecuteNoneQuery("UPDATE `#@__member` SET download_counter = download_counter + 1 WHERE mid='".$cfg_ml->M_ID."'");
                 }
-                //有足够金币,记录用户信息
-                $inquery = "INSERT INTO `#@__member_operation`(mid,oldinfo,money,mtime,buyid,product,pname,sta)
-                  VALUES ('".$cfg_ml->M_ID."','$arctitle','$needMoney','".time()."', 'ARCHIVE".$id."', 'archive','下载软件', 2); ";
-                //记录定单
-                if( !$dsql->ExecuteNoneQuery($inquery) )
-                {
-                    ShowMsg('记录定单失败, 请返回', '-1');
-                    exit(0);
+                else{
+                    //没有足够的金币
+                    if( $needMoney > $cfg_ml->M_Money || $cfg_ml->M_Money=='')
+                    {
+                        $msgtitle = "你没有权限下载软件:{$arctitle}!";
+                        $moremsg = "这个软件需要 <font color='red'>".$needMoney." 金币</font> 才能下载,你目前拥有金币:<font color='red'>".$cfg_ml->M_Money." 个</font> !";
+                        include_once(DEDETEMPLATE.'/plus/view_msg.htm');
+                        exit(0);
+                    }
+                    //有足够金币,记录用户信息
+                    $inquery = "INSERT INTO `#@__member_operation`(mid,oldinfo,money,mtime,buyid,product,pname,sta)
+                      VALUES ('".$cfg_ml->M_ID."','$arctitle','$needMoney','".time()."', 'ARCHIVE".$id."', 'archive','下载软件', 2); ";
+                    //记录定单
+                    if( !$dsql->ExecuteNoneQuery($inquery) )
+                    {
+                        ShowMsg('记录定单失败, 请返回', '-1');
+                        exit(0);
+                    }
+                    //扣除金币
+                    $dsql->ExecuteNoneQuery("UPDATE `#@__member` SET money = money - $needMoney WHERE mid='".$cfg_ml->M_ID."'");
                 }
-                //扣除金币
-                $dsql->ExecuteNoneQuery("UPDATE `#@__member` SET money = money - $needMoney WHERE mid='".$cfg_ml->M_ID."'");
             }
         }
     }

4、测试

  • 管理后台->会员产品分类->设置产品定价
  • 管理后台->会员级别设置->设置对应级别授信额度
  • 用户首页(http://mysite.com/member)->消费中心(http://mysite.com/member/buy.php)-会员升级 完成后可以回到首页查看个人的授信额度使用和剩余情况
  • 下载付费资料看是否不在需要付费,并且出现授信额度使用记录

5、总结

从修改开始修改代码到最后完成真心没超过半小时,但是在这之前我就觉得这个授信额度的每月重置功能如何设计很是闹心。增加定时任务?会员升级后马上处理?总之会引入各种问题,在思前想后想了很久才有这个办法:月份不对马上更新,授信额度不对马上更新,记录使用次数,比对时比对授信额度和已用次数即可,简单实用。
这个功能上上去了客户很满意,但是预算不多,我也没挣到钱,记录下来分享给大家,大家看着好的话打个赏?如果有效以后我会给大家分享更多。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容