無名

大猫咪与小狮子

导航

Discuz X2任务开发

简单描述

由于公司的需求要在系统中添加任务管理,用户通过完成任务而获得一定的奖励,因此其设计过程需要考虑到:

1、由于任务都是在系统中相关功能块处做一些相关事情,比如说在做题系统中完成指定的试题[1];在文章系统中发布3篇文章等等,说白了,完成任务就是在这些相关功能块的数据库表中更新一些数据。

2、由[1]的情况,需要对任务进行可扩展配置(How to do?),比如说配置第m单元到第n单元的试题,即配置时要配置相关功能块的数据库表的哪一些字段的值要达到某一个要求或许是总条数达到某一个值。

3、任务完成进度与任务是否完成以及任务访问地址的管理(该访问地址不存在,就需要自己开发)。

简单模型建立

想象一下,假如每一位访问者都要在试题库中做10试题,这很容易完成,我们只需要统计用户所做试题的总数超过10条就行了(条数>10),

 

问题的关键在于,每一个任务的完成要求字段的值(或许总数)所满足的要求不一样(字段不一样,值不一样,表不一样,统计字段不一样),

Discuz 任务管理

 

配置任务

source\class\task目录下存放每一个任务

文件名格式task_任务名.php,类名与文件名格式相同。

以task_promotion.php为例

 1 if(!defined('IN_DISCUZ')) {
 2     exit('Access Denied');
 3 }
 4 
 5 class task_promotion {
 6 
 7     var $version = '1.0';
 8     var $name = 'promotion_name';
 9     var $description = 'promotion_desc';
10     var $copyright = '<a href="http://www.comsenz.com" target="_blank">Comsenz Inc.</a>';
11     var $icon = '';
12     var $period = '';
13     var $periodtype = 0;
14     var $conditions = array(//任务完成的条件
15         'num' => array(
16             'title' => 'promotion_complete_var_iplimit',
17             'type' => 'text',
18             'value' => '',
19             'default' => 100,
20             'sort' => 'complete',
21         ),
22     );
23 
24     function preprocess($task) {//任务进度
25         global $_G;
26 
27         $promotions = DB::result_first("SELECT COUNT(*) FROM ".DB::table('forum_promotion')." WHERE uid='$_G[uid]'");
28         DB::query("REPLACE INTO ".DB::table('forum_spacecache')." (uid, variable, value, expiration) VALUES ('$_G[uid]', 'promotion$task[taskid]', '$promotions', '$_G[timestamp]')");
29     }
30 
31     function csc($task = array()) {//任务是否完成
32         global $_G;
33 
34         $num = DB::result_first("SELECT COUNT(*) FROM ".DB::table('forum_promotion')." WHERE uid='$_G[uid]'") - DB::result_first("SELECT value FROM ".DB::table('forum_spacecache')." WHERE uid='$_G[uid]' AND variable='promotion$task[taskid]'");
35         $numlimit = DB::result_first("SELECT value FROM ".DB::table('common_taskvar')." WHERE taskid='$task[taskid]' AND variable='num'");
36         if($num && $num >= $numlimit) {
37             return TRUE;
38         } else {
39             return array('csc' => $num > 0 && $numlimit ? sprintf("%01.2f", $num / $numlimit * 100) : 0, 'remaintime' => 0);
40         }
41     }
42 
43     function sufprocess($task) {
44         global $_G;
45 
46         DB::query("DELETE FROM ".DB::table('forum_spacecache')." WHERE uid='$_G[uid]' AND variable='promotion$task[taskid]'");
47     }
48 
49 }

可见source\class\task目录下的文件皆判断任务的完成状态,通方法csc判断任务是否完成!通常情况下还有任务的访问页面方法,前台调用该方法获得做任务的页面。

    function view() {
        return lang('task/avatar', 'avatar_view');
    }

