From 66bcd8061a4d2355b909793b5b526200e3d754d4 Mon Sep 17 00:00:00 2001 From: commie Date: Wed, 25 Mar 2026 02:48:30 +0800 Subject: [PATCH] 19 --- app/api/controller/CollectionController.php | 93 ++++ app/api/controller/CommonController.php | 2 +- app/api/controller/FriendCircleController.php | 2 +- app/api/controller/MomentsController.php | 450 ++++++++++++++++++ app/api/controller/TeamController.php | 55 +-- app/api/controller/ThaliController.php | 22 +- app/api/controller/UserController.php | 61 ++- app/command/Database.php | 138 +++++- app/command/User.php | 86 +++- app/controller/HookController.php | 1 - app/enum/BalanceType.php | 6 + app/event/User.php | 151 ++++-- app/functions.php | 62 ++- app/model/Collection.php | 45 ++ app/model/UserExtend.php | 1 + app/queue/single/Settlement.php | 78 +++ app/view/common/register.html | 34 +- config/event.php | 9 +- config/log.php | 16 + plugin/admin/public/js/user.js | 10 +- public/index.html | 53 ++- resource/translations/zh-Hans/api/common.php | 1 + support/Jwt.php | 36 +- 23 files changed, 1204 insertions(+), 208 deletions(-) create mode 100644 app/api/controller/CollectionController.php create mode 100644 app/api/controller/MomentsController.php create mode 100644 app/model/Collection.php create mode 100644 app/queue/single/Settlement.php diff --git a/app/api/controller/CollectionController.php b/app/api/controller/CollectionController.php new file mode 100644 index 0000000..46c827a --- /dev/null +++ b/app/api/controller/CollectionController.php @@ -0,0 +1,93 @@ +whereIn('user_id',$user->id) + ->order('created_at', 'desc'); + if($content_type){ + $query->where('content_type',$content_type); + } + if($kw){ + $query->whereLike('content','%'.$kw.'%'); + } + + $list = $query->paginate([ + 'list_rows' => $limit, + 'page' => $page, + ]); + return $this->success('ok', $list); + } + /** + * 创建收藏 + * @Apidoc\Param("content_type", type="string",require=true, desc="内容类型 enum('text', 'image', 'file', 'video', 'link','audio')") + * @Apidoc\Param("content", type="string",require=true, desc="json结构化收藏内容本体") + * @Apidoc\Param("tags", type="string",require=true, desc="用户自定义标签,多个用逗号隔开,或者使用数组") + * @Apidoc\Param("is_pinned", type="int",require=true, desc="是否置顶") + * @param Request $request + * @return Response + */ + function create(Request $request): Response + { + $user = \support\Jwt::getUser(); + $content = $request->post('content'); + $content_type = $request->post('content_type', ''); + $tags = $request->post('tags', ''); + $is_pinned = $request->post('is_pinned', 0); + // 验证内容 + if (empty($content_type)) { + return $this->fail(__('The field %field% must be not empty. ',['field'=>'content_type'])); + } + if (empty($content)) { + return $this->fail(__('The field %field% must be not empty. ',['field'=>'content'])); + } + if(is_array($content)) { + $content = json_encode($content); + } + // 创建朋友圈动态 + $collection = CollectionModel::create([ + 'user_id' => $user->id, + 'content_type' => $content_type, + 'content' => $content, + 'tags' => $tags, + 'is_pinned' => $is_pinned + ]); + + return $this->success('发布成功', ['collection' => $collection]); + } +} \ No newline at end of file diff --git a/app/api/controller/CommonController.php b/app/api/controller/CommonController.php index 672fbc6..3a84c4e 100755 --- a/app/api/controller/CommonController.php +++ b/app/api/controller/CommonController.php @@ -151,7 +151,7 @@ class CommonController extends BaseController{ 'role_id' => 1, 'group_id' => 0, 'region' => '86', - 'nickname' => input('nickname'), + 'nickname' => input('nickname','用户_'.substr($username,7)), 'avatar' => '/static/avatar/'.rand(0,17).'.png', ]; if ($invite_code) { diff --git a/app/api/controller/FriendCircleController.php b/app/api/controller/FriendCircleController.php index 70f020a..abc7458 100755 --- a/app/api/controller/FriendCircleController.php +++ b/app/api/controller/FriendCircleController.php @@ -395,7 +395,7 @@ class FriendCircleController extends BaseController{ $res = request()->IM->friend->getFriendList(\support\Encrypt::userIDencode($user_id)); $friendsInfo = $res['friendsInfo']; foreach($friendsInfo as $k=>$v){ - array_push($result,$v['friendUser']['userID']); + array_push($result,\support\Encrypt::userIDDecode($v['friendUser']['userID'])); } cache($cache_key,$result,3600); } diff --git a/app/api/controller/MomentsController.php b/app/api/controller/MomentsController.php new file mode 100644 index 0000000..6bc7243 --- /dev/null +++ b/app/api/controller/MomentsController.php @@ -0,0 +1,450 @@ +[], + 'unread_item_ids' =>[], + 'unread_count' =>0, + 'settings' => Db::name('user_extend')->where('user_id',$user_id)->field('moments_allow_view_days,moments_banner')->findOrEmpty() + ]; + return $this->success('ok',$json); + }else{ + $user = \support\Jwt::getUser(); + if (!$user) { + return $this->fail('请先登录'); + } + $userID = $user->userID; + $res = $this->newcount($request); + $response = $res->rawBody(); + $json = json_decode($response,true); + $json['data']['settings'] = Db::name('user_extend')->where('user_id',$user->id)->field('moments_allow_view_days,moments_banner')->findOrEmpty(); + + $top_unread_items = FriendCircleModel::whereIn('id',$json['data']['unread_item_ids']) + ->with(['user' => function($query) { + $query->field($this->user_display_fields); + }]) + ->order('id', 'desc') + ->limit(0,3) + ->select(); + $json['data']['top_unread_items'] = $top_unread_items ?: []; + $res->withBody(json_encode($json)); + return $res; + } + } + /** + * @Apidoc\Title("列表") + * @Apidoc\Method("GET") + * @Apidoc\Query("userID", type="string", require=false, desc="用户userID,不传则获取所有") + * @Apidoc\Query("page", type="int", require=true, desc="页码",default=1) + * @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10) + */ + function list(Request $request): Response + { + $current_user = \support\Jwt::getUser(); + $current_user_id = $current_user ? $current_user->id : 0; + $page = (int)Input('page', 1); + $limit = (int)Input('limit', 10); + $userID = Input('userID'); + $query = FriendCircleModel::where('status', 1) + ->with(['user' => function($query) { + $query->field($this->user_display_fields); + }]) + ->order('created_at', 'desc'); + if($userID){ + // 如果指定了用户ID,只获取该用户的朋友圈 + $user_id = \support\Encrypt::userIDDecode($userID); + $query->where('user_id',$user_id); + }else{ + $current_userID = \support\Encrypt::userIDencode($current_user_id); + $query->whereIn('user_id',$this->getFriendUserIds($current_userID)); + } + + $list = $query->paginate([ + 'list_rows' => $limit, + 'page' => $page, + ]); + if(!$userID){ + cache('circle_last_read_id_'.$current_user_id,$list[0]['id']); + } + + + // 处理每条朋友圈数据 + $items = $list->items(); + $list->each(function($item) use ($current_user_id){ + // 获取点赞列表 + $likes = Db::name('friend_circle_like')->alias('f') + ->join('user u','u.id=f.user_id') + ->where('f.circle_id', $item->id) + ->field('f.*,u.userID,u.avatar,u.nickname') + ->order('f.created_at', 'desc') + ->limit(20) + ->select(); + $likes = $likes ? $likes->toArray() : []; + // 检查当前用户是否已点赞 + $is_liked = false; + if ($current_user_id > 0) { + $is_liked = null !== array_find($likes,function($item)use($current_user_id){ + return $item['user_id'] == $current_user_id; + }); + // FriendCircleLikeModel::where('circle_id', $item->id) + // ->where('user_id', $current_user_id) + // ->count() > 0; + } + + + // 获取评论列表(最新10条) + $comments = FriendCircleCommentModel::where('circle_id', $item->id) + ->where('status', 1) + ->with(['user' => function($query) { + $query->field($this->user_display_fields); + }, 'replyUser' => function($query) { + $query->field($this->user_display_fields); + }]) + ->order('created_at', 'asc') + ->limit(10) + ->select(); + + // 格式化数据 + $item->is_liked = $is_liked; + $item->likes = $likes; + $item->comments = $comments; + + // 处理图片URL + if (!empty($item->files)) { + $files = is_array($item->files) ? $item->files : json_decode($item->files, true); + if (is_array($files)) { + $item->files = array_map(function($file) { + return cdnurl($file); + }, $files); + } else { + $item->files = []; + } + } else { + $item->files = []; + } + + // 处理用户头像 + if ($item->user && $item->user->avatar) { + $item->user->avatar = cdnurl($item->user->avatar); + } + + // 处理点赞用户头像 + foreach ($item->likes as $like) { + if ($like->user) { + $like->avatar = cdnurl($like->avatar); + } + } + + // 处理评论用户头像 + foreach ($item->comments as $comment) { + if ($comment->user && $comment->user->avatar) { + $comment->user->avatar = cdnurl($comment->user->avatar); + } + if ($comment->replyUser && $comment->replyUser->avatar) { + $comment->replyUser->avatar = cdnurl($comment->replyUser->avatar); + } + } + return $item; + }); + + return $this->success('ok', $list); + } + + /** + * @Apidoc\Title("最近更新的数量") + * @Apidoc\Method("POST") + * @Apidoc\Param("last_see", type="string",require=false, desc="最近查看的时间戳") + */ + function newcount(Request $request): Response + { + $user = \support\Jwt::getUser(); + if (!$user) { + return $this->fail('请先登录'); + } + $user_id = $user->id; + $circle_last_read_id = cache('circle_last_read_id_'.$user_id) ?: 0; + $userID = \support\Encrypt::userIDencode($user_id); + // 统计从上次查看时间到现在新增的朋友圈数量 + $unread_item_ids = FriendCircleModel::where('status', 1) + ->whereIn('user_id',$this->getFriendUserIds($userID)) + ->where('id', '>', $circle_last_read_id) + ->order('id', 'desc') + ->column('id'); + + + return $this->success('ok', [ + 'unread_count' => count($unread_item_ids), + 'unread_item_ids'=>$unread_item_ids + ]); + } + + /** + * @Apidoc\Title("发布朋友圈") + * @Apidoc\Method("POST") + * @Apidoc\Param("body", type="string",require=false, desc="内容") + * @Apidoc\Param("files", type="string",require=false, desc="图片列表(JSON数组)") + */ + function create(Request $request): Response + { + $user = \support\Jwt::getUser(); + if (!$user) { + return $this->fail('请先登录'); + } + + $body = $request->post('content', ''); + $files = $request->post('files', ''); + $address = $request->post('address', ''); + $releaseType = $request->post('releaseType', ''); + // 验证内容 + if (empty($body)) { + return $this->fail('什么内容都木有啊'); + } + + + // 处理图片列表 + $files_array = []; + if (!empty($files)) { + if (is_string($files)) { + $files_array = json_decode($files, true); + } elseif (is_array($files)) { + $files_array = $files; + } + + if (!is_array($files_array)) { + return $this->fail('图片列表格式错误'); + } + + // 限制图片数量 + if (count($files_array) > 9) { + return $this->fail('最多只能上传9张图片'); + } + } + + // 创建朋友圈动态 + $circle = FriendCircleModel::create([ + 'user_id' => $user->id, + 'releaseType' => $releaseType, + 'body' => $body, + 'files' => $files_array, + 'address' => $address, + 'status' => 1, + ]); + + return $this->success('发布成功', ['id' => $circle->id,'data' => $circle]); + } + + /** + * @Apidoc\Title("发表评论") + * @Apidoc\Method("POST") + * @Apidoc\Param("body", type="string",require=true, desc="内容") + * @Apidoc\Param("id", type="int",require=true, desc="朋友圈动态ID") + * @Apidoc\Param("reply_userID", type="string",require=false, desc="回复的用户userID(回复评论时使用)") + */ + function comment(Request $request): Response + { + $user = \support\Jwt::getUser(); + if (!$user) { + return $this->fail('请先登录'); + } + + $body = $request->post('body', ''); + $circle_id = (int)$request->post('id'); + $reply_userID = (int)$request->post('reply_userID'); + + if (empty($body)) { + return $this->fail('评论内容不能为空'); + } + + if ($circle_id <= 0) { + return $this->fail('朋友圈动态ID错误'); + } + + // 检查朋友圈动态是否存在 + $circle = FriendCircleModel::where('id', $circle_id) + ->where('status', 1) + ->find(); + + if (!$circle) { + return $this->fail('朋友圈动态不存在'); + } + + // 如果回复评论,检查被回复的用户是否存在 + $reply_user_id = 0; + if ($reply_userID ) { + $reply_user_id = \support\Encrypt::userIDDecode($reply_userID); + } + if ($reply_user_id>0 ) { + $reply_user = UserModel::where('id', $reply_user_id)->find(); + if (!$reply_user) { + return $this->fail('被回复的用户不存在'); + } + } + + // 创建评论 + $comment = FriendCircleCommentModel::create([ + 'circle_id' => $circle_id, + 'user_id' => $user->id, + 'reply_user_id' => $reply_user_id, + 'body' => $body, + 'status' => 1, + ]); + + // 更新朋友圈评论数 + $circle->comment_count = FriendCircleCommentModel::where('circle_id', $circle_id) + ->where('status', 1) + ->count(); + $circle->save(); + $comment->user = Db::name('user')->field($this->user_display_fields)->where('id',$comment->user_id)->find(); + $comment->replyUser=null; + if($comment->reply_user_id){ + $comment->replyUser = Db::name('user')->field($this->user_display_fields)->where('id',$comment->reply_user_id)->find(); + } + return $this->success('评论成功', $comment); + } + + /** + * @Apidoc\Title("点赞") + * @Apidoc\Method("POST") + * @Apidoc\Param("id", type="int",require=true, desc="朋友圈动态ID") + */ + function like(Request $request): Response + { + $user = \support\Jwt::getUser(); + if (!$user) { + return $this->fail('请先登录'); + } + + $circle_id = (int)$request->post('id', 0); + + if ($circle_id <= 0) { + return $this->fail('朋友圈动态ID错误'); + } + + // 检查朋友圈动态是否存在 + $circle = FriendCircleModel::where('id', $circle_id) + ->where('status', 1) + ->find(); + + if (!$circle) { + return $this->fail('朋友圈动态不存在'); + } + + // 检查是否已点赞 + $like = FriendCircleLikeModel::where('circle_id', $circle_id) + ->where('user_id', $user->id) + ->find(); + + if ($like) { + // 取消点赞 + $like->delete(); + $circle->like_count = max(0, $circle->like_count - 1); + $circle->save(); + return $this->success('取消点赞成功', ['is_liked' => false]); + } else { + // 添加点赞 + FriendCircleLikeModel::create([ + 'circle_id' => $circle_id, + 'user_id' => $user->id, + ]); + $circle->like_count = $circle->like_count + 1; + $circle->save(); + return $this->success('点赞成功', ['is_liked' => true]); + } + } + protected function getFriendUserIds($userID):array{ + if (!$userID) { + return []; + } + $cache_key = 'friend_id_list_'.$userID; + $result = cache($cache_key) ?: []; + if(count($result) === 0){ + $res = request()->IM->friend->getFriendList($userID); + $friendsInfo = $res['friendsInfo']; + foreach($friendsInfo as $k=>$v){ + array_push($result,\support\Encrypt::userIDDecode($v['friendUser']['userID'])); + } + cache($cache_key,$result,3600); + } + $result[] = \support\Encrypt::userIDDecode($userID); + return $result; + } + function delete(Request $request): Response{ + $id = $request->post('id'); + $user = \support\Jwt::getUser(); + if (!$user) { + return $this->fail('请先登录'); + } + if($id){ + FriendCircleModel::where('id',$id)->where('user_id',$user->id)->delete(); + } + return $this->success('删除成功'); + } + /** + * 设置朋友圈背景 + * @param Request $request + * @return Response + */ + function upload_bg(Request $request){ + return $this->setBanner($request); + } + /** + * 设置朋友圈背景 + * @param Request $request + * @return Response + */ + function setBanner(Request $request){ + try { + $user = \support\Jwt::getUser(); + if (!$user) { + return $this->fail('请先登录'); + } + $res = $this->_upload($request); + if(is_string($res)){ + return $this->fail( $res); + } + + Db::name('user_extend')->where('user_id',$user->id)->save([ + 'moments_banner' => $res[0]['file_name'], + ]); + return $this->success(__('successful'),[ + 'url'=>$res[0]['file_name'] + ]); + }catch (\Exception $e){ + return $this->error($e->getMessage()); + } + } + +} \ No newline at end of file diff --git a/app/api/controller/TeamController.php b/app/api/controller/TeamController.php index 026b6bd..17fb15d 100755 --- a/app/api/controller/TeamController.php +++ b/app/api/controller/TeamController.php @@ -31,21 +31,23 @@ class TeamController extends BaseController{ $user = \support\Jwt::getUserinfo(); $user_id = $user['id']; $user= Hook('user.profile',$user); - $team_ids = UserTeamModel::where('ancestor_id',$user_id)->where('depth','>',0)->column('descendant_id'); + //$team_ids = UserTeamModel::where('ancestor_id',$user_id)->where('depth','>',0)->column('descendant_id'); $result=[ - 'total_count' => count($team_ids),//团队总人数 - 'direct_total' => cache('team_direct_total_'.$user_id)??0,//直属团队人数 - 'recharge_total' => cache('team_recharge_total_'.$user_id)??0, - 'withdrawl_total' => cache('team_withdrawl_total_'.$user_id)??0, - 'income_total' => cache('team_income_total_'.$user_id)??0, - 'today_income_total' => cache('user_today_income_total_'.$user_id)??0, - 'promotion_income_total' => cache('user_promotion_income_total_'.$user_id)??0, - 'consume_total' => Db::name('user_extend')->where('user_id',$user_id)->value('sales'),//cache('team_consume_total_'.$user_id)??0,//团队总业绩 - 'user_sales_reward' => cache('user_sales_reward_'.$user_id)??0,//销售奖 - 'user_output_reward' => cache('user_output_reward_'.$user_id)??0,//产值奖 - 'user_withdrawl_reward' => cache('user_withdrawl_reward'.$user_id)??0,//提现奖 - 'user' => $user[0], + 'level' => $user['level'], + 'total_count' => cache_get('team_user_count_'.$user_id),//团队总人数 + 'direct_total' => cache_get('team_direct_total_'.$user_id),//直属团队人数 + 'vip_total' => cache_get('team_vip_total_'.$user_id),//旗下会员总数 + // 'recharge_total' => cache('team_recharge_total_'.$user_id)??0, + // 'withdrawl_total' => cache('team_withdrawl_total_'.$user_id)??0, + // 'income_total' => cache('team_income_total_'.$user_id)??0, + // 'today_income_total' => cache('user_today_income_total_'.$user_id)??0, + // 'promotion_income_total' => cache('user_promotion_income_total_'.$user_id)??0, + // 'consume_total' => cache('team_consume_total_'.$user_id)??0,//团队总业绩 + // 'user_sales_reward' => cache('user_sales_reward_'.$user_id)??0,//销售奖 + // 'user_output_reward' => cache('user_output_reward_'.$user_id)??0,//产值奖 + // 'user_withdrawl_reward' => cache('user_withdrawl_reward'.$user_id)??0,//提现奖 + 'user' => $user[0], ]; return $this->success(__('successful'),$result); @@ -120,7 +122,7 @@ class TeamController extends BaseController{ ->join('user_extend ue', 'u.id = ue.user_id') ->where('u.parent_id', $user['id']) //->where('ue.active', 1) - ->field('u.id,u.userID, u.username,u.money,u.score,u.role_id, u.group,u.avatar, u.created_at') + ->field('u.id,u.userID, u.username,u.nickname,u.money,u.score,u.role_id,u.avatar, u.created_at') ->order('u.created_at desc'); if($kw){ $model = $model->whereLike("u.username",'%'.$kw.'%'); @@ -139,33 +141,22 @@ class TeamController extends BaseController{ }else{ $result = $model->paginate($limit); } - $role_arr = [ - '0' => __('普通用户'), - '1' => __('V1'), - '2' => __('V2'), - '3' => __('V3'), - '4' => __('V4'), - '5' => __('V5'), - ]; $result = $result->toArray(); foreach($result['data'] as $k=>$item){ $result['data'][$k]['avatar'] = cdnurl($item['avatar'] ?: '/storage/avatar/default.png'); - $result['data'][$k]['recharge_total'] = cache('user_recharge_total_'.$item['id'])??0; - $result['data'][$k]['withdrawl_total'] = cache('user_withdrawl_total_'.$item['id'])??0; - $result['data'][$k]['withdrawl_reward'] = cache('user_withdrawl_reward_'.$item['id'])??0; - $result['data'][$k]['income_total'] = cache('user_income_total_'.$item['id'])??0; - $result['data'][$k]['consume_total'] = cache('user_consume_total_'.$item['id'])??0; - $result['data'][$k]['play_count'] = cache('user_play_count_'.$item['id'])??0; + //$result['data'][$k]['recharge_total'] = cache('user_recharge_total_'.$item['id'])??0; + //$result['data'][$k]['withdrawl_total'] = cache('user_withdrawl_total_'.$item['id'])??0; + //$result['data'][$k]['withdrawl_reward'] = cache('user_withdrawl_reward_'.$item['id'])??0; + //$result['data'][$k]['income_total'] = cache('user_income_total_'.$item['id'])??0; + //$result['data'][$k]['consume_total'] = cache('user_consume_total_'.$item['id'])??0; //$result['data'][$k]['created_at'] = date('Y-m-d H:i:s', $item['created_at']); - $result['data'][$k]['total_count'] = UserTeamModel::where('ancestor_id',$item['id'])->where('status',1)->where('depth','>',0)->count('descendant_id'); - $result['data'][$k]['direct_total'] = cache('team_direct_total_'.$item['id'])??0; - $result['data'][$k]['role'] = isset($role_arr[$item['role_id']]) ? $role_arr[$item['role_id']] : __('普通用户'); - //$result['data'][$k]['questionnaire_count'] = WorkRecordModel::where('user_id',$item['id'])->count('id'); //return $item; } return $this->success(__('successful'),$result); } /** + * @Apidoc\NotParse() + * @Apidoc\NotDebug() * @Apidoc\Title("改变用户等级") * @Apidoc\Method("POST") * @Apidoc\Param("id", type="string",require=false, desc="ID") diff --git a/app/api/controller/ThaliController.php b/app/api/controller/ThaliController.php index 3e0a470..d2dff27 100755 --- a/app/api/controller/ThaliController.php +++ b/app/api/controller/ThaliController.php @@ -113,6 +113,11 @@ class ThaliController extends BaseController{ if($quantity == 12){ $price = $thali->year_price; } + //新开通 + $isNew=false; + if(is_null($user->role_id)){ + $isNew = true; + } //升级 $isUpgrade=true; //续费 @@ -145,14 +150,15 @@ class ThaliController extends BaseController{ \app\model\User::score($user->id,-$amount,\app\enum\BalanceType::PURCHASE_ROLE,json_encode(['role_id'=>$role_id,'quantity'=>$quantity,'role_name'=>$thali->title])); cache('user_rights_'.$user->id,null); - //Hook('user.roleup', $user); - // $data = [ - // 'role_id' => $role_id, - // 'user_id' => $user->id, - // 'parent_id' => $user->parent_id, - // 'amount' => $amount, - // ]; - // Hook('role.buy', $data); + if($isNew){ + Hook('user.role_up', $user); + } + $data = [ + 'role_id' => $role_id, + 'user_id' => $user->id, + 'amount' => $amount, + ]; + Hook('user.role_buy', $data); return $this->success(__('successful'),$user); } } \ No newline at end of file diff --git a/app/api/controller/UserController.php b/app/api/controller/UserController.php index eb16cbe..a38566c 100755 --- a/app/api/controller/UserController.php +++ b/app/api/controller/UserController.php @@ -31,7 +31,8 @@ class UserController extends BaseController{ * @Apidoc\Desc("GET为获取用户信息,POST为修改数据") * @Apidoc\Param("nickname", type="string",require=true, desc="昵称") */ - public function profile(){ + public function profile() + { $data = \support\Jwt::getUser(); if(Request()->method() == 'POST'){ $nickname = input('nickname'); @@ -60,6 +61,7 @@ class UserController extends BaseController{ } return $this->success(__('successful')); } + $data = \support\Jwt::getUserInfo($data); $data= Hook('user.profile',$data); return $this->success(__('successful'),$data[0]); } @@ -147,6 +149,25 @@ class UserController extends BaseController{ \support\Jwt::getUser()->save($data); return $this->success(__('successful'),$data); } + /** + * 设置个人banner + * @Apidoc\Method("POST") + * @Apidoc\Param("file", type="File", require=true, desc="文件") + */ + public function setBanner(Request $request) + { + $user_id = \support\Jwt\JwtToken::getCurrentId(); + //单文件上传 + $res = $this->_upload($request); + if(is_string($res)){ + return $this->fail( $res); + } + $data = [ + 'profile_banner' => $res[0]['file_name'], + ]; + Db::name('user_extend')->where('user_id',$user_id)->save($data); + return $this->success(__('successful'),$data); + } function realname(Request $request): Response { /** @@ -201,30 +222,15 @@ class UserController extends BaseController{ } //$userIDs = array_map('\support\Encrypt::userIDDecode',$ids); //$res = $request->IM->user->getUsersInfo($userIDs); - $list = Db::name('user')-> - whereIn('userID',$ids) + $list = Db::name('user')->alias('u') + ->leftJoin('user_extend ue','ue.user_id=u.id') + ->field('u.*,ue.profile_banner') + ->whereIn('u.userID',$ids) ->paginate(Input('limit',10)); $list->each(function($user){ - $user['id'] = $user['userID']; - unset($user['password']); - unset($user['trade_password']); - //unset($user['avatar']); - unset($user['online']); - unset($user['token']); - unset($user['prev_time']); - unset($user['loginfailure']); - unset($user['successions']); - unset($user['maxsuccessions']); - unset($user['currency1']); - unset($user['currency2']); - unset($user['currency3']); - unset($user['currency4']); - unset($user['currency5']); - unset($user['currency6']); - unset($user['currency7']); - unset($user['currency8']); - unset($user['currency9']); - return $user; + $data = \support\Jwt::getUserInfo($user); + $data= Hook('user.profile',$data); + return $data[0]; //$user->hidden(['password']); }); @@ -240,9 +246,12 @@ class UserController extends BaseController{ { $keyword = Input('keyword'); $searchtype = Input('searchtype'); - $fields = 'userID,avatar,username,nickname,avatar,sex,email,mobile,birthday,bio'; - $model = Db::name('user')->field($fields)->where('status',1); - $model = $model->where('userID',$keyword); + $fields = 'u.userID,u.avatar,u.username,u.nickname,u.avatar,u.sex,u.email,u.mobile,u.birthday,u.bio,ue.profile_banner'; + $model = Db::name('user')->alias('u') + ->join('user_extend ue','ue.user_id=u.id') + ->field($fields) + ->where('status',1); + $model = $model->where('u.userID',$keyword); // if($searchtype =='id'){ // $model = $model->where('id',$keyword); // }else{ diff --git a/app/command/Database.php b/app/command/Database.php index 985dbd7..34c0d1d 100755 --- a/app/command/Database.php +++ b/app/command/Database.php @@ -10,6 +10,9 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Output\OutputInterface; use support\think\Db; use app\model\User as UserModel; +use \think\db\PDOConnection; +use think\db\exception\PDOException; +use think\db\exception\InvalidArgumentException; class Database extends Command @@ -22,10 +25,12 @@ class Database extends Command */ protected function configure() { - $this->addOption('action','a', InputArgument::OPTIONAL, '要做什么操作'); - $this->addOption('table','t', InputArgument::OPTIONAL, '表名'); - $this->addOption('domain','ym', InputArgument::OPTIONAL, 'domain'); - $this->addOption('robot_id','rid', InputArgument::OPTIONAL, 'robot_id'); + $this->addOption('action','a', InputOption::VALUE_OPTIONAL, '要做什么操作'); + $this->addOption('table','t', InputOption::VALUE_OPTIONAL, '表名'); + $this->addOption('domain','ym', InputOption::VALUE_OPTIONAL, 'domain'); + $this->addOption('connection','c', InputOption::VALUE_OPTIONAL, '数据库链接名,默认mysql','mysql'); + $this->addOption('dir','d', InputOption::VALUE_OPTIONAL, '缓存目录'); + $this->addOption('robot_id','rid', InputOption::VALUE_OPTIONAL, 'robot_id'); } /** @@ -36,12 +41,32 @@ class Database extends Command protected function execute(InputInterface $input, OutputInterface $output): int { $action = $input->getOption('action'); - if($action == 'prototype'){ - return $this->prototype($input, $output); + if(method_exists($this, $action)){ + return $this->$action($input, $output); } cp('操作不存在:'.$action); return 0; } + function optimize_schema(InputInterface $input, OutputInterface $output) + { + $table = $input->getOption('table'); + try { + if ($table) { + $this->cacheTable($table, $input->getOption('connection')); + } else { + $dirs = ((array) $input->getOption('dir')) ?: $this->getDefaultDirs(); + foreach ($dirs as $dir) { + $this->cacheModel($dir); + } + } + } catch (\Exception $e) { + $output->write($e->getMessage()); + return self::FAILURE; + } + + $output->write('Succeed!'); + return self::SUCCESS; + } function prototype(InputInterface $input, OutputInterface $output){ $table = $input->getOption('table'); // 获取表前缀并构建完整表名 @@ -132,4 +157,105 @@ class Database extends Command // 默认返回混合类型 return 'mixed'; } + + + protected function buildModelSchema(string $class): void + { + $reflect = new \ReflectionClass($class); + if ($reflect->isAbstract() || ! $reflect->isSubclassOf('\think\Model')) { + return; + } + try { + /** @var \think\Model $model */ + $model = new $class; + $connection = $model->db()->getConnection(); + if ($connection instanceof PDOConnection) { + $table = $model->getTable(); + //预读字段信息 + $connection->getSchemaInfo($table, true); + } + } catch (Exception $e) { + } + } + + protected function buildDataBaseSchema(PDOConnection $connection, array $tables, string $dbName): void + { + foreach ($tables as $table) { + //预读字段信息 + $connection->getSchemaInfo("{$dbName}.{$table}", true); + } + } + + /** + * 缓存表 + */ + private function cacheTable(string $table, ?string $connectionName = null): void + { + $connection = Db::connect($connectionName); + if (! $connection instanceof PDOConnection) { + throw new Exception('only PDO connection support schema cache!'); + } + + if (str_contains($table, '.')) { + [$dbName, $table] = explode('.', $table); + } else { + $dbName = $connection->getConfig('database'); + } + + if ($table == '*') { + $table = $connection->getTables($dbName); + } + + $this->buildDataBaseSchema($connection, (array) $table, $dbName); + } + + /** + * 缓存模型 + */ + private function cacheModel(?string $dir = null): void + { + if ($dir) { + $modelDir = app_path('model') . $dir . DIRECTORY_SEPARATOR; + $namespace = 'app\\' . $dir; + } else { + $modelDir = app_path('model').DIRECTORY_SEPARATOR; + $namespace = 'app'; + } + if (! is_dir($modelDir)) { + throw new InvalidArgumentException("{$modelDir} directory does not exist"); + } + + /** @var \SplFileInfo[] $iterator */ + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($modelDir, \RecursiveDirectoryIterator::SKIP_DOTS), + \RecursiveIteratorIterator::SELF_FIRST + ); + + foreach ($iterator as $fileInfo) { + $relativePath = substr($fileInfo->getRealPath(), strlen($modelDir)); + if (! str_ends_with($relativePath, '.php')) { + continue; + } + // 去除 .php + $relativePath = substr($relativePath, 0, -4); + + $class = '\\' . $namespace . '\\model\\' . str_replace('/', '\\', $relativePath); + if (! class_exists($class)) { + continue; + } + + $this->buildModelSchema($class); + } + } + + /** + * 获取默认目录名 + * @return array + */ + private function getDefaultDirs(): array + { + // 包含默认的模型目录 + $dirs = [null]; + return $dirs; + } } diff --git a/app/command/User.php b/app/command/User.php index ef7071f..1ab792a 100755 --- a/app/command/User.php +++ b/app/command/User.php @@ -32,26 +32,76 @@ class User extends Command */ protected function execute(InputInterface $input, OutputInterface $output): int { - $action = $input->getOption('action','login'); - if($action == 'login'){ - $IM = new \support\OpenImSdk\Client([ - 'host' => 'http://127.0.0.1:10002', // OpenIM API地址 - 'secret' => 'n1e5a6s6m7', // OpenIM密钥 - ]); - $user_id = $input->getOption('user_id'); - if(!$user_id){ - return false; - } - $user = \support\Jwt::direct($user_id); - $imToken = $IM->auth->getUserToken($user['userID'],2); - cp('userID:' . $user['id']); - cp('nickname:' . $user['nickname']); - cp('token:' . $user['token']); - cp('imToken:' . $imToken['token']); - return 0; + $action = $input->getOption('action'); + if(method_exists($this, $action)){ + return $this->$action($input, $output); } - cp('action not exist'); + cp('操作不存在:'.$action); return 0; } + function login(InputInterface $input, OutputInterface $output){ + // $IM = new \support\OpenImSdk\Client([ + // 'host' => 'http://127.0.0.1:10002', // OpenIM API地址 + // 'secret' => 'n1e5a6s6m7', // OpenIM密钥 + // ]); + $user_id = $input->getOption('user_id'); + if(!$user_id){ + return false; + } + $user = \support\Jwt::direct($user_id); + //$imToken = $IM->auth->getUserToken($user['userID'],2); + cp('userID:' . $user['id']); + cp('nickname:' . $user['nickname']); + cp('token:' . $user['token']); + //cp('imToken:' . $imToken['token']); + return 0; + } + function build_team(InputInterface $input, OutputInterface $output){ + $list = Db::name('user')->field('id')->order('id','asc')->select(); + foreach($list as $k=>$user){ + //team_total + $team_user_ids = Db::name('user_team')->where('descendant_id',$user['id']) + ->where('depth','>',0) + ->order('depth','ASC') + ->column('ancestor_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','>',0)->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); + } + + return 0; + } + protected function level_up($user_id,$count=0){ + $levels = [ + 0, + 500, + 1000, + 5000, + 10000, + 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(); + + } } diff --git a/app/controller/HookController.php b/app/controller/HookController.php index 064300f..9fc0b68 100755 --- a/app/controller/HookController.php +++ b/app/controller/HookController.php @@ -153,7 +153,6 @@ class HookController{ public function callbackAfterUserOfflineCommand(Request $request): Response{ $user_id = Input('userID'); - //Db::name('user')->where('id',$user_id)->update(['online'=>0]); return $this->success(); } diff --git a/app/enum/BalanceType.php b/app/enum/BalanceType.php index 97b3e0c..69ab9ed 100755 --- a/app/enum/BalanceType.php +++ b/app/enum/BalanceType.php @@ -58,6 +58,10 @@ enum BalanceType: int * 购买积分卡 */ case GIFT_BUY = 407; + /** + * 购买积分卡 + */ + case SEE_POINT_AWARD = 901; /** * 获取所有类型映射数组 @@ -78,6 +82,8 @@ enum BalanceType: int self::PURCHASE_ROLE->value => __('购买角色'), self::GIFT_BUY->value => __('购买积分卡'), + + self::SEE_POINT_AWARD->value => __('见点奖'), ]; diff --git a/app/event/User.php b/app/event/User.php index f6e59d9..f49fe92 100755 --- a/app/event/User.php +++ b/app/event/User.php @@ -4,35 +4,55 @@ use support\think\Db; use Request; use Symfony\Component\Console\Input\Input; class User{ - function register_successed($user){ + function register_successed($user) + { + $_user = $user; + if(!is_array($_user)){ + $_user = $_user->toArray(); + } $date = date('Y-m-d'); cache_add('statistics_register_'.$date,1); $saveData = [ - 'invite_code' => build_invite_code($user->id), - 'userID' => \support\Encrypt::userIDencode($user->id) + //'invite_code' => build_invite_code($_user['id']), + 'invite_code' => \support\Encrypt::userIDencode($_user['id']), + 'userID' => \support\Encrypt::userIDencode($_user['id']) ]; //管理直推人数和团队人数 - if($user->parent_id){ - parent_info( $user->id,[ - 'id' => $user->parent_id, - 'username' => Db::name('user')->where('id',$user->parent_id)->value('username') - ]); - //管理直推人数 - cache_add('team_direct_total_'.$user->parent_id,1); - \app\model\UserExtend::where('user_id',$user->parent_id)->save([ - 'direct_total' => Db::raw('direct_total+1'), - 'team_total' => Db::raw('team_total+1'), + if($_user['parent_id']){ + parent_info( $_user['id'],[ + 'id' => $_user['parent_id'], + 'username' => Db::name('user')->where('id',$_user['parent_id'])->value('username') ]); + //直属团队人数 + Db::name('user_extend')->where('user_id',$_user['parent_id']) + ->data([ + 'direct_total'=> Db::raw('direct_total+1') + ])->save(); + cache_add('team_direct_total_'.$_user['parent_id'],1); + + //管理团队人数 + $team_user_ids = Db::name('user_team')->where('descendant_id',$user['id']) + ->where('depth','>',0) + ->order('depth','ASC') + ->column('ancestor_id'); + + Db::name('user_extend')->whereIn('user_id',$team_user_ids)->data([ + 'team_total'=> Db::raw('team_total+1') + ])->save(); + $list = Db::name('user_extend')->whereIn('user_id',$team_user_ids)->field('user_id,team_total')->select(); + foreach($list as $v){ + cache('team_user_count_'.$v['user_id'],$v['team_total']); + } } - \app\model\User::where('id',$user->id)->update($saveData); + \app\model\User::where('id',$_user['id'])->update($saveData); //创建扩展数据 - \app\model\UserExtend::create([ - 'user_id' => $user->id, - 'direct_total' => 0, - 'team_total' => 0, - 'consume' => 0, - 'sales' => 0 + Db::name('user_extend')->replace()->insert([ + 'user_id' => $_user['id'], + 'consume' => 0, + // 'profile_banner' => '', + // 'moments_banner' => '', + // 'moments_allow_view_days'=>0, ]); @@ -44,41 +64,51 @@ class User{ * @var \support\OpenImSdk\Client $IM */ $IM = request()->IM; - log_alert($data['userID']); $imToken = $IM->auth->getUserToken($data['userID'],Input('platform')); $data['imToken'] = $imToken['token']; return $data; } + protected function level_up($user_id,$count=0){ + $levels = [ + 0, + 500, + 1000, + 5000, + 10000, + 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)){ $data = $data->toArray(); } - $role_arr = [ - '1' => __('普通用户'), - '2' => __('VIP'), - ]; - $data['has_trade_password'] = $data['trade_password'] ? true: false; - $data['avatar'] = cdnurl($data['avatar']); - $disallowFields = ['trade_password','password','client','loginfailure']; - $data = array_diff_key($data, array_flip($disallowFields)); - $data['recharge_total'] = cache('user_recharge_total_'.$data['id'])?:0; - $data['withdrawl_total'] = cache('user_withdrawl_total_'.$data['id'])?:0; - $data['income_total'] = cache('user_income_total_'.$data['id'])?:0; - $data['today_income'] = cache('user_today_income_'.date('Ymd').'_'.$data['id'])?:0; - $data['month_income'] = cache('user_month_income_'.date('Ym').'_'.$data['id'])?:0; - $data['consume_total'] = cache('user_consume_total_'.$data['id'])?:0; - $data['power_total'] = cache('user_power_total_'.$data['id'])?:0; - $data['role_reward_total'] = cache('user_role_reward_total_'.$data['id'])?:0; - $data['avatar'] = $data['avatar']?:"/static/img/avatar.png"; - $data['role'] = isset($role_arr[$data['role_id']]) ? $role_arr[$data['role_id']] : __('普通用户');//\app\model\UserRole::where('id',$data['role_id'])->value('name'); - $last_see = $last_see ?? cache('last_see_'.$data['id']); $count = 0; - $data['friend_settings'] = [ - 'unread_count' => $count ??0, + $ff = [ + 'unread_count' => 0, 'userHeadImg' => null, ]; + try { + $ff = Db::name('user_extend')->where('user_id',$user->id)->field('moments_allow_view_days,profile_banner,moments_banner')->find(); + $data['moments_allow_view_days'] = $ff['moments_allow_view_days']; + $data['moments_banner'] = $ff['moments_banner']; + $data['profile_banner'] = $ff['profile_banner']; + $ff['userHeadImg'] = $ff['moments_banner']; + } catch (\Exception $e) { + } + $ff['unread_count'] = $count ?:0; + $data['friend_settings'] = $ff; return $data; } function changepwd_successed($data=[]){ @@ -94,18 +124,45 @@ class User{ return $data; } //用户角色组变化 - function roleup($user=[]){ + function role_up($user=[]){ $data = $user; if(!is_array($data)){ $data = $data->toArray(); } - if(!$user->active){ - $user->active = 1; - $user->save(); - cache_add('team_direct_total_'.$user->parent_id,1); + //旗下会员总数 + $team_user_ids = Db::name('user_team')->where('descendant_id',$user['id']) + ->where('depth','>',0) + ->order('depth','ASC') + ->column('ancestor_id'); + Db::name('user_extend')->whereIn('user_id',$team_user_ids) + ->data([ + 'vip_total'=> Db::raw('vip_total+1') + ]) + ->save(); + $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']); } + + // if(!$user->active){ + // $user->active = 1; + // $user->save(); + // cache_add('team_direct_total_'.$user->parent_id,1); + // } return $user; } + //用户角色组变化 + function role_buy($data=[]) + { + // $data = [ + // 'role_id'=>1, + // 'user_id'=>100008, + // 'amount'=>1000 + // ]; + + //addJob($data,'Settlement'); + } function buildTeam($user){ diff --git a/app/functions.php b/app/functions.php index 837880d..b1a06fb 100755 --- a/app/functions.php +++ b/app/functions.php @@ -179,7 +179,7 @@ if (!function_exists('captcha_verfiy')) { $list = cache($cache_key); $list = $list ?: []; if (!isset($list[$code])) { - abort(__('Captcha is incorrect').$cache_key.$code); + abort(__('Captcha is incorrect')); } if ($list[$code] + $expris < time()) { unset($list[$code]); @@ -456,50 +456,62 @@ if (!function_exists('msectime')) { if (!function_exists('cache_add')) { function cache_add($key, $value=1, $tag = null) { - if (substr($key, 0, 20) == 'user_recharge_total_') { + if (str_starts_with($key, 'user_recharge_total_')) { $tag = 'recharge_total'; } - if (substr($key, 0, 20) == 'user_recharge_total_') { - $tag = 'recharge_total'; - } - if (substr($key, 0, 17) == 'user_power_total_') { - $tag = 'user_power_total'; - } - if (substr($key, 0, 18) == 'user_income_total_') { + if (str_starts_with($key, 'user_income_total_')) { $tag = 'income_total'; } - if (substr($key, 0, 16) == 'user_play_count_') { - $tag = 'play_count'; - } - if (substr($key, 0, 19) == 'user_consume_total_') { + if (str_starts_with($key, 'user_consume_total_')) { $tag = 'consume_total'; } - if (substr($key, 0, 18) == 'team_member_total_') { - $tag = 'team_member_total'; + if (str_starts_with($key, 'team_user_total_')) { + $tag = 'team_user_total'; } - if (substr($key, 0, 18) == 'team_direct_total_') { + if (str_starts_with($key, 'team_direct_total_')) { $tag = 'team_direct_total'; } - if (substr($key, 0, 20) == 'team_recharge_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 (substr($key, 0, 21) == 'team_withdrawl_total_') { + if (str_starts_with($key, 'team_withdrawl_total_')) { $tag = 'team_withdrawl_total'; } - if (substr($key, 0, 18) == 'team_income_total_') { + if (str_starts_with($key, 'team_income_total_')) { $tag = 'team_income_total'; } - if (substr($key, 0, 16) == 'team_play_count_') { - $tag = 'team_play_count'; - } - if (substr($key, 0, 19) == 'team_consume_total_') { + if (str_starts_with($key, 'team_consume_total_')) { $tag = 'team_consume_total'; } - cache($key, (cache($key) ?? 0) + $value, null, $tag); + $old_value = cache_get($key); + 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)->column('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)->column('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)->column('vip_total'); + } + cache($key,$ret); + } + return $ret; + } +} if (!function_exists('build_invite_code')) { function build_invite_code($id = '') { @@ -660,4 +672,4 @@ if(!function_exists('__my__template_inputs')){ return [$template, $vars, $app, $plugin]; } -} \ No newline at end of file +} diff --git a/app/model/Collection.php b/app/model/Collection.php new file mode 100644 index 0000000..374cc86 --- /dev/null +++ b/app/model/Collection.php @@ -0,0 +1,45 @@ +belongsTo('User', 'user_id', 'id');//->setEagerlyType(0); + } + public function setTagsAttr($v) + { + if(is_array($v)){ + return implode(',',$v); + } + return $v; + } + public function getTagsAttr($v) + { + if($v && is_string($v)){ + return explode(',',$v); + } + return null; + } + function getStatusList(){ + return [ + '0' => '兑换中', + '1' => '成功', + '-1' => '失败', + ]; + } +} diff --git a/app/model/UserExtend.php b/app/model/UserExtend.php index 95925e4..97603d0 100755 --- a/app/model/UserExtend.php +++ b/app/model/UserExtend.php @@ -6,6 +6,7 @@ use app\model\Base; /** * @property integer $user_id 用户ID * @property integer $direct_total 直推数量 + * @property integer $vip_total VIP数量 * @property integer $team_total 团队成员数量 * @property float $consume 消费统计 * @property float $sales 销售额 diff --git a/app/queue/single/Settlement.php b/app/queue/single/Settlement.php new file mode 100644 index 0000000..12ce9fa --- /dev/null +++ b/app/queue/single/Settlement.php @@ -0,0 +1,78 @@ +alias('ut') + ->where('ut.ancestor_id',$user_id) + ->join('user as u','u.id=ut.descendant_id') + ->field('u.id,u.level') + ->where('ut.depth','>',0) + ->order('ut.depth','asc') + ->column('ut.descendant_id'); + $yifen = 0; + $last_level = 0; + foreach($list as $user){ + if($user['level']<=$last_level){ + $this->log('用户ID:'.$user['id'].'\t,等级:'.$user['level'].'\t,$last_level:'.$last_level.'\t跳过'); + continue; + } + $last_level = $user['level']; + $commission_rate = $commission_rates[$user['level']] - $yifen; + if($commission_rate>0){ + $yifen += $commission_rate; + $commission_amount = bcmul($amount,$commission_rate,4); + $this->log('用户ID:'.$user['id'].'\t,等级:'.$user['level'].'\t,比例:'.$commission_rate.'\t,金额:'.$commission_amount); + //\app\model\User::score($user['id'],$commission_amount,\app\enum\BalanceType::SEE_POINT_AWARD,'团队奖励:'.$user_id); + } + //已经是最大等级了 + if($yifen>=0.25 || $user['level'] == 5){ + $this->log('$yifen:'.$yifen.'\t,结束'); + break; + } + } + + // 无需反序列化 + //var_export($data); // 输出 ['to' => 'tom@gmail.com', 'content' => 'hello'] + } + function log($data){ + \support\Log::info('settlement')->info(json_encode($data)); + } + // 消费失败回调 + /* + $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']){ + $this->log($package['data']); + } + } +} \ No newline at end of file diff --git a/app/view/common/register.html b/app/view/common/register.html index 0ce77bf..d060180 100644 --- a/app/view/common/register.html +++ b/app/view/common/register.html @@ -10,9 +10,9 @@ {literal}