商城签到功能的设计与实现
需求分析
1、用户当天登录商城,只要签到就直接奖励一定的积分或者根据用户本周或者本月内已经连续签到的天数进行积分奖励,后台可以设置具体的奖励规则,这里假设本周内连续登录三天奖励 1 积分,五天奖励 2 积分,七天奖励 3 积分,每周一签到次数归零(归零方法不一定是每周一签到次数自动设为零,详见下文)
2、实现形式:在个人中心放置签到按钮或者登录成功之后进行弹窗提示
3、个人中心,用户可以看到签到日志(如果设置日志记录的话)和积分流水
4、商城后台可以对签到送积分的规则进行设置,也可以看到签到日子和积分流水,具体规则包括:1、奖励模式 2、相应模式配置 3、日志记录 4、是否开启等,具体详见签到配置表
签到配置列表,这些配置信息可以格式化以后作为商城的一项配置
type |
签到模式(当天签到就有奖励(1)、连续签到一定天数会有不同奖励(2)) |
configs |
type为1时,表示每天签到奖励积分数;type为2时,表示连续签到天数以及奖励阶梯(可以作为数组元素并存) |
open_log |
是否记录签到日志 |
save_days |
签到日志保存天数 |
is_open |
是否开启签到机制 |
|
|
数据库设计相关
1、商城用户表添加下面两个字段
last_signin_time 保存用户上一次签到时间
cont_days 保存用户连续签到天数
2、商城配置表添加一下字段
signin_configs 保存商城签到功能配置信息(json格式化或者序列化都可以)
3、签到日志表
表名:pre_signin_log |
功能:用于保存用户签到日志记录 |
|||
字段 |
数据类型 |
属性 |
约束条件 |
说明 |
id |
int(10) |
无符号、非空、自增 |
主键 |
主键id |
user_id |
int(10) |
无符号、非空、默认0 |
外键、普通索引(signin_user_id) |
用户id |
integral_num |
int(5) |
无符号、非空、默认0 |
|
签到奖励积分 |
add_time |
int(11) |
无符号、非空、默认0 |
|
签到时间 |
设计思路分析(用户签到操作时处理)
1、当天签到就送积分的简单模式(无需多言)
2、根据用户连续签到天数进行积分奖励的复杂模式
连续性判断:这个简单,判断昨天有没有签到就行
连续签到次数判断:根据连续性判断结果,再判断当天是不是周一,确定或者重置本周当前连续签到次数
奖励积分数实现:确定了连续签到次数,就可以根据商城签到配置信息确定当天签到后该奖励的积分数量并进行日志记录和积分流水记录操作
php 示例代码(ecshop实现)
/** * 代码中以文章开头的假设为思路,具体根据商城配置做修改 */ function userSignin(){ if (!$_SESSION['user_id']) { return false; } $time = getdate(); $today_zero = mktime(0, 0, 0, $time['mon'], $time['mday'], $time['year']); $sql = "select last_signin_time from ".$GLOBALS['ecs']->table('users')." where user_id = '$_SESSION[user_id]'"; $last_signin_time = $GLOBALS['db']->getOne($sql); if($today_zero < $last_signin_time && $last_signin_time < ($today_zero + 24*60*60)){ // 今日已经签到过了 array('error'=>true, 'msg'=>'你今日已经签过到咯'); }else{ // 签到处理 if($time['wday'] == 1){ // 如果是周一,签到从零算起 $sql = "update ".$GLOBALS['ecs']->table('users')." set cont_days = 1, last_signin_time = ".time()." where user_id = '$_SESSION[user_id]'"; $GLOBALS['db']->query($sql); return array('error'=>false, 'msg'=>'签到成功'); }else{ // 如果不是周一得判断有没有连续签到,具体方法是判断昨天有没有签到,如果签到了,连续签到次数加一,如果没有签到,连续次数归一 if(($today_zero - 24 * 60 *60) < $last_signin_time && $last_signin_time < $today_zero){ // 昨天已经签过到,连续签到天数加一 $sql = "update ".$GLOBALS['ecs']->table('users')." set cont_days = cont_days + 1, last_signin_time = ".time()." where user_id = '$_SESSION[user_id]'"; $GLOBALS['db']->query($sql); $cont_days = $GLOBALS['db']->getOne("select cont_days from ".$GLOBALS['ecs']->table('users')." where user_id = '$_SESSION[user_id]'"); // 根据文章开头的假设确定奖励积分数量 switch ($cont_days) { case 3: $add_integrals = 1; break; case 5: $add_integrals = 2; break; case 7: $add_integrals = 3; break; default: break; } // code... // 签到日志记录操作和积分账户处理操作代码省略…… if($add_integrals){ return array('error'=>false, 'msg'=>'你已经连续签到 '.$cont_days.' 天,获得奖励 '.$add_integrals.' 积分'); }else{ return array('error'=>false, 'msg'=>'签到成功'); } }else{ // 昨天没有签到,连续签到天数归一 $sql = "update ".$GLOBALS['ecs']->table('users')." set cont_days = 1, last_signin_time = ".time()." where user_id = '$_SESSION[user_id]'"; $GLOBALS['db']->query($sql); return array('error'=>false, 'msg'=>'签到成功'); } } } } $signinRes = userSignin(); var_dump($signinRes); // 打印签到结果