where('start_time', '<=', time()); } /** * @param string $name * @param mixed $data * @return bool */ public static function setC($name, $data, $success = false) { CacheService::set($name, $data); CacheService::set($name . "_success", $success); return true; } /** * @param $data * @return bool * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public static function doVote($data) { $num = $data['num'] ?? 0; $id = $data['id'] ?? 0; $uid = $data['uid'] ?? 0; $wait_id = $data['wait_id'] ?? ''; if ($uid == 0 || !$wait_id) { return true; } $vote = VoteSub::ing()->where('id', $id)->find(); if (!$vote) { return self::setC($wait_id, '该投票已结束'); } $vote_parent = Vote::ing()->where('id', $vote['vote_id'])->find(); if (!$vote_parent) { return self::setC($wait_id, '该投票已结束'); } $num = bcadd($num, 0, $vote_parent['money_precision']); if ($num <= 0) { return self::setC($wait_id, '请输入大于0的投票数额'); } if (!$id) { return self::setC($wait_id, '请选择要参与的投票'); } $my_money = UserMoney::initialUserMoney($uid, $vote_parent['money_type']); if ($my_money['money'] < $num) return self::setC($wait_id, $vote_parent['money_type'] . '余额不足'); $vote_sum = UserVote::where('sub_vote_id', $id)->sum('vote_num'); $all_num = bcsub($vote['vote_num'], $vote_sum, $vote_parent['money_precision']); if ($all_num < $num) return self::setC($wait_id, '本期投票额度不足,最多还可投' . $all_num . $vote_parent['money_type']); $vote_sum = UserVote::where('uid', $uid)->where('sub_vote_id', $id)->sum('vote_num'); $all_num = bcsub($vote['max_vote_num'], $vote_sum, $vote_parent['money_precision']); if ($all_num < $num) return self::setC($wait_id, '本期投票额度不足,最多还可投' . $all_num . $vote_parent['money_type']); //检查手续费 $vote_commission_type = sys_config('vote_commission_type', ''); $vote_commission_ratio = 0; if ($vote_commission_type) { $vote_commission_ratio = sys_config('vote_commission_ratio', 0); } if ($vote_commission_ratio > 0) { $need = bcmul(bcdiv($vote_commission_ratio, 100, 4), $num, $vote_parent['money_precision']); $my_money = UserMoney::initialUserMoney($uid, $vote_commission_type); if ($need > $my_money) { return self::setC($wait_id, '手续费' . $vote_commission_type . '余额不足'); } } BaseModel::beginTrans(); try { $res2 = true; $res1 = UserVote::create(['uid' => $uid, 'sub_vote_id' => $id, 'vote_id' => $vote_parent['id'], 'vote_num' => $num, 'add_time' => time()]); if (isset($need) && $need > 0) $res2 = UserMoney::expendMoney($uid, $vote_commission_type, $need, 'join_vote_commission', '参与投票手续费', '参与投票' . $vote_parent['vote_name'] . ' 第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . ' 手续费', $vote_parent['id'], $vote['id']); $res2 = $res2 && UserMoney::expendMoney($uid, $vote_parent['money_type'], $num, 'join_vote', '参与投票', '参与投票' . $vote_parent['vote_name'] . ' 第' . $vote['loop'] . '期' . $vote['vote_sub_name'], $vote_parent['id'], $vote['id']); $res6 = User::addAchievement($uid, $num); $res7 = UserPointPlan::checkPass(); $res4 = self::uperAward($uid, $num, $vote_parent['money_type'], $vote_parent['money_precision']) && self::layerAward($uid, $num, $vote_parent['money_type'], $vote_parent['money_precision']); // $res4 = true; $res3 = self::checkVote($id); // $res3= true; $res = $res1 && $res2 && $res3 && $res4 && $res6 && $res7; if ($res) { BaseModel::commitTrans(); return self::setC($wait_id, '投票成功', true); } else { BaseModel::rollbackTrans(); return self::setC($wait_id, '$res1=' . ($res1 ? 'true' : 'false') . '$res2=' . ($res2 ? 'true' : 'false') . '$res3=' . ($res3 ? 'true' : 'false') . '$res4=' . ($res4 ? 'true' : 'false') . '-----' . UserVote::getErrorInfo('') . ',' . UserMoney::getErrorInfo('') . ',' . self::getErrorInfo('')); } } catch (Exception $e) { BaseModel::rollbackTrans(); CacheService::set($wait_id, $e->getMessage() . '出现错误'); return false; } } /** * @param $uid * @param $num * @param $money_type * @param $money_precision * @return bool * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public static function uperAward($uid, $num, $money_type, $money_precision) { $user = User::getUserInfo($uid); if (!$user['spread_uid']) return true; $uper = User::getUserInfo($user['spread_uid']); $vote_recommend_award = sys_data('vote_recommend_award'); $key = array_column($vote_recommend_award, 'spread_num'); array_multisort($key, SORT_DESC, $vote_recommend_award); $layer = 1; $res = true; while ($uper) { foreach ($vote_recommend_award as $v) { if ($v['spread_num'] <= $uper['spread_count']) { if ($layer == $v['award_layer']) { //发奖 $brokerage = bcmul($num, bcdiv($v['ratio'], 100, 4), $money_precision); if ($brokerage > 0) { $res = $res && UserMoney::incomeMoney($uper['uid'], $money_type, $brokerage, 'vote_spread_brokerage', '推荐投票', '下级用户' . $user['nickname'] . '(' . $uid . ')' . '参与投票,获得推荐奖'); } } break; } } $uper = User::getUserInfo($uper['spread_uid']); $layer++; } return $res; } /** * @param $uid * @param $num * @param $money_type * @param $money_precision * @return bool * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public static function layerAward($uid, $num, $money_type, $money_precision) { $user = User::getUserInfo($uid); if (!$user['spread_uid']) return true; $uper = User::getUserInfo($user['spread_uid']); $send = 0; $layer = 1; $res = true; while ($uper) { $uper_level = UserLevel::getUserLevelInfo(UserLevel::getUserLevel($uper['uid'])); $uper_point = UserPointPlan::is_point($uper['uid']); if ($uper_point) { if ($uper_point['layer_award_ratio'] > $uper_level['layer_award_ratio']) $uper_level['layer_award_ratio'] = $uper_point['layer_award_ratio']; if ($uper_point['layer_award_layer'] > $uper_level['layer_award_layer']) $uper_level['layer_award_layer'] = $uper_point['layer_award_layer']; } if ($uper_level['layer_award_ratio'] > 0 && $uper_level['layer_award_layer'] >= $layer) { $brokerage = bcmul($num, bcdiv($uper_level['layer_award_ratio'], 100, 4), $money_precision); if ($brokerage > $send) { $res = $res && UserMoney::incomeMoney($uper['uid'], $money_type, bcsub($brokerage, $send, $money_precision), 'vote_layer_brokerage', '投票极差奖', '下级用户' . $user['nickname'] . '(' . $uid . ')' . '参与投票,获得级差奖'); $send = $brokerage; } } $uper = User::getUserInfo($uper['spread_uid']); $layer++; } return $res; } /** * @param $id * @return bool|void * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ private static function checkVote($id) { $vote = VoteSub::ing()->where('id', $id)->find(); if (!$vote) { return self::setErrorInfo('该投票已结束'); } $vote_parent = Vote::ing()->where('id', $vote['vote_id'])->find(); if (!$vote_parent) { return self::setErrorInfo('该投票已结束'); } $vote_sum = UserVote::where('sub_vote_id', $id)->sum('vote_num'); if ($vote_sum >= $vote['vote_num']) { $res = true; if ($vote['loop'] >= 3) { //投票成功发放奖金 $send_vote = VoteSub::where('vote_id', $vote_parent['id'])->where('loop', $vote['loop'] - 2)->find(); $list = UserVote::where('vote_id', $send_vote['id'])->where('uid', '<>', 0)->field('uid,SUM(vote_num) as sum')->group('uid')->select(); $back = bcdiv($vote_parent['success_back'] + 100, 100, 4); foreach ($list as $v) { $money = bcmul($v['sum'], $back, $vote_parent['money_precision']); $res = $res && UserMoney::incomeMoney($v['uid'], $vote_parent['money_type'], $money, 'vote_success', '投票完成', '投票' . $vote_parent['vote_name'] . ' 第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . ' 完成,返还第' . $send_vote['loop'] . '期' . $send_vote['vote_sub_name'] . '投票收益', $vote_parent['id'], $vote['id']); } VoteSub::where('id', $send_vote['id'])->update(['status' => 4, 'finish_time' => time()]); } $res = $res && VoteSub::where('id', $id)->update(['status' => 2, 'success_time' => time()]); // $vote->status = 2; // $vote->success_time = time(); // $res = $res && $vote->save(); //开启下一期(默认生成为第二天早上10点开始) if (!VoteSub::where('loop', $vote['loop'] + 1)->where('vote_id', $vote_parent['id'])->find()) { $vote_up = bcdiv($vote_parent['step_vote_num'] + 100, 100, 4); $vote_all = bcpow($vote_up, $vote['loop'], 100); $vote_all_now = bcmul($vote_all, $vote_parent['start_vote_num'], $vote_parent['money_precision']); $vote_user_max = bcadd($vote_parent['start_max_vote_num'], bcmul($vote_parent['step_max_vote_num'], $vote['loop'], $vote_parent['money_precision']), $vote_parent['money_precision']); $create = [ 'vote_sub_name' => $vote_parent['vote_name'] . '第' . $vote['loop'] . '期', 'vote_id' => $vote_parent['id'], 'vote_num' => $vote_all_now, 'max_vote_num' => $vote_user_max, 'start_time' => strtotime(date('Y-m-d', strtotime('+1day')) . ' ' . $vote_parent['day_start']), 'end_time' => bcadd(strtotime(date('Y-m-d', strtotime('+1day')) . ' ' . $vote_parent['day_start']), bcadd($vote_parent['start_still_time'], bcmul($vote_parent['start_still_time'], $vote['loop'])) * 3600), 'loop' => $vote['loop'] + 1, 'status' => 1, 'add_time' => time(), ]; $res = $res && VoteSub::create($create); } return $res; } return true; } /** * //自动结束 * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public static function checkAllStop() { $votes = VoteSub::ing()->where('end_time', '<=', time())->select(); $res = true; foreach ($votes as $vote) { $vote_parent = Vote::ing()->where('id', $vote['vote_id'])->find(); $res = VoteSub::where('id', $vote['id'])->update(['status' => 3, 'finish_time' => time()]); $list = UserVote::where('sub_vote_id', $vote['id'])->where('uid', '<>', 0)->field('uid,SUM(vote_num) as sum')->group('uid')->select(); $back = bcdiv($vote_parent['fail_back_now'], 100, 4); //倒叙 $vote_end_brokerage = sys_config('vote_end_brokerage', 0); $money_all = UserVote::where('vote_id', $vote['vote_id'])->sum('vote_num'); $vote_end_brokerage = bcmul($money_all, bcdiv($vote_end_brokerage, 100, 4), $vote_parent['money_precision']); $last_vote_all = UserVote::where('sub_vote_id', $vote['id'])->sum('vote_num'); //---- foreach ($list as $v) { $money = bcmul($v['sum'], $back, $vote['money_precision']); $left_money = bcsub($v['sum'], $money, $vote_parent['money_precision']); $res = $res && UserMoney::incomeMoney($v['uid'], $vote_parent['money_type'], $money, 'vote_fail', '投票失败', '投票' . $vote_parent['vote_name'] . ' 第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . ' 失败,返还第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . '投票金额', $vote_parent['id'], $vote['id']); if ($left_money > 0 && $vote_parent['other_back_money_type']) $res = $res && UserMoney::incomeMoney($v['uid'], $vote_parent['other_back_money_type'], $left_money, 'vote_fail', '投票失败', '投票' . $vote_parent['vote_name'] . ' 第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . ' 失败,返还第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . '部分投票金额' . $vote_parent['other_back_money_type'], $vote_parent['id'], $vote['id']); //倒叙 if ($vote_end_brokerage > 0) { //加权值 $single_money = bcmul(bcdiv($v['sum'], $last_vote_all, 4), $vote_end_brokerage, $vote_parent['money_precision']); if ($single_money > 0) { $res = $res && UserMoney::incomeMoney($v['uid'], $vote_parent['money_type'], $single_money, 'vote_end_brokerage', '投票倒叙分红', '投票' . $vote_parent['vote_name'] . ' 第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . ' 失败,投票结束,获得倒叙分红', $vote_parent['id'], $vote['id']); } } //------ } $send_vote_1 = VoteSub::where('vote_id', $vote_parent['id'])->where('loop', $vote['loop'] - 1)->find(); if ($send_vote_1) { $list = UserVote::where('sub_vote_id', $send_vote_1['id'])->where('uid', '<>', 0)->field('uid,SUM(vote_num) as sum')->group('uid')->select(); $back = bcdiv($vote_parent['fail_back_last'], 100, 4); foreach ($list as $v) { $money = bcmul($v['sum'], $back, $vote['money_precision']); $left_money = bcsub($v['sum'], $money, $vote_parent['money_precision']); $res = $res && UserMoney::incomeMoney($v['uid'], $vote_parent['money_type'], $money, 'vote_fail', '投票失败', '投票' . $vote_parent['vote_name'] . ' 第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . ' 失败,返还第' . ($vote['loop'] - 1) . '期' . $send_vote_1['vote_sub_name'] . '部分投票金额', $vote_parent['id'], $vote['id']); if ($left_money > 0) $res = $res && UserMoney::incomeMoney($v['uid'], $vote_parent['other_back_money_type'], $left_money, 'vote_fail', '投票失败', '投票' . $vote_parent['vote_name'] . ' 第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . ' 失败,返还第' . ($vote['loop'] - 1) . '期' . $send_vote_1['vote_sub_name'] . '部分投票金额' . $vote_parent['other_back_money_type'], $vote_parent['id'], $vote['id']); } } $res = VoteSub::where('id', $send_vote_1['id'])->update(['status' => 3, 'finish_time' => time()]); $send_vote_2 = VoteSub::where('vote_id', $vote_parent['id'])->where('loop', $vote['loop'] - 2)->find(); if ($send_vote_2) { $list = UserVote::where('sub_vote_id', $send_vote_2['id'])->where('uid', '<>', 0)->field('uid,SUM(vote_num) as sum')->group('uid')->select(); $back = bcdiv($vote_parent['fail_back_before_last'], 100, 4); foreach ($list as $v) { $money = bcmul($v['sum'], $back, $vote['money_precision']); $left_money = bcsub($v['sum'], $money, $vote_parent['money_precision']); $res = $res && UserMoney::incomeMoney($v['uid'], $vote_parent['money_type'], $money, 'vote_fail', '投票失败', '投票' . $vote_parent['vote_name'] . ' 第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . ' 失败,返还第' . ($vote['loop'] - 2) . '期' . $send_vote_2['vote_sub_name'] . '部分投票金额', $vote_parent['id'], $vote['id']); if ($left_money > 0) $res = $res && UserMoney::incomeMoney($v['uid'], $vote_parent['other_back_money_type'], $left_money, 'vote_fail', '投票失败', '投票' . $vote_parent['vote_name'] . ' 第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . ' 失败,返还第' . ($vote['loop'] - 2) . '期' . $send_vote_2['vote_sub_name'] . '部分投票金额' . $vote_parent['other_back_money_type'], $vote_parent['id'], $vote['id']); } } $res = VoteSub::where('id', $send_vote_2['id'])->update(['status' => 3, 'finish_time' => time()]); //节点奖励 $point_award = sys_config('point_ratio', 0); if ($point_award > 0) { $vote_point_brokerage = bcmul($money_all, bcdiv($point_award, 100, 4), $vote_parent['money_precision']); $all_point = UserPointPlan::all_point(); if (count($all_point) > 0) { $single_get = bcdiv($vote_point_brokerage, count($all_point), $vote_parent['money_precision']); if ($single_get > 0) { foreach ($all_point as $v) { $res = $res && UserMoney::incomeMoney($v['uid'], $vote_parent['money_type'], $single_get, 'vote_point_brokerage', '投票节点分红', '投票' . $vote_parent['vote_name'] . ' 第' . $vote['loop'] . '期' . $vote['vote_sub_name'] . ' 失败,投票结束,获得节点分红', $vote_parent['id'], $vote['id']); } } } } $vote_parent->status = 2; $res = $res && $vote_parent->save(); } return $res; } /** * //机器人 * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public static function robotOrder() { $robots = Robot::ing()->select(); $res = true; foreach ($robots as $robot) { //查询机器人负责的投票情况 $vote = VoteSub::ing()->where('id', $robot['sub_vote_id'])->find(); if (!$vote) { $res = $res && Robot::where('id', $robot['id'])->update(['status' => 2]); continue; } $last = UserVote::where('uid', 0)->where('sub_vote_id', $vote['id'])->order('add_time', 'desc')->find(); if ($last && ($last['add_time'] + $robot['step_time'] * 60 > time())) { continue; } $vote_parent = Vote::ing()->where('id', $vote['vote_id'])->find(); $all_num = UserVote::where('sub_vote_id', $vote['id'])->sum('vote_num'); //缺值 $need = bcsub($vote['vote_num'], $all_num, $vote_parent['money_precision']); //机器人本次投值 $post = bcadd($robot['start_num'], bcmul(UserVote::where('uid', 0)->where('sub_vote_id', $vote['id'])->count(), $robot['step_num'], $vote_parent['money_precision']), $vote_parent['money_precision']); $post = $need < $post ? $need : $post; $res = $res && UserVote::create(['uid' => 0, 'sub_vote_id' => $vote['id'], 'vote_id' => $vote_parent['id'], 'vote_num' => $post, 'add_time' => time()]); $res = $res && self::checkVote($vote['id']); } return $res; } /** * @param $where * @return array */ public static function getList($where) { $model = new self(); if (isset($where['id']) && $where['id']) $model = $model->where('vote_id', $where['id']); $count = $model->count(); $data = $model->page((int)$where['page'], (int)$where['limit'])->select()->each(function ($item) { switch ($item['status']) { case 1: $item['_status'] = '进行中'; break; case 2: $item['_status'] = '投票成功'; break; case 3: $item['_status'] = '投票失败'; break; case 0: $item['_status'] = '未开始'; break; default: $item['_status'] = '未知'; break; } $item['_start_time'] = date('Y-m-d H:i:s', $item['start_time']); $item['_end_time'] = date('Y-m-d H:i:s', $item['end_time']); $item['_add_time'] = date('Y-m-d H:i:s', $item['add_time']); $item['now_vote_num'] = UserVote::where('sub_vote_id', $item['id'])->sum('vote_num'); }); return compact('count', 'data'); } }