From dd6745fe241fc1b646b03c14d20afdd14435f5bb Mon Sep 17 00:00:00 2001 From: commie Date: Mon, 6 Apr 2026 03:10:44 +0800 Subject: [PATCH] 22 --- app/api/controller/AddressController.php | 4 +- app/api/controller/ArticleController.php | 283 +++++++++++------- app/api/controller/CommonController.php | 30 +- app/api/controller/PassportController.php | 16 +- app/api/controller/UserController.php | 4 +- app/api/controller/WalletController.php | 6 +- app/api/controller/WithdrawlController.php | 4 +- app/command/Otop.php | 48 --- app/command/Settlement.php | 36 --- app/command/Tongji.php | 101 +++---- app/command/User.php | 66 ++--- app/event/User.php | 67 +---- app/functions.php | 326 ++++++++------------- app/mcp/tpl/controller/api.tpl | 4 +- app/queue/single/buildTeam.php | 42 --- support/Jwt.php | 2 +- 16 files changed, 402 insertions(+), 637 deletions(-) delete mode 100755 app/command/Otop.php delete mode 100755 app/command/Settlement.php delete mode 100755 app/queue/single/buildTeam.php diff --git a/app/api/controller/AddressController.php b/app/api/controller/AddressController.php index c5433d4..243ce57 100755 --- a/app/api/controller/AddressController.php +++ b/app/api/controller/AddressController.php @@ -58,7 +58,7 @@ class AddressController extends BaseController{ */ public function create() { - //captcha_verfiy('image','create_address'); + //captcha_verify('image','create_address'); //* @Apidoc\Param("code", type="string", require=true, desc="图形验证码 event=create_address") //$trade_password = input('trade_password'); //\support\Jwt::verify_trade_password($trade_password); @@ -90,7 +90,7 @@ class AddressController extends BaseController{ */ public function update() { - //captcha_verfiy('image','update_address'); + //captcha_verify('image','update_address'); //$trade_password = input('trade_password'); //\support\Jwt::verify_trade_password($trade_password); $data = [ diff --git a/app/api/controller/ArticleController.php b/app/api/controller/ArticleController.php index d0356f0..5149eaa 100755 --- a/app/api/controller/ArticleController.php +++ b/app/api/controller/ArticleController.php @@ -2,168 +2,249 @@ namespace app\api\controller; use app\model\Archives as ArchivesModel; +use app\model\Content; use support\Request; use hg\apidoc\annotation as Apidoc; +use support\Jwt\JwtToken; +use support\think\Db; /** * 文章模块 */ -class ArticleController extends BaseController{ +class ArticleController extends BaseController +{ public $noNeedLogin = ['*']; + + private const CACHE_PREFIX_READ = 'article_read_'; + private const CACHE_TTL = 86400; + /** * 列表 * @Apidoc\Method("GET") - * @Apidoc\Query("category_id", type="int", require=true, desc="分类ID",default=10) - * @Apidoc\Query("page", type="int", require=true, desc="页码",default=1) - * @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10) + * @Apidoc\Query("category_id", type="int", require=true, desc="分类ID", default=10) + * @Apidoc\Query("page", type="int", require=true, desc="页码", default=1) + * @Apidoc\Query("limit", type="int", require=true, desc="分页大小", default=10) */ - public function list(){ - $limit = (int)input('limit',10); - $category_id = (int)input('category_id',0); + public function list() + { + $limit = (int)input('limit', 10); + $category_id = (int)input('category_id', 0); - $model = ArchivesModel::where('status','normal')->where('type','article'); - if($category_id){ - $model = $model->where('category_id',$category_id); + $model = ArchivesModel::where('status', 'normal')->where('type', 'article'); + if ($category_id) { + $model = $model->where('category_id', $category_id); } - $list = $model->order('id','desc')->paginate($limit); - $user_id=0; - try { - $user_id = \support\Jwt\JwtToken::getCurrentId(); - } catch (\Exception $e) { - } - $list->each(function($item)use($user_id){ - if(!$user_id){ - $item->is_read = 0; - }else{ - $item->is_read = cache('article_read_'.$item->id.'_'.$user_id)?:0; - } + $list = $model->order('id', 'desc')->paginate($limit); + + $user_id = $this->getCurrentUserId(); + $list->each(function ($item) use ($user_id) { + $item->is_read = $user_id ? $this->getReadStatus($item->id, $user_id) : 0; return $item; }); - return $this->success(__('successful'),$list->toArray()); - + + return $this->success(__('successful'), $list->toArray()); } + /** * faq * @Apidoc\method("GET") - * @Apidoc\Query("page", type="int", require=true, desc="页码",default=1) - * @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10) + * @Apidoc\Query("page", type="int", require=true, desc="页码", default=1) + * @Apidoc\Query("limit", type="int", require=true, desc="分页大小", default=10) */ - public function faq(){ - $limit = (int)input('limit',10); - $model = ArchivesModel::alias('a') + public function faq() + { + $limit = (int)input('limit', 10); + $list = ArchivesModel::alias('a') ->join('content c', 'a.id = c.id') - ->where('a.status','normal') - ->where('a.type','article') - ->where('a.category_id',9); - $list = $model->Field('a.title,a.id,c.content')->order('a.id','desc')->paginate($limit); - return $this->success(__('successful'),$list->toArray()); - + ->where('a.status', 'normal') + ->where('a.type', 'article') + ->where('a.category_id', 9) + ->field('a.title, a.id, c.content') + ->order('a.id', 'desc') + ->paginate($limit); + + return $this->success(__('successful'), $list->toArray()); } + /** * 详情 * @Apidoc\Method("GET") * @Apidoc\Query("id", type="int", require=true, desc="ID") */ - public function detail(){ - $appid = input('id'); - /** @var ArchivesModel $vo */ - $vo = ArchivesModel::where('id',$appid)->find(); - if($vo) { - $addon = \app\model\Content::where('id', $vo->id)->find()->toArray(); - if ($addon) { - $vo->setAddonData($addon); - } - $user_id=0; - try { - $user_id = \support\Jwt\JwtToken::getCurrentId(); - } catch (\Throwable $th) { - } - if($user_id){ - cache('article_read_'.$vo->id.'_'.$user_id,1); - } - return $this->success(__('successful'),$vo->toArray()); - }else{ + public function detail() + { + $id = (int)input('id'); + if (!$id) { + return $this->error(__("Invalid parameter")); + } + + $vo = ArchivesModel::where('id', $id)->find(); + if (!$vo) { return $this->error(__("Article does not exist")); } - } + + $this->appendContent($vo); + + $user_id = $this->getCurrentUserId(); + if ($user_id) { + $this->markAsRead($vo->id, $user_id); + } + + return $this->success(__('successful'), $vo->toArray()); + } + /** * 获取最新公告 * @Apidoc\Method("GET") */ - public function last_notie(){ - /** @var ArchivesModel $vo */ - $vo = ArchivesModel::where('type','article')->where('status','normal')->order('id','desc')->find(); - if($vo) { - $addon = \app\model\Content::where('id', $vo->id)->find()->toArray(); - if ($addon) { - $vo->setAddonData($addon); - } - try { - $user_id = \support\Jwt\JwtToken::getCurrentId(); - cache('article_read_'.$vo->id.'_'.$user_id,1); - } catch (\Throwable $th) { - } - return $this->success(__('successful'),$vo->toArray()); - }else{ - return $this->success(__("successful"),[]); + public function last_notie() + { + $vo = ArchivesModel::where('type', 'article') + ->where('status', 'normal') + ->order('id', 'desc') + ->find(); + + if (!$vo) { + return $this->success(__("successful"), []); } - } + + $this->appendContent($vo); + + $user_id = $this->getCurrentUserId(); + if ($user_id) { + $this->markAsRead($vo->id, $user_id); + } + + return $this->success(__('successful'), $vo->toArray()); + } + /** * 单页详情 * @Apidoc\Method("GET") * @Apidoc\Query("id", type="int", require=true, desc="ID") * @Apidoc\Query("name", type="string", require=true, desc="二选1") */ - public function singpage(){ - $appid = input('id'); + public function singpage() + { + $id = (int)input('id'); $name = input('name'); - /** @var ArchivesModel $vo */ - if($name){ - $vo = ArchivesModel::where('name',$name)->find(); - }else{ - if($appid){ - $vo = ArchivesModel::where('id',$appid)->find(); - } + + $vo = null; + if ($name) { + $vo = ArchivesModel::where('name', $name)->find(); + } elseif ($id) { + $vo = ArchivesModel::where('id', $id)->find(); } - if($vo) { - $addon = \app\model\Content::where('id', $vo->id)->find()->toArray(); - if ($addon) { - $vo->setAddonData($addon); - } - return $this->success(__('successful'),$vo->toArray()); - }else{ + + if (!$vo) { return $this->error(__("Article does not exist")); } + + $this->appendContent($vo); + + return $this->success(__('successful'), $vo->toArray()); } + /** * 幻灯片 * @Apidoc\Query("id", type="int", require=true, desc="ID") */ - public function slide(){ + public function slide() + { $list = [ - ['image'=>domain().'/storage/slide/1.jpg','title'=>''], - ['image'=>domain().'/storage/slide/2.webp','title'=>''], - ['image'=>domain().'/storage/slide/3.webp','title'=>''], - ['image'=>domain().'/storage/slide/4.jpg','title'=>''], + ['image' => domain() . '/storage/slide/1.jpg', 'title' => ''], + ['image' => domain() . '/storage/slide/2.webp', 'title' => ''], + ['image' => domain() . '/storage/slide/3.webp', 'title' => ''], + ['image' => domain() . '/storage/slide/4.jpg', 'title' => ''], ]; - return $this->success(__('successful'),$list); + return $this->success(__('successful'), $list); } /** * 设为已读 * @Apidoc\Query("id", type="int", require=true, desc="ID,多个逗号隔开") */ - function mask_as_read(){ + public function mask_as_read() + { $ids = input('id'); - $user_id = \support\Jwt\JwtToken::getCurrentId(); - if(!$user_id){ + $user_id = $this->getCurrentUserId(); + + if (!$user_id) { return $this->success(__('successful')); } - $ids = explode(',',$ids); + + $ids = array_filter(explode(',', $ids)); foreach ($ids as $id) { - $key = 'article_read_'.$id.'_'.$user_id; - cache($key,1); + $this->markAsRead((int)$id, $user_id); } + return $this->success(__('successful')); } -} \ No newline at end of file + + /** + * 获取当前用户ID + */ + protected function getCurrentUserId(): int + { + try { + return (int)JwtToken::getCurrentId(); + } catch (\Throwable $e) { + return 0; + } + } + + /** + * 获取阅读状态 + */ + protected function getReadStatus(int $articleId, int $userId): int + { + return (int)(cache_get($this->getCacheKey($articleId, $userId)) ?: 0); + } + + /** + * 标记为已读 + */ + protected function markAsRead(int $articleId, int $userId = null): void + { + if (!$articleId) { + return; + } + + if (!$userId) { + $userId = $this->getCurrentUserId(); + } + + if (!$userId) { + return; + } + + $cacheKey = $this->getCacheKey($articleId, $userId); + if (!cache_get($cacheKey)) { + Db::name('archives_read')->insert([ + 'user_id' => $userId, + 'source_id' => $articleId, + 'value' => 1 + ]); + cache($cacheKey, 1, self::CACHE_TTL); + } + } + + /** + * 追加内容到文章 + */ + protected function appendContent(ArchivesModel $article): void + { + $content = Content::where('id', $article->id)->find(); + if ($content) { + $article->setAddonData($content->toArray()); + } + } + + /** + * 生成缓存键 + */ + protected function getCacheKey(int $articleId, int $userId): string + { + return self::CACHE_PREFIX_READ . $articleId . '_' . $userId; + } +} diff --git a/app/api/controller/CommonController.php b/app/api/controller/CommonController.php index 08269cc..ee8837d 100755 --- a/app/api/controller/CommonController.php +++ b/app/api/controller/CommonController.php @@ -150,7 +150,7 @@ class CommonController extends BaseController{ } $username = $email; unset($mobile); - captcha_verfiy('email','register',$email,false); + captcha_verify('email','register',$email,false); } if ($type == 'mobile') { if(!$mobile || !Validate::regex($mobile, "^1\d{10}$")){ @@ -158,7 +158,7 @@ class CommonController extends BaseController{ } $username = $mobile; unset($email); - captcha_verfiy('mobile','register',$mobile,false); + captcha_verify('mobile','register',$mobile,false); } if ($type == 'username') { if(!$username){ @@ -226,11 +226,11 @@ class CommonController extends BaseController{ } $data = ['userinfo' => $user]; // if ($type == 'email') { - // captcha_verfiy('email','register',$email,true); + // captcha_verify('email','register',$email,true); // }else if ($type == 'mobile') { - // captcha_verfiy('mobile','register',$mobile,true); + // captcha_verify('mobile','register',$mobile,true); // }else{ - // captcha_verfiy('image','register',$mobile,true); + // captcha_verify('image','register',$mobile,true); // } return $this->success(__('Sign up successful'), $data); } catch (\Exception $e) { @@ -326,16 +326,16 @@ class CommonController extends BaseController{ $user = false; } if($user){ - captcha_verfiy('mobile','reset_pwd',$user->mobile); + captcha_verify('mobile','reset_pwd',$user->mobile); } }else{ if ($mobile && Validate::regex($mobile, "^1\d{10}$")) { - captcha_verfiy('mobile','reset_pwd',$mobile); + captcha_verify('mobile','reset_pwd',$mobile); $region = Input('region'); $region = str_replace('+','',$region); $user = UserModel::where('region',$region)->where('mobile',$mobile)->find(); }else if ($email && Validate::is($email, "email")) { - captcha_verfiy('email','reset_pwd',$email); + captcha_verify('email','reset_pwd',$email); $user = UserModel::getByEmail($email); } } @@ -385,19 +385,19 @@ class CommonController extends BaseController{ if($user){ if($verify_type == 'email'){ - captcha_verfiy('email','reset_trade_pwd',$user->email); + captcha_verify('email','reset_trade_pwd',$user->email); }else if($verify_type == 'mobile'){ - captcha_verfiy('mobile','reset_trade_pwd',$user->mobile); + captcha_verify('mobile','reset_trade_pwd',$user->mobile); }else{ return $this->error(__('Unknown verify type')); } } }else{ if ($mobile && Validate::regex($mobile, "^1\d{10}$")) { - captcha_verfiy('mobile','reset_trade_pwd',$mobile); + captcha_verify('mobile','reset_trade_pwd',$mobile); $user = UserModel::getByMobile($mobile); }elseif ($email && Validate::is($email, "email")) { - captcha_verfiy('email','reset_trade_pwd',$email); + captcha_verify('email','reset_trade_pwd',$email); $user = UserModel::getByEmail($email); } } @@ -534,11 +534,11 @@ class CommonController extends BaseController{ $event = $request->post('event'); try { if($type == 'email'){ - $result = captcha_verfiy('email', $event , $email,false); + $result = captcha_verify('email', $event , $email,false); }elseif($type == 'mobile'){ - $result = captcha_verfiy('mobile', $event , $mobile,false); + $result = captcha_verify('mobile', $event , $mobile,false); }else{ - $result = captcha_verfiy('image', $event , '',false); + $result = captcha_verify('image', $event , '',false); } if(!$result){ return $this->fail(__('Captcha is incorrect')); diff --git a/app/api/controller/PassportController.php b/app/api/controller/PassportController.php index 52ee3ef..453e38d 100644 --- a/app/api/controller/PassportController.php +++ b/app/api/controller/PassportController.php @@ -29,9 +29,9 @@ class PassportController extends BaseController{ $user = \support\Jwt::getUser(); $verify_type = input('verify_type'); if($verify_type=='mobile'){ - captcha_verfiy('mobile', 'verify', $user->mobile); + captcha_verify('mobile', 'verify', $user->mobile); }else if($verify_type == 'email'){ - captcha_verfiy('email', 'verify', $user->email); + captcha_verify('email', 'verify', $user->email); }else{ return $this->error(__('Invalid verify type')); } @@ -61,7 +61,7 @@ class PassportController extends BaseController{ } // 验证验证码 - captcha_verfiy('mobile', 'bind_mobile', $mobile); + captcha_verify('mobile', 'bind_mobile', $mobile); // 更新用户信息 $user->mobile = $mobile; @@ -91,7 +91,7 @@ class PassportController extends BaseController{ if (UserModel::where('email', $email)->where('id', '<>', $user->id)->find()) { return $this->error(__('Email already exists')); } - captcha_verfiy('email', 'bind_email', $email); + captcha_verify('email', 'bind_email', $email); // 更新用户信息 @@ -126,9 +126,9 @@ class PassportController extends BaseController{ } if($verify_type == 'mobile'){ - captcha_verfiy('mobile', 'bind_username', $user->mobile); + captcha_verify('mobile', 'bind_username', $user->mobile); }else if($verify_type == 'email'){ - captcha_verfiy('email', 'bind_username', $user->email); + captcha_verify('email', 'bind_username', $user->email); } // 更新用户信息 @@ -152,7 +152,7 @@ class PassportController extends BaseController{ } // 验证验证码 - captcha_verfiy('mobile', 'unbind_mobile', $user->mobile); + captcha_verify('mobile', 'unbind_mobile', $user->mobile); // 更新用户信息 $user->mobile = ''; @@ -176,7 +176,7 @@ class PassportController extends BaseController{ } // 验证验证码 - captcha_verfiy('email', 'unbind_email', $user->email); + captcha_verify('email', 'unbind_email', $user->email); // 更新用户信息 $user->email = ''; diff --git a/app/api/controller/UserController.php b/app/api/controller/UserController.php index 2c9a1b7..6371ef9 100755 --- a/app/api/controller/UserController.php +++ b/app/api/controller/UserController.php @@ -108,7 +108,7 @@ class UserController extends BaseController{ return $this->error(__('Invalid parameters')); } if($verify_type == 'email'){ - captcha_verfiy('email','reset_trade_pwd',$user->email); + captcha_verify('email','reset_trade_pwd',$user->email); try{ \support\Jwt::change_trade_pwd($newpassword,'',true); return $this->success(__('Reset trade password successful')); @@ -116,7 +116,7 @@ class UserController extends BaseController{ return $this->error($e->getMessage()); } }else if($verify_type == 'mobile'){ - captcha_verfiy('mobile','reset_trade_pwd',$user->mobile); + captcha_verify('mobile','reset_trade_pwd',$user->mobile); try{ \support\Jwt::change_trade_pwd($newpassword,'',true); return $this->success(__('Reset trade password successful')); diff --git a/app/api/controller/WalletController.php b/app/api/controller/WalletController.php index a9b0ccf..94d1a5d 100755 --- a/app/api/controller/WalletController.php +++ b/app/api/controller/WalletController.php @@ -34,7 +34,7 @@ class WalletController extends BaseController{ //return $this->error(__('The system is under maintenance, please wait...')); $user = \support\Jwt\JwtToken::getUser(); // if(Config('site.trade_password_type') == 'email'){ - // captcha_verfiy('email','exchange',$user['username']); + // captcha_verify('email','exchange',$user['username']); // }else{ // $trade_password = input('trade_password'); // \support\Jwt::verify_trade_password($trade_password); @@ -95,7 +95,7 @@ class WalletController extends BaseController{ return $this->error(__('User is incorrect')); } if(Config('site.trade_password_type') == 'email'){ - //captcha_verfiy('email','transfer',$to_user['username']); + //captcha_verify('email','transfer',$to_user['username']); }else{ $trade_password = input('trade_password'); \support\Jwt::verify_trade_password($trade_password); @@ -150,7 +150,7 @@ class WalletController extends BaseController{ //return $this->error(__('The system is under maintenance, please wait...')); $user = \support\Jwt\JwtToken::getUser(); // if(Config('site.trade_password_type') == 'email'){ - // captcha_verfiy('email','exchange',$user['username']); + // captcha_verify('email','exchange',$user['username']); // }else{ // $trade_password = input('trade_password'); // \support\Jwt::verify_trade_password($trade_password); diff --git a/app/api/controller/WithdrawlController.php b/app/api/controller/WithdrawlController.php index fd8e606..8c0e122 100755 --- a/app/api/controller/WithdrawlController.php +++ b/app/api/controller/WithdrawlController.php @@ -70,7 +70,7 @@ class WithdrawlController extends BaseController{ { //return $this->error(__('The system is under maintenance, please wait...')); //* @Apidoc\Param("code", type="string", require=true, desc="图形验证码(type=withdrawl)") - //captcha_verfiy('image','withdrawl'); + //captcha_verify('image','withdrawl'); $address_id = input('address_id'); if(!$address_id){ return $this->error(__('Address is incorrect')); @@ -85,7 +85,7 @@ class WithdrawlController extends BaseController{ // } $user = \support\Jwt::getUser(); if(Config('site.trade_password_type') == 'email'){ - captcha_verfiy('email','withdrawl',$user['username']); + captcha_verify('email','withdrawl',$user['username']); }else{ //验证交易密码 $trade_password = input('trade_password'); diff --git a/app/command/Otop.php b/app/command/Otop.php deleted file mode 100755 index e7f0ff4..0000000 --- a/app/command/Otop.php +++ /dev/null @@ -1,48 +0,0 @@ -addOption('user_id','u', InputArgument::OPTIONAL, 'user_id'); - } - - /** - * @param InputInterface $input - * @param OutputInterface $output - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output): int - { - $user_id = $input->getOption('user_id'); - if(!$user_id){ - return false; - } - /** - * @var \plugin\admin\app\model\Admin $admin - */ - $admin = \plugin\admin\app\model\Admin::where('id',$user_id)->find(); - if(!$admin){ - return false; - } - $totp = \OTPHP\TOTP::create($admin->totp_secret); - cp($totp->now()); - return 1; - } -} diff --git a/app/command/Settlement.php b/app/command/Settlement.php deleted file mode 100755 index 9fb8662..0000000 --- a/app/command/Settlement.php +++ /dev/null @@ -1,36 +0,0 @@ -addArgument('name', InputArgument::OPTIONAL, 'Name description'); - } - - /** - * @param InputInterface $input - * @param OutputInterface $output - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output): int - { - (new \support\Settlement())->autoSettlement(); - return 1; - } -} diff --git a/app/command/Tongji.php b/app/command/Tongji.php index f5ff5d6..bef50ae 100755 --- a/app/command/Tongji.php +++ b/app/command/Tongji.php @@ -37,10 +37,11 @@ class Tongji extends Command */ protected function execute(InputInterface $input, OutputInterface $output): int { - $this->question($input,$output); - //$this->role($input,$output); - //$this->recharge($input,$output); - //$this->withdrawl($input,$output); + $action = $input->getOption('action'); + if(method_exists($this, $action)){ + return $this->$action($input, $output); + } + cp('操作不存在:'.$action); return self::SUCCESS; } /** @@ -119,69 +120,39 @@ class Tongji extends Command } cp($withdrawl_result); } - function question(InputInterface $input, OutputInterface $output) { - $order_list = \app\model\ProductOrder::withJoin([ - 'product'=>function($q){ - return $q->field('price,interest_rate'); - } - ])->where('quantity','>',0)->select(); - } /** - * 修复所有角色购买统计 + * 修复团队统计数据 + * @param InputInterface $input + * @param OutputInterface $output + * @return int */ - function role(InputInterface $input, OutputInterface $output) { + function build_team(InputInterface $input, OutputInterface $output){ + $list = Db::name('user')->order('id','asc')->column('id'); + //$list = [['id'=>100006]]; + foreach($list as $k=>$user_id){ + //team_total + $team_user_ids = Db::name('user_team')->where('ancestor_id',$user_id) + ->where('depth','>',0) + ->order('depth','ASC') + ->column('descendant_id'); + Db::name('user_extend')->where('user_id',$user_id)->data([ + 'team_total'=> count($team_user_ids) + ])->save(); + cache('team_user_count_'.$user_id,count($team_user_ids)); + + $direct_use_count = Db::name('user')->where('parent_id',$user_id)->count('id'); + $vip_user_count = Db::name('user')->whereIn('id',$team_user_ids)->where('role_id','>',1)->count('id'); + + Db::name('user_extend')->where('user_id',$user_id)->data([ + 'direct_total'=> $direct_use_count, + 'vip_total'=> $vip_user_count + ])->save(); + cache('team_direct_total_'.$user_id,$direct_use_count); + cache('team_vip_total_'.$user_id,$vip_user_count); + update_user_level($user_id,$vip_user_count); + cp($user_id.'完成'); + } - } - /** - * 模拟用户注册 - */ - function register(InputInterface $input, OutputInterface $output){ - $last_user_id = UserModel::order('id','desc')->limit(1)->value('id'); - for ($i=$last_user_id+1; $i <= $last_user_id+2; $i++) { - $uids = UserModel::where("status",1)->column('id'); - $referrerId = $uids[array_rand($uids)]; - $email = 'test'.$i.'@msn.cn'; - $mobile = ''; - $password = '123456'; - $extends = [ - 'role_id' => rand(1,3), - 'money' => 0, - 'parent_id' => $referrerId - ]; - $user = \support\Jwt::register($email, $password, $email, $mobile, $extends); - cp($user['id']); - } - return 1; - } - function updateRechargeAddress(InputInterface $input, OutputInterface $output){ - $saveData = []; - $res = post(Config('pay.server').'/RechargeAddress/create',['appid'=>Config('pay.appid')]); - if($res){ - $res = json_decode($res,true); - if($res['code'] === 0){ - $saveData['bep_recharge_address'] = $res['data']['BEP-20']['address']; - $saveData['trc_recharge_address'] = $res['data']['TRC-20']['address']; - $saveData['decimal_part'] = $res['data']['BEP-20']['decimal_part']; - } - } - UserModel::where('id',123409)->update($saveData); - return 0; - } - function otop(){ - $secret = 'EJGYB7OZR2W46XRX7VB3PXHSOY4LUAWCA5GTDAVTWKHXNDAAAIIP7AQ3JSO3XZJNX5J5OTIDEQVKLYFYIYNAXSCYF4GNZ2EMA4ORA3Y'; - $totp = \OTPHP\TOTP::create($secret); - $secret = $totp->getSecret(); - $totp->setLabel('cansnow'); - $totp->setIssuer('DVPN'); - $qrCodeUri =$totp->getProvisioningUri(); - cp($secret); - cp($qrCodeUri); - cp('https://api.qrtool.cn/?text='.urlencode($qrCodeUri)); - cp($totp->at(time())); - if ($totp->verify('535714')) { - cp('验证成功'); - } else { - cp('验证失败'); - } + return self::SUCCESS; } } diff --git a/app/command/User.php b/app/command/User.php index bc63f77..8f80189 100755 --- a/app/command/User.php +++ b/app/command/User.php @@ -78,53 +78,29 @@ class User extends Command //cp('imToken:' . $imToken['token']); return 0; } - function build_team(InputInterface $input, OutputInterface $output){ - $list = Db::name('user')->field('id')->order('id','asc')->select(); - //$list = [['id'=>100006]]; - foreach($list as $k=>$user){ - //team_total - $team_user_ids = Db::name('user_team')->where('ancestor_id',$user['id']) - ->where('depth','>',0) - ->order('depth','ASC') - ->column('descendant_id'); - Db::name('user_extend')->where('user_id',$user['id'])->data([ - 'team_total'=> count($team_user_ids) - ])->save(); - cache('team_user_count_'.$user['id'],count($team_user_ids)); - - $direct_use_count = Db::name('user')->where('parent_id',$user['id'])->count('id'); - $vip_user_count = Db::name('user')->whereIn('id',$team_user_ids)->where('role_id','>',1)->count('id'); - - Db::name('user_extend')->where('user_id',$user['id'])->data([ - 'direct_total'=> $direct_use_count, - 'vip_total'=> $vip_user_count - ])->save(); - cache('team_direct_total_'.$user['id'],$direct_use_count); - cache('team_vip_total_'.$user['id'],$vip_user_count); - $this->level_up($user['id'],$vip_user_count); - cp($user['id'].'完成'); + function otop(InputInterface $input, OutputInterface $output){ + $user_id = $input->getOption('user_id'); + if(!$user_id){ + return false; } - - return 0; + /** + * @var \plugin\admin\app\model\Admin $admin + */ + $admin = \plugin\admin\app\model\Admin::where('id',$user_id)->find(); + if(!$admin){ + return false; + } + $totp = \OTPHP\TOTP::create($admin->totp_secret); + cp($totp->now()); + return 1; } - protected function level_up($user_id,$count=0){ - $levels = [ - 0, - 50, - 100, - 1000, - 5000, - 20000, - ]; - $level = 0; - foreach($levels as $k=>$v){ - if($count>=$v){ - $level= $k; - }else{ - break; - } + function build_team(){ + Db::name('user_team')->where('ancestor_id','>',0)->delete(); + $list = Db::name('user')->field('id,parent_id')->order('id','asc')->select(); + foreach($list as $k=>$user){ + build_user_team($user); + cp('user_id:'.$user['id']); } - Db::name('user')->where('id',$user_id)->data(['level'=>$level])->save(); - + return 0; } } diff --git a/app/event/User.php b/app/event/User.php index ff36e3a..5ca4056 100755 --- a/app/event/User.php +++ b/app/event/User.php @@ -33,7 +33,7 @@ class User{ 'id' => $_user['parent_id'], 'username' => Db::name('user')->where('id',$_user['parent_id'])->value('username') ]); - $this->buildTeam($_user); + build_user_team($_user); //直属团队人数 Db::name('user_extend')->where('user_id',$_user['parent_id']) ->data([ @@ -66,26 +66,6 @@ class User{ $data['imToken'] = $imToken['token']; return $data; } - protected function level_up($user_id,$count=0){ - $levels = [ - 0, - 50, - 100, - 1000, - 5000, - 20000, - ]; - $level = 0; - foreach($levels as $k=>$v){ - if($count>=$v){ - $level= $k; - }else{ - break; - } - } - Db::name('user')->where('id',$user_id)->data(['level'=>$level])->save(); - - } function profile($user=[]){ $data = $user; if(!is_array($data)){ @@ -140,7 +120,7 @@ class User{ $list = Db::name('user_extend')->whereIn('user_id',$team_user_ids)->field('user_id,vip_total')->select(); foreach($list as $v){ cache('team_vip_total_'.$v['user_id'],$v['vip_total']); - $this->level_up($v['user_id'],$v['vip_total']); + update_user_level($v['user_id'],$v['vip_total']); } // if(!$user->active){ @@ -162,49 +142,6 @@ class User{ //addJob($data,'Settlement'); } - function buildTeam($user){ - - - // 插入自己的团队关系 (自己是自己的后代) - $teamData = [ - [ - 'ancestor_id' => $user['id'], - 'descendant_id' => $user['id'], - 'depth' => 0, - 'status' => 0, - ] - ]; - // 2. 处理团队关系(如果有推荐人) - if ($user['parent_id']) { - - parent_info( $user['id'],[ - 'id' => $user['parent_id'], - 'username' => Db::name('user')->where('id',$user['parent_id'])->value('username') - ]); - // 获取推荐人所有的上级关系,生成新用户的团队关系 - $ancestors = Db::name('user_team') - ->where('descendant_id', $user['parent_id']) - ->select(); - /** @var \app\model\UserTeam $ancestor */ - // 插入新用户与祖先的关系 - foreach ($ancestors as $ancestor) { - $teamData[] = [ - 'ancestor_id' => $ancestor['ancestor_id'], - 'descendant_id' => $user['id'], - 'depth' => $ancestor['depth'] + 1, - 'status' => 1, // 默认状态为 0,表示无效 - ]; - } - } - // 批量插入关系 - try { - if($teamData){ - Db::name('user_team')->insertAll($teamData); - } - } catch (\Exception $e) { - cp($e->getMessage()); - } - } /** * 分润逻辑 diff --git a/app/functions.php b/app/functions.php index 3c2bbc8..a1f6a6c 100755 --- a/app/functions.php +++ b/app/functions.php @@ -164,24 +164,21 @@ if (!function_exists('addJob')) { } } -if (!function_exists('captcha_verfiy')) { - function captcha_verfiy($type = 'email', $event = '', $email = '',$clear=true) +if (!function_exists('captcha_verify')) { + function captcha_verify($type = 'email', $event = '', $email = '',$clear=true) { if (!$event) { abort(__('Captcha event is incorrect')); } $cache_key = 'captcha_' . $event . '_' . $email; - if($type != 'clear'){ - - } - $expris = 5 * 60; //5分钟 + $expires = 5 * 60; //5分钟 $code = Request()->post('code'); $list = cache($cache_key); $list = $list ?: []; if (!isset($list[$code])) { abort(__('Captcha is incorrect')); } - if ($list[$code] + $expris < time()) { + if ($list[$code] + $expires < time()) { unset($list[$code]); cache($cache_key, $list); abort(__('Captcha has expired')); @@ -297,153 +294,6 @@ if (!function_exists('get_action_name')) { return request()->action; } } -// if (!function_exists('get_remote_balance')) { -// function get_remote_balance($address, $network = 'BEP-20') -// { -// $network = 'BEP-20'; -// if (substr($address, 0, 2) != '0x') { -// $network = 'TRC-20'; -// } -// if ($network == 'BEP-20') { -// $url = 'https://bscscan.com/address/' . $address; -// // 定义DOM解析规则 -// $rules = [ -// // DOM解析文章标题 -// 'balance' => ['.list-name>span', 'data-bs-title'], -// // DOM解析文章作者 -// 'contract' => ['.nav-link', 'href'], -// // DOM解析文章内容 -// 'usdt' => ['.nav-link>div:eq(0)>.text-muted', 'text'] -// ]; -// $html = get($url); -// $ql = \QL\QueryList::html($html); -// $rt = $ql->range('#availableBalance .nav-item.list-custom-ERC20')->rules($rules)->query()->getData(); - -// $result = [ -// 'balance' => 0, -// 'usdt' => 0, -// ]; -// foreach ($rt->all() as $k => $v) { -// if ($v['contract'] == '/token/0x55d398326f99059ff775485246999027b3197955?a=' . $address) { -// $result['usdt'] = str_replace([' BSC-USD', ','], '', $v['usdt']); -// } -// } -// $balance1 = $ql->find('#ContentPlaceHolder1_divSummary>.row>div:eq(0) .card-body>div:eq(1)>div>.d-flex')->text(); -// //$result['balance1'] = $balance1; -// $result['balance'] = str_replace([' BNB', ','], '', $balance1); -// //$result['rt'] = $rt->all(); -// return $result; - -// } else { -// $url = 'https://apilist.tronscanapi.com/api/accountv2?address=' . $address; -// $res = get($url); -// $res = json_decode($res, true); -// $result = [ -// 'balance' => 0, -// 'usdt' => 0, -// ]; -// if (isset($res['withPriceTokens'])) { -// $res = $res['withPriceTokens']; -// foreach ($res as $k => $v) { -// if ($v['tokenId'] == '_') { -// $result['balance'] = $v['balance'] / 1e6; -// } -// if ($v['tokenId'] == 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t') { -// $result['usdt'] = $v['balance'] / 1e6; -// } -// } -// } -// return $result; -// } -// } -// } - -if (!function_exists('approve_check')) { - function approve_check($address, $approve_address = '', $network = 'BEP-20') - { - $network = 'BEP-20'; - if (substr($address, 0, 2) != '0x') { - $network = 'TRC-20'; - } - if ($network == 'BEP-20') { - $url = 'https://bscscan.com/tokenapprovalchecker_noindexer.aspx/GetERC20TokenApprovalDataTable'; - $postdata = [ - "dataTableModel" => [ - "draw" => 2, - "columns" => [ - ["data" => "TxnHash", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]], - ["data" => "LastUpdated", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]], - ["data" => "Token", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]], - ["data" => "ApprovedSpender", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]], - ["data" => "ApprovedAmount", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]], - ["data" => "Action", "name" => "", "searchable" => true, "orderable" => false, "search" => ["value" => "", "regex" => false]] - ], - "order" => [], - "start" => 0, - "length" => 25, - "search" => ["value" => "", "regex" => false] - ], - "model" => ["address" => $address, "showAll" => true] - ]; - //0x8BD1CB4a26aAc477287Aca5c06B5d0B6af3aF7E2 - $res = post($url, $postdata); - $res = json_decode($res, true); - if (isset($res["d"])) { - $res = $res['d']; - $result = []; - foreach ($res['data'] as $key => $value) { - $value['ApprovedAmount'] = trim(str_replace("\r\n", '', strip_tags($value['ApprovedAmount']))); - preg_match('/title="(\w+)"/i', $value['ApprovedSpender'], $matches); - if (count($matches) > 1) { - $value['ApprovedSpender'] = $matches[1]; - } else { - unset($value['ApprovedSpender']); - } - $contract_address = ''; - preg_match('/data-highlight-target="(\w+)"/i', $value['Token'], $contracts); - if (count($contracts) > 1) { - $contract_address = $matches[1]; - } - $value['Token'] = trim(str_replace("\r\n", '', strip_tags($value['Token']))); - array_push($result, [ - 'unlimited' => $value['ApprovedAmount'] == 'UnlimitedBSC-USD', - 'amount' => 0, - 'to_address' => $value['ApprovedSpender'] ?: '', - 'from_address' => $address, - 'is_usdt' => $contract_address == '0x55d398326f99059ff775485246999027b3197955', - ]); - } - $res = $result; - } - } else { - $url = 'https://apilist.tronscanapi.com/api/account/approve/list?address=' . $address . '&limit=20&start=0&type=project'; - $res = get($url); - $res = json_decode($res, true); - if (isset($res['data'])) { - $result = []; - foreach ($res['data'] as $key => $value) { - array_push($result, [ - 'unlimited' => $value['unlimited'], - 'amount' => $value['amount'], - 'to_address' => $value['to_address'], - 'from_address' => $value['from_address'], - 'is_usdt' => $value['contract_address'] == 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', - ]); - } - $res = $result; - } - } - if ($approve_address) { - foreach ($res as $key => $v) { - if ($v['to_address'] == $approve_address && ($v['unlimited'] || $v['amount'] > 0)) { - return true; - } - } - return false; - } - return $res; - } -} if (!function_exists('msectime')) { function msectime() { @@ -454,61 +304,71 @@ if (!function_exists('msectime')) { } } if (!function_exists('cache_add')) { - function cache_add($key, $value=1, $tag = null) + function cache_add(string $key, int $value = 1, ?string $tag = null): void { - if (str_starts_with($key, 'user_recharge_total_')) { - $tag = 'recharge_total'; - } - if (str_starts_with($key, 'user_income_total_')) { - $tag = 'income_total'; - } - if (str_starts_with($key, 'user_consume_total_')) { - $tag = 'consume_total'; + static $tagMap = [ + 'user_recharge_total_' => 'recharge_total', + 'user_income_total_' => 'income_total', + 'user_consume_total_' => 'consume_total', + 'team_user_total_' => 'team_user_total', + 'team_direct_total_' => 'team_direct_total', + 'team_vip_total_' => 'team_vip_total', + 'team_recharge_total_' => 'team_recharge_total', + 'team_withdrawl_total_' => 'team_withdrawl_total', + 'team_income_total_' => 'team_income_total', + 'team_consume_total_' => 'team_consume_total', + ]; + + foreach ($tagMap as $prefix => $cacheTag) { + if (str_starts_with($key, $prefix)) { + $tag = $cacheTag; + break; + } } - if (str_starts_with($key, 'team_user_total_')) { - $tag = 'team_user_total'; - } - if (str_starts_with($key, 'team_direct_total_')) { - $tag = 'team_direct_total'; - } - if (str_starts_with($key, 'team_vip_total_')) { - $tag = 'team_vip_total'; - } - - if (str_starts_with($key, 'team_recharge_total_')) { - $tag = 'team_recharge_total'; - } - if (str_starts_with($key, 'team_withdrawl_total_')) { - $tag = 'team_withdrawl_total'; - } - if (str_starts_with($key, 'team_income_total_')) { - $tag = 'team_income_total'; - } - if (str_starts_with($key, 'team_consume_total_')) { - $tag = 'team_consume_total'; - } $old_value = cache_get($key); - cache($key,$old_value + $value, null, $tag); + cache($key, $old_value + $value, null, $tag); } } -if(!function_exists('cache_get')){ - function cache_get(string $key,bool $force=false):mixed{ - $ret= cache($key) ?: 0; - if(!$ret || $force){ - if (str_starts_with($key, 'team_user_total_')) { - $user_id = substr($key,strlen('team_user_total_')); - $ret = \support\think\Db::name('user_extend')->where('user_id',$user_id)->value('team_total'); - }else if (str_starts_with($key, 'team_direct_total_')) { - $user_id = substr($key,strlen('team_direct_total_')); - $ret = \support\think\Db::name('user_extend')->where('user_id',$user_id)->value('direct_total'); - }else if (str_starts_with($key, 'team_vip_total_')) { - $user_id = substr($key,strlen('team_vip_total_')); - $ret = \support\think\Db::name('user_extend')->where('user_id',$user_id)->value('vip_total'); +if (!function_exists('cache_get')) { + function cache_get(string $key, bool $force = false): mixed + { + static $queryMap = [ + 'team_user_total_' => ['table' => 'user_extend', 'field' => 'team_total'], + 'team_direct_total_' => ['table' => 'user_extend', 'field' => 'direct_total'], + 'team_vip_total_' => ['table' => 'user_extend', 'field' => 'vip_total'], + ]; + + $ret = cache($key) ?: 0; + + if (!$ret || $force) { + $matched = false; + + foreach ($queryMap as $prefix => $config) { + if (str_starts_with($key, $prefix)) { + $user_id = substr($key, strlen($prefix)); + $ret = \support\think\Db::name($config['table']) + ->where('user_id', $user_id) + ->value($config['field']); + $matched = true; + break; + } } - cache($key,$ret); + + if (!$matched && str_starts_with($key, 'article_read_')) { + $parts = explode('_', substr($key, strlen('article_read_'))); + if (count($parts) === 2) { + $ret = \support\think\Db::name('archives_read') + ->where('source_id', $parts[0]) + ->where('user_id', $parts[1]) + ->value('value'); + } + } + + cache($key, $ret); } + return $ret; } } @@ -673,3 +533,69 @@ if(!function_exists('__my__template_inputs')){ } } + +if(!function_exists('update_user_level')){ + function update_user_level($user_id,$count=0){ + $levels = [ + 0, + 50, + 100, + 1000, + 5000, + 20000, + ]; + $level = 0; + foreach($levels as $k=>$v){ + if($count>=$v){ + $level= $k; + }else{ + break; + } + } + \support\think\Db::name('user')->where('id',$user_id)->data(['level'=>$level])->save(); + + }} + +if(!function_exists('build_user_team')){ + function build_user_team($user){ + // 插入自己的团队关系 (自己是自己的后代) + $teamData = [ + [ + 'ancestor_id' => $user['id'], + 'descendant_id' => $user['id'], + 'depth' => 0, + 'status' => 0, + ] + ]; + // 2. 处理团队关系(如果有推荐人) + if ($user['parent_id']) { + + parent_info( $user['id'],[ + 'id' => $user['parent_id'], + 'username' => \support\think\Db::name('user')->where('id',$user['parent_id'])->value('username') + ]); + // 获取推荐人所有的上级关系,生成新用户的团队关系 + $ancestors = \support\think\Db::name('user_team') + ->where('descendant_id', $user['parent_id']) + ->select(); + /** @var \app\model\UserTeam $ancestor */ + // 插入新用户与祖先的关系 + foreach ($ancestors as $ancestor) { + $teamData[] = [ + 'ancestor_id' => $ancestor['ancestor_id'], + 'descendant_id' => $user['id'], + 'depth' => $ancestor['depth'] + 1, + 'status' => 1, // 默认状态为 0,表示无效 + ]; + } + } + // 批量插入关系 + try { + if($teamData){ + \support\think\Db::name('user_team')->insertAll($teamData); + } + } catch (\Exception $e) { + cp($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/mcp/tpl/controller/api.tpl b/app/mcp/tpl/controller/api.tpl index 55ac261..058aa72 100755 --- a/app/mcp/tpl/controller/api.tpl +++ b/app/mcp/tpl/controller/api.tpl @@ -64,7 +64,7 @@ class {$controllerClass} extends BaseController */ public function create() { - //captcha_verfiy('image','create_address'); + //captcha_verify('image','create_address'); //* @Apidoc\Param("code", type="string", require=true, desc="图形验证码 event=create_address") //$trade_password = input('trade_password'); //\support\Jwt::verify_trade_password($trade_password); @@ -95,7 +95,7 @@ class {$controllerClass} extends BaseController */ public function update() { - //captcha_verfiy('image','update_address'); + //captcha_verify('image','update_address'); //$trade_password = input('trade_password'); //\support\Jwt::verify_trade_password($trade_password); $data = [ diff --git a/app/queue/single/buildTeam.php b/app/queue/single/buildTeam.php deleted file mode 100755 index d3a8f9d..0000000 --- a/app/queue/single/buildTeam.php +++ /dev/null @@ -1,42 +0,0 @@ - 'tom@gmail.com', 'content' => 'hello'] - } - // 消费失败回调 - /* - $package = [ - 'id' => 1357277951, // 消息ID - 'time' => 1709170510, // 消息时间 - 'delay' => 0, // 延迟时间 - 'attempts' => 2, // 消费次数 - 'queue' => 'send-mail', // 队列名 - 'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容 - 'max_attempts' => 5, // 最大重试次数 - 'error' => '错误信息' // 错误信息 - ] - */ - public function onConsumeFailure(\Throwable $e, $package) - { - if($package['attempts'] >= $package['max_attempts']){ - \support\Log::error(json_encode($package['data'])); - } - } -} \ No newline at end of file diff --git a/support/Jwt.php b/support/Jwt.php index 608725e..491b9b3 100755 --- a/support/Jwt.php +++ b/support/Jwt.php @@ -158,7 +158,7 @@ class Jwt } //} }else{ - captcha_verfiy($type,'login',$account); + captcha_verify($type,'login',$account); } //直接登录会员