source\admincp  admincp_tasks.php是管理任务的文件,将任务与配置到数据库中

 1 $applyperm = $_G['gp_grouplimit'] == 'special' && is_array($_G['gp_applyperm']) ? implode("\t", $_G['gp_applyperm']) : $_G['gp_grouplimit'];
 2         $_G['gp_starttime'] = strtotime($_G['gp_starttime']);
 3         $_G['gp_endtime'] = strtotime($_G['gp_endtime']);
 4         $reward = $_G['gp_reward'];
 5         $prize = $_G['gp_prize_'.$reward];
 6         $bonus = $_G['gp_bonus_'.$reward];
 7         if(!$_G['gp_name'] || !$_G['gp_description']) {
 8             cpmsg('tasks_basic_invalid', '', 'error');
 9         } elseif(($_G['gp_endtime'] && $_G['gp_endtime'] <= TIMESTAMP) || ($_G['gp_starttime'] && $_G['gp_endtime'] && $_G['gp_endtime'] <= $_G['gp_starttime'])) {
10             cpmsg('tasks_time_invalid', '', 'error');
11         } elseif($reward && (!$prize || ($reward == 'credit' && !$bonus))) {
12             cpmsg('tasks_reward_invalid', '', 'error');
13         }
14         $data = array(
15             'relatedtaskid' => $_G['gp_relatedtaskid'],
16             'available' => 0,
17             'name' => $_G['gp_name'],
18             'description' => $_G['gp_description'],
19             'icon' => $_G['gp_iconnew'],
20             'tasklimits' => $_G['gp_tasklimits'],
21             'applyperm' => $applyperm,
22             'scriptname' => $_G['gp_script'],
23             'starttime' => $_G['gp_starttime'],
24             'endtime' => $_G['gp_endtime'],
25             'period' => $_G['gp_period'],
26             'periodtype' => $_G['gp_periodtype'],
27             'reward' => $reward,
28             'prize' => $prize,
29             'bonus' => $bonus,
30         );
31         $taskid = DB::insert('common_task', $data, 1);
32 
33         if(is_array($task_conditions)) {
34             foreach($task_conditions as $taskvarkey => $taskvars) {
35                 if($taskvars['title']) {
36                     $comment = lang('task/'.$_G['gp_script'], $taskvars['title'].'_comment');
37                     $comment = $comment != $taskvars['title'].'_comment' ? $comment : '';
38                     //if block add by com.zaodao  Jayson.Xie 
39                     if($comment == ""){
40                         $comment = $taskvars['description'];
41                     }
42                     $data = array(
43                         'taskid' => $taskid,
44                         'sort' => $taskvars['sort'],
45                         'name' => lang('task/'.$_G['gp_script'], $taskvars['title']),
46                         'description' => $comment,
47                         'variable' => $taskvarkey,
48                         'value' => is_array($_G['gp_'.$taskvarkey]) ? addslashes(serialize($_G['gp_'.$taskvarkey])) : $_G['gp_'.$taskvarkey],
49                         'type' => $taskvars['type'],
50                     );
51                     DB::insert('common_taskvar', $data);
52                 }
53             }
54         }
55 
56         cpmsg('tasks_succeed', "action=tasks", 'succeed');
57 
58     }

数据库中分别用两个表来管理任务

common_task  任务表,记录任务与通用配置信息

 

【关键点】 common_taskvar  个性化配置信息与任务完成条件的记录(完成条件的每一个字段在该表中用一条记录来存储,因此当判断一个任务是否完成就从该表中取出字段,再到相应的表中去查询、统计以确定是否完成)

 

其中字段variable即使记录完成条件中所需要的字段名,

比如文章数目要达到5,就让表中记录variable=‘文章名’,value='5'

description字段是一个注解,显示在

在系统的前台,判断一个用户是否完成,只需要调用scs()方法即可。

注,在discuzX2中,不能配置完成条件的description属性值,系统自带的是 在语言包文件夹下获取的,只需在source\admincp  admincp_tasks.php中添加如下代码即可,

                    if($comment == ""){
                        $comment = $taskvars['description'];
                    }

在每个该段代码的地方都给加上,

在配置完成条件的时候,就可以用description字段。

var $conditions = array(
        'danyuan' => array(
            'title' => '完成的题目数大于或等于此设置,才算完成任务!',
            'type' => 'text',
            'value' => '',
            'default' => 100,
            'sort' => 'complete',
            'description' => 'ssssssssss',
        ),
    
    );

 

posted on 2013-07-13 13:16  xiezhengcai  阅读(1183)  评论(0编辑  收藏  举报