CREATE TABLE `yq_clock_setting` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255) NULL DEFAULT NULL COMMENT '标题' COLLATE 'utf8mb4_general_ci',
`deposit` DECIMAL(10,2) NULL DEFAULT '0.00' COMMENT '押金',
`days` INT(11) NOT NULL DEFAULT '0' COMMENT '挑战天数',
`maxpeople` INT(11) NOT NULL DEFAULT '0' COMMENT '最大参与人数0不限制',
`clock_start_time` TIME NULL DEFAULT NULL COMMENT '打卡开始时间',
`clock_end_time` TIME NULL DEFAULT NULL COMMENT '打卡结束时间',
`create_time` INT(11) NULL DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
)
COMMENT='打卡配置'
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=4
;
CREATE TABLE `yq_clock_take` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`user_id` INT(11) NOT NULL DEFAULT '0',
`deposit` DECIMAL(10,2) NOT NULL DEFAULT '0.00' COMMENT '押金',
`getmoney` DECIMAL(10,2) NOT NULL DEFAULT '0.00' COMMENT '瓜分金额(不包括押金)',
`days` INT(11) NOT NULL DEFAULT '0' COMMENT '挑战天数',
`clock_start_time` TIME NULL DEFAULT NULL COMMENT '打卡开始时间',
`clock_end_time` TIME NULL DEFAULT NULL COMMENT '打卡结束时间',
`status` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '-1挑战失败0刚参与1挑战中2挑战成功',
`create_time` INT(11) NULL DEFAULT NULL COMMENT '参与时间',
PRIMARY KEY (`id`) USING BTREE
)
COMMENT='打开活动参与纪录\r\n'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=157
;
CREATE TABLE `yq_clock_take_log` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`user_id` INT(11) NOT NULL DEFAULT '0' COMMENT '打卡人',
`take_id` INT(11) NOT NULL DEFAULT '0' COMMENT '参与ID',
`clock_time` INT(11) NULL DEFAULT NULL COMMENT '打卡时间',
PRIMARY KEY (`id`) USING BTREE,
INDEX `take_id` (`take_id`) USING BTREE
)
COMMENT='打卡记录'
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=113
;
二、控制器
namespace app\api\controller;
use app\common\services\ClockService;
use itholiday\enum\ClockTakeStatus;
use think\Db;
/**
* 打卡
* Class Clock
* @package app\api\controller
*/
class Clock extends Apibase
{
protected $noNeedLogin = ['info', 'notice', 'lastresult'];
/**
* 打卡配置-我的参与情况
*/
public function info()
{
$data['button_status'] = 0;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = 0;
$data['button_msg'] = '立即参与';
//是否参与过
$flag = db('clock_take')->alias('A')->join('__CLOCK_SETTING__ B', 'A.days=B.days')->field('A.*,B.title')->where('A.user_id', $this->user_id)->order('A.id', 'desc')->find();
if (!empty($flag)) {
if ($flag['status'] == ClockTakeStatus::$take) {
$data['button_status'] = 1;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = 0;
$data['button_msg'] = '立即打卡';
$create_tomorrow_start_time = strtotime('+1 day', strtotime(date('Y-m-d', $flag['create_time']) . ' ' . $flag['clock_start_time']));
if ($create_tomorrow_start_time > time()) {
$data['button_status'] = 2;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = $create_tomorrow_start_time - time();
$data['button_msg'] = '距下次打卡还有' . $data['button_remain'] . '秒';
}
} else if ($flag['status'] == ClockTakeStatus::$loading) {
$data['button_status'] = 2;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = 0;
$data['button_msg'] = '距下次打卡';
//有正在进行中的,可能挑战完了还未开奖
$docounts = db('clock_take_log')->where('user_id', $this->user_id)->where('take_id', $flag['id'])->count();
$today_clock_end_time = strtotime(date('Y-m-d') . ' ' . $flag['clock_end_time']);
/*if ($docounts >= $flag['days'] && $today_clock_end_time > time()) {
//完成
$data['button_status'] = 3;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = $today_clock_end_time - time();
$data['button_msg'] = '等待' . $data['button_remain'] . '秒后开奖';
} else {
//挑战失败
$time = date('H:i:s');
if ($time < $flag['clock_start_time']) {
$data['button_status'] = 2;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$create_today_start_time = strtotime(date('Y-m-d') . ' ' . $flag['clock_start_time']);
$data['button_remain'] = $create_today_start_time - time();
$data['button_msg'] = '距下次打卡还有' . $data['button_remain'] . '秒';
}
}*/
// 判断打卡次数与需要打卡的天数相比较,如果打卡天数
if ($docounts >= $flag['days']) {
// 已经打完卡 判断是否到开奖时间
if($today_clock_end_time > time()){
// 未到开奖时间
$data['button_status'] = 3;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = $today_clock_end_time - time();
$data['button_msg'] = '等待' . $data['button_remain'] . '秒后开奖';
}else{
// 到开奖时间
$data['button_status'] = 0;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = 0;
$data['button_msg'] = '立即参与';
}
}elseif ($docounts < $flag['days']) {
$clock_time = db('clock_take_log')->where('user_id', $this->user_id)->where('take_id', $flag['id'])->order('clock_time desc')->value("clock_time");
$create_tomorrow_start_time = strtotime('+1 day', strtotime(date('Y-m-d', $clock_time) . ' ' . $flag['clock_start_time']));
// 未到打卡时间 获取距离下次打卡时间
$data['button_status'] = 2;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = $create_tomorrow_start_time - time();
$data['button_msg'] = '距下次打卡还有' . $data['button_remain'] . '秒';
}
}
}
$data['button_remain'] = sectotime($data['button_remain']);
//打卡配置
$clocklist = db('clock_setting')->group('days')->order('days', 'asc')->select();
if (empty($clocklist)) $this->resultdata(['0', '打卡活动未开放.请在后台配置']);
$data['clocklist'] = $clocklist ?: [];
$today_start_time = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
foreach ($data['clocklist'] as &$item) {
//本期参与
$item['nowqishu'] = date('Ymd');
$nowcanyu = db('clock_take')->where('days', $item['days'])->whereBetweenTime('create_time', $today_start_time, time())->count();
$item['nowcanyu'] = $nowcanyu ?: 0;
//瓜分金额
$guafen = db('clock_take')->where('days', $item['days'])->whereTime('create_time', 'today')->sum('deposit');
$item['guafen'] = intval($guafen ?: 0);
}
//打卡记录参与纪录
$data['takelist'] = ClockService::clocktakenotice();
//活动规则
$clock_setting = cmf_get_option('clock_setting');
$data['config'] = $clock_setting;
if(!empty($data['config']['rules'])){
$data['config']['rules'] = htmlspecialchars_decode($data['config']['rules']);
}
$this->resultdata(['1', 'ok'], $data);
}
public function info2()
{
$data['button_status'] = 0;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = 0;
$data['button_msg'] = '立即参与';
//是否参与过
$flag = db('clock_take')->alias('A')->join('__CLOCK_SETTING__ B', 'A.days=B.days')->field('A.*,B.title')->where('A.user_id', $this->user_id)->order('A.id', 'desc')->find();
if (!empty($flag)) {
if ($flag['status'] == ClockTakeStatus::$take) {
$data['button_status'] = 1;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = 0;
$data['button_msg'] = '立即打卡';
$create_tomorrow_start_time = strtotime('+1 day', strtotime(date('Y-m-d', $flag['create_time']) . ' ' . $flag['clock_start_time']));
if ($create_tomorrow_start_time > time()) {
$data['button_status'] = 2;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = $create_tomorrow_start_time - time();
$data['button_msg'] = '距下次打卡还有' . $data['button_remain'] . '秒';
}
} else if ($flag['status'] == ClockTakeStatus::$loading) {
$data['button_status'] = 1;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = 0;
$data['button_msg'] = '立即打卡';
//有正在进行中的,可能挑战完了还未开奖
$docounts = db('clock_take_log')->where('user_id', $this->user_id)->where('take_id', $flag['id'])->count();
$today_clock_end_time = strtotime(date('Y-m-d') . ' ' . $flag['clock_end_time']);
if ($docounts >= $flag['days'] && $today_clock_end_time > time()) {
//完成
$data['button_status'] = 3;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$data['button_remain'] = $today_clock_end_time - time();
$data['button_msg'] = '等待' . $data['button_remain'] . '秒后开奖';
} else {
//挑战失败
$time = date('H:i:s');
if ($time < $flag['clock_start_time']) {
$data['button_status'] = 2;//0立即参与、1立即打卡、2距下次打卡、3等待开奖
$create_today_start_time = strtotime(date('Y-m-d') . ' ' . $flag['clock_start_time']);
$data['button_remain'] = $create_today_start_time - time();
$data['button_msg'] = '距下次打卡还有' . $data['button_remain'] . '秒';
}
}
}
}
$data['button_remain'] = sectotime($data['button_remain']);
//打卡配置
$clocklist = db('clock_setting')->group('days')->order('days', 'asc')->select();
if (empty($clocklist)) $this->resultdata(['0', '打卡活动未开放.请在后台配置']);
$data['clocklist'] = $clocklist ?: [];
$today_start_time = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
foreach ($data['clocklist'] as &$item) {
//本期参与
$item['nowqishu'] = date('Ymd');
$nowcanyu = db('clock_take')->where('days', $item['days'])->whereBetweenTime('create_time', $today_start_time, time())->count();
$item['nowcanyu'] = $nowcanyu ?: 0;
//瓜分金额
$guafen = db('clock_take')->whereTime('create_time', 'today')->where('days', $item['days'])->sum('deposit');
$item['guafen'] = intval($guafen ?: 0);
}
//打卡记录参与纪录
$data['takelist'] = ClockService::clocktakenotice();
//活动规则
$clock_setting = cmf_get_option('clock_setting');
$data['config'] = $clock_setting;
$this->resultdata(['1', 'ok'], $data);
}
/**
* 上期结果
*/
public function lastresult()
{
$days = input('days');
if ($days < 1) $this->resultdata(['0', '参数错误']);
//上期结果
$today_start_time = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
$clock_qi_start_time = $today_start_time - $days * 86400;
$clock_qi_end_time = $today_start_time - ($days - 1) * 86400;
$lastresult = Db::query("select count(*) as canyu,sum(deposit) as guafen from yq_clock_take where `days`={$days} and create_time between {$clock_qi_start_time} and {$clock_qi_end_time}");
$data['canyu'] = $lastresult ? ($lastresult[0]['canyu'] ?? 0) : 0;
//瓜分20200520
// $data['guafen'] = intval($lastresult ? ($lastresult[0]['guafen'] ?? 0) : 0);
// $data['guafen'] = 0;
//汇报率20200520
$hblist = Db::query("select (getmoney+deposit)/deposit as huibao from yq_clock_take where `days`={$days} and getmoney>0 and (create_time between {$clock_qi_start_time} and {$clock_qi_end_time})");
// $hblist = Db::query("select (getmoney)/deposit as huibao from yq_clock_take where `days`={$days} and getmoney>0 and (create_time between {$clock_qi_start_time} and {$clock_qi_end_time})");
if (empty($hblist)) {
$data['huibao'] = '0';
} else {
$sum = 0;
foreach ($hblist as $item) {
$sum += $item['huibao'];
}
$data['huibao'] = $sum / count($hblist) * 100;
}
//上期幸运榜20200520
/*$list = db('clock_take')->alias('a')->join('__USER__ b', 'a.user_id=b.id')
->field('a.status,a.getmoney,b.wx_nickname,b.nickname,b.mobile,b.avatar,b.headimgurl')
->where('a.days', $days)
->whereBetweenTime('a.create_time', $clock_qi_start_time, $clock_qi_end_time)
->where('a.status', ClockTakeStatus::$done)
->where('a.getmoney', 'gt', 0)
->order('a.id', 'desc')->limit(5)->select();*/
$list = db('clock_take')->field('id,user_id,status,getmoney')->whereBetweenTime('create_time', $clock_qi_start_time, $clock_qi_end_time)->where('status', 2)->where('getmoney', 'gt', 0)->order('id', 'desc')->select();
$luckylist = [];
$data['guafen'] = 0;
if (!empty($list)) {
foreach ($list as &$item) {
$userinfo = db("user")->where("id", $item['user_id'])->find();
$item['wx_nickname'] = $userinfo['wx_nickname'];
$item['nickname'] = $userinfo['nickname'];
$item['mobile'] = $userinfo['mobile'];
$item['avatar'] = $userinfo['avatar'];
$item['headimgurl'] = $userinfo['headimgurl'];
$avatar = $item['avatar'] ?: $item['headimgurl'] ?: '/static/images/avatar.png';
$nickname = $item['nickname'] ?: $item['wx_nickname'] ?: substr_replace($item['mobile'], '****', 3, 4);
array_push($luckylist, ['avatar' => $avatar, 'nickname' => $nickname, 'getmoney' => round($item['getmoney'], 2)]);
$data['guafen'] += $item['getmoney'];
}
}
$data['luckylist'] = $luckylist ?: [];
$this->resultdata(['1', 'ok'], $data);
}
/**
* 参与打卡活动-打卡
*/
public function take()
{
$days = input('days', 0, 'intval');
if (empty($days)) $this->resultdata(['0', '参数错误']);
$clock = db('clock_setting')->where('days', $days)->group('days')->field('title,deposit,days,maxpeople,clock_start_time,clock_end_time')->find();
if (empty($clock)) $this->resultdata(['0', '没有这样的挑战']);
//是否参与过
$flag = db('clock_take')->alias('A')->join('__CLOCK_SETTING__ B', 'A.days=B.days')->field('A.*,B.title')
->where('A.user_id', $this->user_id)->where('A.status', 'in', [ClockTakeStatus::$take, ClockTakeStatus::$loading])->order('A.id', 'desc')->find();
if (empty($flag)) {
//没有正在进行中的挑战,可以直接参与
//参与人数限制、参与、提示下次时间准时打卡
if ($clock['maxpeople'] > 0) {
$all = db('clock_take')->where('days', $days)->where('status', ClockTakeStatus::$take)->whereTime('create_time', 'today')->count();
$all >= $clock['maxpeople'] && $this->resultdata(['0', '参与人数封顶,请参与其他类型或明天再来']);
}
if ($clock['deposit'] > $this->user['user_money']) {
$this->resultdata(['0', '余额不足']);
}
$res = ClockService::takepartin($clock, $this->user_id);
if ($res) {
// $this->resultdata(['1', '参与成功,请明天' . $clock['clock_start_time'] . '到' . $clock['clock_end_time'] . '准时打卡']);
$this->resultdata(['1', '参与成功,请明天' . $clock['clock_start_time'] . '到' . $clock['clock_end_time'] . '准时打卡,打卡周期 '.$days.' 天']);
} else {
$this->resultdata(['0', '参与失败,请稍后后重试']);
}
} else {
if ($days != $flag['days']) {
$this->resultdata(['0', '您已参与了' . $flag['days'] . '天' . $flag['title']]);
}
//php获取昨日起始时间戳和结束时间戳
$last_take_log = db('clock_take_log')->where('take_id', $flag['id'])->order('id', 'desc')->find();
if (empty($last_take_log)) {
//隔两天去打卡
if (date('Y-m-d', $flag['create_time']) != date('Y-m-d')) {
$takeday_clock_end_time = strtotime(date('Y-m-d', $flag['create_time']) . ' ' . $flag['clock_end_time']);
if ($takeday_clock_end_time + 86400 < time()) {
ClockService::clocktakefail($flag, $clock);
$this->resultdata(['0', '挑战失败,请参与下期']);
}
}
} else {
//隔两天去打卡
$takelogday_clock_end_time = strtotime(date('Y-m-d', $last_take_log['clock_time']) . ' ' . $flag['clock_end_time']);
if ($takelogday_clock_end_time + 86400 < time()) {
ClockService::clocktakefail($flag, $clock);
$this->resultdata(['0', '挑战失败,请参与下期']);
}
}
//必须是连续两天打卡的逻辑
if ($flag['status'] == ClockTakeStatus::$take) {
//挑战失败
$create_today_start_time = strtotime(date('Y-m-d', $flag['create_time']) . ' ' . $flag['clock_start_time']) + 86400;
if (time() < $create_today_start_time) {
$this->resultdata(['0', '还未到打卡时间']);
}
//TODO 直接打卡、。是否结束打卡并颁奖
$res = db('clock_take_log')->insertGetId([
'user_id' => $this->user_id,
'take_id' => $flag['id'],
'clock_time' => time()
]);
if ($res) {
db('clock_take')->where('id', $flag['id'])->setField('status', ClockTakeStatus::$loading);
//未完成
$this->resultdata(['1', '打卡成功,已打卡1次']);
} else {
$this->resultdata(['0', '打卡失败,请稍后重试']);
}
} else {
//有正在进行中的,可能挑战完了还未开奖
$docounts = db('clock_take_log')->where('user_id', $this->user_id)->where('take_id', $flag['id'])->count();
if ($docounts >= $flag['days']) {
//完成
$this->resultdata(['1', '您已完成' . $flag['days'] . '天挑战,等待' . $flag['clock_end_time'] . '开奖']);
} else {
$time = date('H:i:s');
if ($time < $flag['clock_start_time']) {
$this->resultdata(['0', '还未到打卡时间']);
}
//未完成
//TODO 直接打卡、。是否结束打卡并颁奖
$res = db('clock_take_log')->insertGetId([
'user_id' => $this->user_id,
'take_id' => $flag['id'],
'clock_time' => time()
]);
if ($res) {
if ($docounts + 1 >= $flag['days']) {
//完成
$this->resultdata(['1', '您已完成' . $flag['days'] . '天' . $clock['title'] . ',等待' . $flag['clock_end_time'] . '开奖']);
} else {
//未完成
$this->resultdata(['1', '打卡成功,已连续打卡' . ($docounts + 1) . '次']);
}
} else {
$this->resultdata(['0', '打卡失败,请稍后重试']);
}
}
}
}
}
public function take2()
{
$days = input('days', 0, 'intval');
if (empty($days)) $this->resultdata(['0', '参数错误']);
$clock = db('clock_setting')->where('days', $days)->group('days')->field('title,deposit,days,maxpeople,clock_start_time,clock_end_time')->find();
if (empty($clock)) $this->resultdata(['0', '没有这样的挑战']);
//是否参与过
$flag = db('clock_take')->alias('A')->join('__CLOCK_SETTING__ B', 'A.days=B.days')->field('A.*,B.title')
->where('A.user_id', $this->user_id)->where('A.status', 'in', [ClockTakeStatus::$take, ClockTakeStatus::$loading])->order('A.id', 'desc')->find();
if (empty($flag)) {
//没有正在进行中的挑战,可以直接参与
//参与人数限制、参与、提示下次时间准时打卡
if ($clock['maxpeople'] > 0) {
$all = db('clock_take')->where('days', $days)->where('status', ClockTakeStatus::$take)->whereTime('create_time', 'today')->count();
$all >= $clock['maxpeople'] && $this->resultdata(['0', '参与人数封顶,请参与其他类型或明天再来']);
}
if ($clock['deposit'] > $this->user['user_money']) {
$this->resultdata(['0', '余额不足']);
}
$res = ClockService::takepartin($clock, $this->user_id);
if ($res) {
// $this->resultdata(['1', '参与成功,请明天' . $clock['clock_start_time'] . '到' . $clock['clock_end_time'] . '准时打卡']);
$this->resultdata(['1', '参与成功,请明天' . $clock['clock_start_time'] . '到' . $clock['clock_end_time'] . '准时打卡,打卡周期 '.$days.' 天']);
} else {
$this->resultdata(['0', '参与失败,请稍后后重试']);
}
} else {
if ($days != $flag['days']) {
$this->resultdata(['0', '您已参与了' . $flag['days'] . '天' . $flag['title']]);
}
//php获取昨日起始时间戳和结束时间戳
$last_take_log = db('clock_take_log')->where('take_id', $flag['id'])->order('id', 'desc')->find();
if (empty($last_take_log)) {
//隔两天去打卡
if (date('Y-m-d', $flag['create_time']) != date('Y-m-d')) {
$takeday_clock_end_time = strtotime(date('Y-m-d', $flag['create_time']) . ' ' . $flag['clock_end_time']);
if ($takeday_clock_end_time + 86400 < time()) {
ClockService::clocktakefail($flag, $clock);
$this->resultdata(['0', '挑战失败,请参与下期']);
}
}
} else {
//隔两天去打卡
$takelogday_clock_end_time = strtotime(date('Y-m-d', $last_take_log['clock_time']) . ' ' . $flag['clock_end_time']);
if ($takelogday_clock_end_time + 86400 < time()) {
ClockService::clocktakefail($flag, $clock);
$this->resultdata(['0', '挑战失败,请参与下期']);
}
}
//必须是连续两天打卡的逻辑
if ($flag['status'] == ClockTakeStatus::$take) {
//挑战失败
$create_today_start_time = strtotime(date('Y-m-d', $flag['create_time']) . ' ' . $flag['clock_start_time']) + 86400;
if (time() < $create_today_start_time) {
$this->resultdata(['0', '还未到打卡时间']);
}
//TODO 直接打卡、。是否结束打卡并颁奖
$res = db('clock_take_log')->insertGetId([
'user_id' => $this->user_id,
'take_id' => $flag['id'],
'clock_time' => time()
]);
if ($res) {
db('clock_take')->where('id', $flag['id'])->setField('status', ClockTakeStatus::$loading);
//未完成
$this->resultdata(['1', '打卡成功,已打卡1次']);
} else {
$this->resultdata(['0', '打卡失败,请稍后重试']);
}
} else {
//有正在进行中的,可能挑战完了还未开奖
$docounts = db('clock_take_log')->where('user_id', $this->user_id)->where('take_id', $flag['id'])->count();
if ($docounts >= $flag['days']) {
//完成
$this->resultdata(['1', '您已完成' . $flag['days'] . '天挑战,等待' . $flag['clock_end_time'] . '开奖']);
} else {
$time = date('H:i:s');
if ($time < $flag['clock_start_time']) {
$this->resultdata(['0', '还未到打卡时间']);
}
//未完成
//TODO 直接打卡、。是否结束打卡并颁奖
$res = db('clock_take_log')->insertGetId([
'user_id' => $this->user_id,
'take_id' => $flag['id'],
'clock_time' => time()
]);
if ($res) {
if ($docounts + 1 >= $flag['days']) {
//完成
$this->resultdata(['1', '您已完成' . $flag['days'] . '天' . $clock['title'] . ',等待' . $flag['clock_end_time'] . '开奖']);
} else {
//未完成
$this->resultdata(['1', '打卡成功,已连续打卡' . ($docounts + 1) . '次']);
}
} else {
$this->resultdata(['0', '打卡失败,请稍后重试']);
}
}
}
}
}
/**
* 我的挑战统计
*/
public function my()
{
$canyu = db('clock_take')->where('user_id', $this->user_id)->count();
$success = db('clock_take')->where('user_id', $this->user_id)->where('status', ClockTakeStatus::$done)->count();
$guafen = db('clock_take')->where('user_id', $this->user_id)->sum('getmoney');
$data['canyu'] = $canyu ?: 0;
$data['success'] = $success ?: 0;
$data['guafen'] = $guafen ?: 0;
$this->resultdata(['1', 'ok'], $data);
}
/**
* 我的打卡挑战记录
* TODO 开完奖后 status改为1
*/
public function clocklist()
{
//参与日期 天数1/3 进行中(未完成、完成) 瓜分金额(待开奖)
$list = db('clock_take')->where('user_id', $this->user_id)->field('id,create_time,days,status,deposit,getmoney')->order('id', 'desc')->select();
if (!empty($list)) {
foreach ($list as &$item) {
$item['create_time'] = date('Ymd', $item['create_time']);
$hasdone = db('clock_take_log')->where('user_id', $this->user_id)->where('take_id', $item['id'])->count();
$item['hasdone'] = $hasdone ?: 0;
$item['getmoney'] = ($item['days'] <= $hasdone) && ($item['status'] == ClockTakeStatus::$loading) ? '待开奖' : round($item['getmoney'], 2);
if ($item['status'] == ClockTakeStatus::$fail) {
$item['status'] = '失败';
$item['getmoney'] = '0.00';
} else if ($item['status'] == ClockTakeStatus::$done) {
$item['status'] = '已完成';
$item['getmoney'] = round($item['getmoney'], 2) ?: '进行中';
} else {
$item['status'] = '进行中';
$item['getmoney'] = '进行中';
}
}
}
$this->resultdata(['1', 'ok'], $list ?: []);
}
}
三、核心代码
namespace app\common\services;
use app\adminer\model\sLog;
use itholiday\enum\ClockTakeStatus;
use itholiday\enum\UserMoneyLogEnum;
use itholiday\util\LoggerUtil;
use itholiday\util\RedisUtil;
use think\Db;
/**
* 打卡逻辑
* Class ClockService
* @package app\common\services
*/
class ClockService
{
/**
* 参与打卡
* @param $clock
* @param $user_id
* @return bool
*/
public static function takepartin($clock, $user_id)
{
Db::startTrans();
try {
$user = db('user')->find($user_id);
//写记录
$res = db('clock_take')->insertGetId([
'user_id' => $user_id,
'status' => ClockTakeStatus::$take,
'deposit' => $clock['deposit'],
'getmoney' => 0,
'days' => $clock['days'],
'clock_start_time' => $clock['clock_start_time'],
'clock_end_time' => $clock['clock_end_time'],
'create_time' => time(),
]);
if (!$res) throw new \Exception('');
// 扣押金并写日志
$res = db('user')->where('id', $user_id)->setDec('user_money', $clock['deposit']);
if (!$res) throw new \Exception('');
$res = db('user_money_log')->insertGetId([
'user_id' => $user_id,
'coin' => 0 - $clock['deposit'],
'user_money' => $user['user_money'] - $clock['deposit'],
'log_type' => UserMoneyLogEnum::$take_clock,
'notes' => '参与' . $clock['days'] . '日' . $clock['title'],
'title' => $clock['days'] . '日' . $clock['title'],
'create_time' => time(),
]);
if (!$res) throw new \Exception('');
} catch (\Exception $e) {
Db::rollback();
return false;
}
Db::commit();
return true;
}
public static function clocktakenotice()
{
$list = db('clock_take')->alias('a')->join('__USER__ b', 'a.user_id=b.id')
->field('a.days,b.wx_nickname,b.nickname,b.mobile,b.avatar,b.headimgurl')->where('a.status', ClockTakeStatus::$take)->order('a.id', 'desc')->limit(5)->select();
$takelist = [];
if (!empty($list)) {
foreach ($list as $item) {
$avatar = $item['avatar'] ?: $item['headimgurl'] ?: '/static/images/avatar.png';
$nickname = $item['nickname'] ?: $item['wx_nickname'] ?: substr_replace($item['mobile'], '****', 3, 4);
$desipot = db("clock_setting")->where("days", $item['days'])->value("deposit");
$newFileds = $item['days'].'日挑战';
array_push($takelist, ['avatar' => $avatar, 'nickname' => $nickname, 'days' => $desipot,'days_field'=>$newFileds]);
// array_push($takelist, ['avatar' => $avatar, 'nickname' => $nickname, 'days' => $item['days']]);
}
}
return $takelist;
}
/**
* 挑战成功
* @param $clocktake
*/
public static function clocktakesuccess($clocktake, $clock)
{
$log['uid'] = $clocktake['user_id'];
$log['content'] = json_encode(array('title' => '您已完成' . $clocktake['days'] . '天' . $clock['title'], 'content' => ''));
$log['status'] = 0;//有弹窗
$log['create_time'] = time();
db('window')->insert($log);
db('clock_take')->where('id', $clocktake['id'])->setField('status', ClockTakeStatus::$done);
return true;
}
/**
* 挑战失败
* @param $clocktake
*/
public static function clocktakefail($clocktake, $clock = array())
{
$log['uid'] = $clocktake['user_id'];
$log['content'] = json_encode(['title' => '您未坚持,' . $clock['days'] . '日' . $clock['title'] . '失败', 'content' => '']);
$log['status'] = 0;//有弹窗
$log['create_time'] = time();
db('window')->insert($log);
db('clock_take')->where('id', $clocktake['id'])->setField('status', ClockTakeStatus::$fail);
return true;
}
public static function clockRedisQueueSuccess($clock_loading_set_item)
{
//标记处理完成
RedisUtil::getInstance()->sRem('clock_loading', $clock_loading_set_item);//移除集合
if (empty(RedisUtil::getInstance()->sCard('clock_loading'))) {
RedisUtil::getInstance()->set('clock_over', 1);//全部完成
$endToday = mktime(0, 0, 0, date('m'), date('d') + 1, date('Y')) - 1;
RedisUtil::getInstance()->setExpire('clock_over', $endToday - time());//到今天结束
}
}
/**
* 打卡发奖
*/
public static function publishreward()
{
//2020-05-15性能优化 会重复查询处理=》只处理一次
$clock_over = RedisUtil::getInstance()->get('clock_over');//今日打卡业务是否处理完成
if ($clock_over) return;//处理完成
$sCard = RedisUtil::getInstance()->sCard('clock_loading');
if (empty($sCard)) {
//没有成员,今日第一次进入,初始化处理集合。
$clock_setting = unserialize(RedisUtil::getInstance()->get('clock_setting'));
if (empty($clock_setting)) {
echo '请在后台配置打卡' . PHP_EOL;
return;
}
foreach ($clock_setting as $item) {
RedisUtil::getInstance()->sAdd('clock_loading', serialize($item));//写入集合
}
}
//取出待处理的业务项目
$clock_loadings = RedisUtil::getInstance()->sMembers('clock_loading');
if (empty($clock_loadings)) return;
dump($clock_loadings);
$time = date('H:i:s');
foreach ($clock_loadings as $item) {
$item = unserialize($item);
if ($time < $item['clock_end_time']) continue;//没到结束打卡时间
self::doClockJob($item);
}
}
public static function doClockJob($data)
{
$clock_loading_set_item = serialize($data);//集合元素
$days = $data['days'] ?? 0;
if (empty($days)) return true;
$clock = db('clock_setting')->where('days', $days)->find();
$today_start_time = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
$clock_qi_start_time = $today_start_time - $days * 86400;
$clock_qi_end_time = $today_start_time - ($days - 1) * 86400;
$takelist = db('clock_take')->where('days', $clock['days'])->whereBetweenTime('create_time', $clock_qi_start_time, $clock_qi_end_time)->select();//上一期参与的
if (empty($takelist)) {
// 标记处理完成
ClockService::clockRedisQueueSuccess($clock_loading_set_item);
return true;
}
LoggerUtil::logger('$takelist:' . json_encode($takelist, JSON_UNESCAPED_UNICODE), 'clock_publish_queue');
try {
$finishNum = 0;//完成人数
$finishUidinfos = [];//完成UID
$reward_pool = 0;
foreach ($takelist as $item) {
//判断此人是否完成
$doneCount = db('clock_take_log')->where('take_id', $item['id'])->count();
if ($doneCount < $item['days']) {
$reward_pool += $item['deposit'];//添加奖金池
//挑战失败
ClockService::clocktakefail($item, $clock);
} else {
$finishNum++;
array_push($finishUidinfos, $item);
//挑战完成
ClockService::clocktakesuccess($item, $clock);
//对完成的退回押金
db('user')->where('id', $item['user_id'])->setInc('user_money', $item['deposit']);
sLog::userMoneyLog($item['user_id'], $item['deposit'], UserMoneyLogEnum::$done_clock, '完成' . $item['days'] . '天' . $clock['title'] . ',退回押金' . $item['deposit'] . '元', '打卡退回押金');
}
}
file_put_contents('clocklog.txt', '$finishNum:' . $finishNum . PHP_EOL, FILE_APPEND);
file_put_contents('clocklog.txt', '$reward_pool:' . $reward_pool . PHP_EOL, FILE_APPEND);
file_put_contents('clocklog.txt', '$finishUidinfos:' . json_encode($finishUidinfos) . PHP_EOL, FILE_APPEND);
//对完成的瓜分
if ($finishNum && $reward_pool >= 0.01 * $finishNum) {
//瓜分多余的 算法:注册时间距现在时间越短、积极参与的获得的概率大
$r = get_red($reward_pool, $finishNum, 1);
foreach ($finishUidinfos as $k => $item) {
$getmoney = $r[$k] / 100;//将最终结果,转换成元为单位
file_put_contents('clocklog.txt', '$getmoney:' . $getmoney . PHP_EOL, FILE_APPEND);
db('user')->where('id', $item['user_id'])->setInc('user_money', $getmoney);
db('user')->where('id', $item['user_id'])->setInc('add_money', $getmoney);
sLog::userMoneyLog($item['user_id'], $getmoney, UserMoneyLogEnum::$done_clock, '完成' . $item['days'] . '天' . $clock['title'] . ',瓜分到奖金' . $getmoney . '元', '打卡瓜分奖金');
db('clock_take')->where('id', $item['id'])->setField('getmoney', $getmoney);
}
}
//标记处理完成
ClockService::clockRedisQueueSuccess($clock_loading_set_item);
} catch (\Exception $e) {
LoggerUtil::logger('exception:' . $e->getMessage() . PHP_EOL . '消息数据为:' . json_encode($data, JSON_UNESCAPED_UNICODE), 'clock_publish_queue');
return false;
}
return true;
}
}