立即注册 登录
彼岸网 返回首页

天香公主的个人空间 http://www.bian-wang.com/discuz/?10005 [收藏] [复制] [分享] [RSS] txgz999@yahoo.com

日志

Discuz系统中的积分机制

热度 1已有 311 次阅读2017-10-22 02:10 AM |个人分类:Discuz

本文探讨一下Discuz系统里积分的机制。

1。数据库里用户积分和积分规则的储存
Discuz里允许网站设置最多八种积分。在管理中心的全局->积分设置里,管理员可以设置这八种积分的名称,初始值,还有积分策略,即对固定的一组动作(如每天登录和发表日志),各个积分应如何改动。这些信息保存在数表 common_credit_rule里。
在数表里有个表列叫action(动作),给每个动作起了一个名字,比如发表日志叫publishblog,每天登录叫daylogin。代码里用到了这些动作名。另外还有个数表common_credit_rule_log记载了各个用户每次积分变动的时间,引发变动的动作,和积分变化情况,这些信息有助于在用户做一个可能引发积分变化的动作后判断是否要改变积分,还有一个数表common_member_count则记载了用户的累积积分。在用户积分变化时,需要更新这两个数表里的数据。

2。服务器端记录积分变动和通知客户端
在文件function_core.php里有个函数updatecreditbyaction,在每个common_credit_rule里提到的动作发生后都会使用它在记录积分变动。比如发表日志后,下面的代码会被运行(在文件function_blog.php里的函数blog_post里): updatecreditbyaction('publishblog', 0, array('blogs' => 1)); 这个函数调用了其它函数来记录积分变动: updatecreditbyaction in function_core.php -> execrule in class_credit.php -> updatecreditbyrule in class_credit.php -> updatemembercount in class_credit.php 在execrule中更新了common_credit_rule_log,在updatemembercount里更新了common_member_count。除此之外updatemembercount还有下面这句很重要的语句: dsetcookie('creditnotice', implode('D', $_G['cookiecredits']).'D'.$_G['uid']); 它将用户的积分变动放入了cookie送回到了客户端。

