model->with(['worker']) ->where('id', $id) ->field($fields) ->find(); } /** * 获取用户列表 * * @throws RepositoryException */ public function list(): ?array { return $this->findList(); } /** * 获取指定账户记录By手机号 * * @param string $phone * @param array $fields * @return Model|null * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function infoByPhone(string $phone, array $fields = []): ?Model { $where[] = ['mobile', '=', $phone]; return $this->findOneByWhere($where, $fields); } /** * 获取指定账户记录By用户名 * * @param string $username * @param array $fields * @return Model|null * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function infoByUsername(string $username, array $fields = []): ?Model { $where[] = ['username', '=', $username]; return $this->findOneByWhere($where, $fields); } /** * 混合查找记录 * * @param string $username 混合查询 手机号或用户名 * @return array|Model|null * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function findByHybrid(string $username) { return $this->model->whereOr('username', $username)->whereOr('mobile', $username)->find(); } /** * 通过微信小程序的openID查询 * * @param string $openID * @return array|Model|null * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function findByOpenID(string $openID) { return $this->model->where('openid', $openID)->find(); } /** * 通过微信小程序的unionid查询 * * @param string $id * @return array|Model|null * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function findByUnionId(string $id) { if (empty($id)) { return null; } return $this->model->whereOr('unionid', $id)->find(); } /** * 通过个人邀请码查询用户信息 * * @param string $inviteCode * @return array|Model|null * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function findByInviteCode(string $inviteCode) { if (empty($inviteCode)) { return null; } return $this->model->where('invite_code', $inviteCode)->find(); } /** * 通过个人编号查询用户信息 * * @param string $coding * @return array|Model|null * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function findByUserCoding(string $coding) { if (empty($coding)) { return null; } return $this->model->where('coding', $coding)->find(); } /** * 修改密码 * * @param int $accountId * @param string $oldPwd * @param string $newPwd * @return bool * @throws RepositoryException */ public function modifyPwd(int $accountId, string $oldPwd, string $newPwd): bool { if (!$user = $this->findById($accountId)) { throw new RepositoryException('用户不存在'); } if ($user['password'] != md5($oldPwd)) { throw new RepositoryException('原密码错误'); } $user->password = md5($newPwd); return $user->save(); } /** * 修改用户数据 * * @param int $accountId * @param array $fieldsKV 修改内容:键值对 * @return mixed * @throws RepositoryException */ public function accountEditInfo(int $accountId, array $fieldsKV) { $allowFields = ['headimgurl', 'real_name', 'nickname', 'mobile', 'gender', 'province', 'city', 'county', 'birthday']; $fieldsKV = arrayKeysFilter($fieldsKV, $allowFields); if (isset($fieldsKV['mobile']) && !empty($fieldsKV['mobile'])) { if (!checkMobile($fieldsKV['mobile'])) { throw new RepositoryException('手机号不正确'); } } if (!$account = $this->findById($accountId)) { throw new RepositoryException('用户信息错误'); } return $account->save($fieldsKV); } /** * 统计用户分销人数(二级) */ public function shareAccountCount(int $accountId): array { $data = [ 'first' => 0, 'second' => 0, 'total' => 0, ]; try { $data['first'] = ShareRegLog::where('inviter_account_id', $accountId)->where('is_active', ShareRegLog::COMMON_ON)->count(); $data['second'] = ShareRegLog::where('inviter_parent_account_id', $accountId)->where('is_active', ShareRegLog::COMMON_ON)->count(); $data['total'] = $data['first'] + $data['second']; } catch (Exception $e) { } return $data; } /** * 注册时邀请关系绑定 * 存在邀请人时。邀请人、邀请人的邀请人三者关系绑定 * * @param int $regAccountId 注册人ID * @param int $inviterId 邀请人ID * @param int $inviterParentAid 邀请人的邀请人ID * @return bool * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function addShareRegLog(int $regAccountId, int $inviterId, int $inviterParentAid = 0): bool { if ($regAccountId <= 0 || $inviterId <= 0) { return false; } $shareConf = ExtraConfig::share(); if (ShareRegLog::where('reg_account_id', $regAccountId)->find()) { return true; } ShareRegLog::create([ 'reg_account_id' => $regAccountId, 'inviter_account_id' => $inviterId, 'inviter_parent_account_id' => $inviterParentAid, 'score' => $shareConf[self::SHARE_CURRENT] ?? 0, 'parent_score' => $shareConf[self::SHARE_PARENT] ?? 0, 'is_active' => ShareRegLog::COMMON_OFF, 'created_at' => date('Y-m-d H:i:s'), ]); return true; } /** * 分享注册激活 【手机绑定时激活】 * 激活时:1、日志变更 2、积分发放【邀请人、邀请人上级、邀请人客服】 3、积分日志添加 * * @param int $regAccountId * @return bool */ public function activeShareRegLog(int $regAccountId): bool { if ($regAccountId <= 0) { return false; } Db::startTrans(); try { if (!$regLog = ShareRegLog::where('reg_account_id', $regAccountId)->find()) { return false; } if ($regLog['is_active'] == ShareRegLog::COMMON_ON) { return true; } ShareRegLog::where('reg_account_id', $regAccountId)->save( ['is_active' => ShareRegLog::COMMON_ON, 'activated_at' => date('Y-m-d H:i:s')] ); // TODO 若激活后需要增加佣金、积分等等在此添加逻辑 Db::commit(); } catch (Exception $e) { self::log($e); Db::rollback(); return false; } return true; } /** * 查看分享绑定的用户信息 * * @param int $accountId * @param string $grade * @param int $page * @param int $size * @return array|null */ public function shareUsers(int $accountId, string $grade, int $page = 1, int $size = 10): ?array { $data = [ 'total' => 0, 'current' => $page, 'size' => $size, 'list' => new Collection(), ]; try { if (!in_array($grade, [self::SHARE_GRADE_FIRST, self::SHARE_GRADE_SECOND])) { throw new RepositoryException('层级参数错误'); } $fields = ['id', 'real_name', 'nickname', 'headimgurl', 'invite_source', 'phone_active']; $whereMap = []; switch ($grade) { case self::SHARE_GRADE_FIRST: $whereMap[] = ['inviter_account_id', '=', $accountId]; break; case self::SHARE_GRADE_SECOND: $whereMap[] = ['inviter_parent_account_id', '=', $accountId]; break; } $whereMap[] = ['is_active', '=', self::BOOL_TRUE]; $orders = ['id' => 'desc']; $data = ShareRegLog::findList($whereMap, [], $page, $size, function ($q) use ($fields) { return $q->with([ 'account' => function ($q2) use ($fields) { $q2->field($fields); } ]); }, $orders); foreach ($data['list'] as $item) { $item['desc'] = ''; $item['grade'] = $grade; if ($grade == self::SHARE_GRADE_SECOND) { $item['score'] = $item['parent_score']; } if ($grade == self::SHARE_GRADE_SERVICE) { $item['score'] = $item['service_score']; } unset($item['parent_score']); unset($item['service_score']); $regAccount = $item['account']; if ($regAccount) { $regAccount['headimgurl'] = File::convertCompleteFileUrl($regAccount['headimgurl']); } $item['account'] = $regAccount; } } catch (RepositoryException | Exception $e) { } return $data; } /** * 用户行为记录统计 * 点赞、收藏、分享等 * @param string $type * @param string $action * @param int $accountId * @return int */ public function countRecordByAction(string $type, string $action, int $accountId = 0): int { if (!in_array($type, AccountRecord::allowTypes())) { return 0; } if (!in_array($action, AccountRecord::allowActions())) { return 0; } return AccountRecord::countByAction($type, $action, $accountId); } /** * 获取并处理用户列表 【后台用户列表】 * * @param array $where * @param array $field 必传字段coin_total * @param int $page * @param int $size * @param callable|null $call * @return array|null * @throws RepositoryException */ public function getAndHandleAccountList(array $where, array $field, int $page = 1, int $size = 20, callable $call = null): ?array { $items = self::findList($where, $field, $page, $size, function ($q) use ($call) { if ($call !== null) { $q = $call($q); } return $q ->with(['tags']) ->order('id', 'desc'); }); $items['list']->each(function ($item) { $item->tag = $item->tags->column('name'); $genderText = '保密'; if ($item->gender == 1) { $genderText = '男'; } if ($item->gender == 2) { $genderText = '女'; } $item->gender_text = $genderText; }); return $items; } /** * 创建消息 支持推送订阅消息和短信 支持批量 * * @param array $item * item[title]: 是生生世世 消息标题 * item[type]: notice 消息类型 此处固定为notice 通知 * item[target]: part 目标类型 all=所有人 part=部分人 * item[subscribe_temp_id]: d0efR-Ga27c6eIvx9mAwJcnAqzhM_Sq68XiFvjvlBJM 订阅消息模版ID * item[subscribe_data][thing1]: 事实上 订阅消息内容 subscribe_data根据模版变动参数 * item[subscribe_data][time4]: 坎坎坷坷 * item[subscribe_data][thing5]: 哈对方的身份 * item[sms_temp_id]: SMS_231436568 短信模版ID * item[content]: 收拾收拾 通知内容 * * @param array $targetList [13,15] 发送人ID列表 * @throws GuzzleException */ public function createMessage(array $item, array $targetList) { $repo = AccountRepository::getInstance(); try { $type = $item['type'] ?? ''; $target = $item['target'] ?? ''; $subscribeData = $item['subscribe_data'] ?? []; $smsData = $item['sms_data'] ?? []; $item["send_at"] = date('Y-m-d H:i:s'); $item["content"] = $item['content']; $item['is_push'] = MessageModel::COMMON_ON; $item['to_subscribe'] = (int) !empty($item['subscribe_temp_id']); $item['to_sms'] = (int) !empty($item['sms_temp_id']); $item['subscribe_data'] = json_encode($subscribeData, JSON_UNESCAPED_UNICODE); $item['sms_data'] = json_encode($smsData, JSON_UNESCAPED_UNICODE); $message = $repo->addMessage($type, $target, $targetList, $item); } catch (Exception $e) { AccountRepository::log('创建消息通知失败 ', $e); } try { if ($item['to_sms']) { // 批量发送短信 $res = AccountRepository::getInstance()->smsSend($message->id, $item['sms_temp_id'], $targetList, $smsData); // var_dump($res); } } catch (Exception $e) { AccountRepository::log('短信发送失败 ', $e); } try { if ($item['to_subscribe'] > 0) { // 订阅消息发送 AccountRepository::getInstance()->subscribeSend($message->id, $item['subscribe_temp_id'], $targetList, $subscribeData, \app\model\Config::MINI_PATH_MESSAGE_CENTER); } } catch (Exception $e) { AccountRepository::log('订阅消息发送失败 ', $e); } } /** * 获取邀请人 仅统计手机授权成功的用户 * * @param int $accountId * @return int */ public function getInviteCount(int $accountId) { return Account::where('inviter_account_id', $accountId) ->where('phone_active', Account::COMMON_ON) ->count(); } /** * 获取累计佣金 * * @param int $accountId * @return float */ public function getCommissionTotal(int $accountId): float { return AccountDataLog::where('account_id', $accountId) ->where('type', AccountDataLog::TYPE_COMMISSION) ->where('action', '<>', AccountDataLog::ACTION_WITHDRAWAL_RETURN) ->where('num', '>', 0) ->sum('num'); } /** * 获取累计提现 * * @param int $accountId * @return float */ public function getCommissionWithdrawalTotal(int $accountId): float { return AccountWithdrawalCommission::where('account_id', $accountId) ->where('status', AccountWithdrawalCommission::COMMON_ON) ->sum('number'); } /** * 获取提现中佣金 * * @param int $accountId * @return float */ public function getCommissionWithdrawalIngTotal(int $accountId): float { return AccountWithdrawalCommission::where('account_id', $accountId) ->where('status', AccountWithdrawalCommission::COMMON_OFF) ->sum('number'); } /** * 获取佣金日志 * * @param int $accountId * @param int $page * @param int $size * @return array * @throws Exception */ public function getCommissionLog(int $accountId, int $page = 1, int $size = 10): array { $where[] = ['type', '=', AccountDataLog::TYPE_COMMISSION]; $where[] = ['account_id', '=', $accountId]; $order = ['created_at' => 'desc']; $fields = ['id', 'name', 'num', 'created_at']; return AccountDataLog::findList($where, $fields, $page, $size, null, $order); } }