123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- <?php
- namespace app\models\vote;
- use app\models\point_plan\UserPointPlan;
- use app\models\user\User;
- use app\models\user\UserLevel;
- use app\models\user\UserMoney;
- use app\models\user\UserMoneyOrder;
- use crmeb\basic\BaseModel;
- use crmeb\services\CacheService;
- use crmeb\traits\ModelTrait;
- use think\db\exception\DataNotFoundException;
- use think\db\exception\DbException;
- use think\db\exception\ModelNotFoundException;
- use think\Exception;
- class VoteSub extends BaseModel
- {
- /**
- * 数据表主键
- * @var string
- */
- protected $pk = 'id';
- /**
- * 模型名称
- * @var string
- */
- protected $name = 'vote_sub';
- use ModelTrait;
- /**
- * @param bool $doing
- * @return VoteSub
- */
- public static function ing($doing = true)
- {
- return $doing == false ? self::where('status', 1) : self::where('status', 1)->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');
- }
- }
|