3。客户端检查和显示积分变动
客户端的积分功能的主力是文件common.js里的函数showCreditPrompt,它在Discuz里被多处调用。这里分两种情形:
1)该动作引发整个网页的更新
在几乎被每个模板文件嵌入了的子模板文件里有这么一段 <script type="text/javascript">var STYLEID = '{STYLEID}', STATICURL = '{STATICURL}', IMGDIR = '{IMGDIR}', VERHASH = '{VERHASH}', charset = '{CHARSET}', discuz_uid = '$_G[uid]', cookiepre = '{$_G[config][cookie][cookiepre]}', cookiedomain = '{$_G[config][cookie][cookiedomain]}', cookiepath = '{$_G[config][cookie][cookiepath]}', showusercard = '{$_G[setting][showusercard]}', attackevasive = '{$_G[config][security][attackevasive]}', disallowfloat = '{$_G[setting][disallowfloat]}', creditnotice = '<!--{if $_G['setting']['creditnotice']}-->$_G['setting']['creditnames']<!--{/if}-->', defaultstyle = '$_G[style][defaultextstyle]', REPORTURL = '$_G[currenturl_encode]', SITEURL = '$_G[siteurl]', JSPATH = '$_G[setting][jspath]', CSSPATH = '$_G[setting][csspath]', DYNAMICURL = '$_G[dynamicurl]';</script> <script type="text/javascript" src="{$_G[setting][jspath]}common.js?{VERHASH}"></script> 其中给变量creditnotice赋了值,并加入了文件common.js。而common.js里则调用了showCreditPrompt: if(typeof IN_ADMINCP == 'undefined') { if (creditnotice != '' && getcookie('creditnotice')) { _attachEvent(window, 'load', showCreditPrompt, document); } 所以每个镶嵌了子模板header_common.htm的模板文件都会激发showCreditPrompt
2)该动作引发网页的局部更新
这就需要在每个这样的动作处理完毕时直接调用showCreditPrompt。以发日志评论为例,在文件home.js中里的函数comment_add的结尾处就有 showCreditPrompt(); 接下来分析下showCreditPrompt的作用: showCreditPrompt in common.js -> _showCreditPrompt in common_extra.js -> creditShow in common_extra.js -> showPrompt in common.js _showCreditPrompt函数一开始就从cookie里提取了服务器端积分变动的通知 function _showCreditPrompt() { var notice = getcookie('creditnotice').split('D'); var basev = getcookie('creditbase').split('D'); var creditrule = decodeURI(getcookie('creditrule', 1)).replace(String.fromCharCode(9), ' '); 而最终showPrompt将积分变动作为提示显示在了屏幕上:


4。例子:每天登录
以登录网站为例,当用户填写了用户名和密码后,浏览器以POST的方式向服务器发送了登录请求后

收到的回复里设置了下面两个Cookie: creditnotice=0D0D2D0D0D0D0D0D0D1 creditrule=%E6%AF%8F%E5%A4%A9%E7%99%BB%E5%BD%95 其中前一个Cookie以D为分隔符给出了变动的积分和用户ID,上面字符串的具体含义是ID是1的用户第二种积分加2分;后一个字符串是经URL加码过的,用解码器(如 链接)查可以得知它的意思是"每天登录"。
Disucz遵循POST/REDIRECT/GET (PRG) 模式,没有直接在POST的回复里给出浏览器需要显示的内容,而是指示浏览器发送一个GET请求。

在对这个请求的答复里,可以看到各种网站使用的积分的名称,在这个例子里第二种积分的名称是"金钱",而其后加入的文件common.js里的代码则从所有这些信息中导出了显示给用户的提示内容:

发表评论 评论 (8 个评论)

回复 天香公主 2017-10-23 09:32 PM
牛肉炖土豆: 我觉得 JS,htm改多少都无所谓的,只要不改PHP就好,是否能实现呢
你可以试试在手机版里添加了common.js后再把电脑版的同名文件也加上,你前面说了有多处抱怨$,这些应该是在手机版的那些模版文件里吧,把抱怨$的地方的$均该为jQuery试试。
回复 牛肉炖土豆 2017-10-23 09:21 PM
天香公主: 我看了下手机版的common.js, 和电脑版的相比好像缺了不少东西。我估计要想在手机版上加这个提示,可能要从电脑版的同名文件以及common_extra.js搬很多代码过来 ...
我觉得 JS,htm改多少都无所谓的,只要不改PHP就好,是否能实现呢
回复 天香公主 2017-10-23 08:55 PM
牛肉炖土豆: 每一篇文章都像一本书!价值连城~要好好收藏,嘿嘿
哈,过奖过奖。我倒觉得Discuz的代码就象一本长篇小说,随手翻几页就能读到精彩之处。
回复 天香公主 2017-10-23 08:53 PM
牛肉炖土豆: 那应该就没办法了
哎,我是看到其他手机模板有这个积分提示,所有想自己搞一下,看样子不是那么简单!
我看了下手机版的common.js, 和电脑版的相比好像缺了不少东西。我估计要想在手机版上加这个提示,可能要从电脑版的同名文件以及common_extra.js搬很多代码过来,改那么多不值得吧
回复 牛肉炖土豆 2017-10-23 02:05 AM
每一篇文章都像一本书!价值连城~要好好收藏,嘿嘿
回复 牛肉炖土豆 2017-10-22 10:28 PM
天香公主: 嗯,PC版的Discuz自己定义了$符号的含义,而手机版上没有,手机版上的$出自jQuery,两者不匹配。
那应该就没办法了
哎,我是看到其他手机模板有这个积分提示,所有想自己搞一下,看样子不是那么简单!
回复 天香公主 2017-10-22 09:01 PM
牛肉炖土豆: 经测试,发现只要有<div id=&quot;append_parent&quot;></div>和PC的COMMON.js就能实现手机模板论坛页面的提示,不过这个JS跟手机版冲突不断,几乎跟手机版的所 ...
嗯,PC版的Discuz自己定义了$符号的含义,而手机版上没有,手机版上的$出自jQuery,两者不匹配。
回复 牛肉炖土豆 2017-10-22 08:48 PM
经测试,发现只要有<div id="append_parent"></div>和PC的COMMON.js就能实现手机模板论坛页面的提示,不过这个JS跟手机版冲突不断,几乎跟手机版的所有JS冲突,罪魁祸首是这个JS里面的
function $(id) {
        return !id ? null : document.getElementById(id);
}
但没有这个就不行,卡在这里了....

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 立即注册

小黑屋|Archiver|彼岸网  

Powered by Discuz! X3.1 © 2001-2014 Comsenz Inc.
GMT-4, 2017-11-25 03:49 AM , Processed in 0.061699 second(s), 19 queries.

返回顶部