partner_id > 0) { return array( 'code' => 200, 'message' => 'success', 'data' => $user, ); } $partnerModel = new PartnerModel(); $data = $user->toArray(); $data['media_id'] = config("wechat.fpdx.public_id"); $data['secret'] = bin2hex(\openssl_random_pseudo_bytes(4)); $partner = $partnerModel->fill($data); $partner->created_at = time(); if (!empty($partner->photo_src)) { $partner->check_photo = 0; $partner->is_commit_check = 1; } if (!empty($partner->qq) || !empty($partner->weixin)) { $partner->check_contact = 0; $partner->is_commit_check = 1; } if (!empty($partner->introduce) || !empty($partner->expect)) { $partner->intro_check = 0; $partner->is_commit_check = 1; } if (!empty($partner->voice)) { $partner->voice_check = 0; $partner->is_commit_check = 1; } if (!empty($partner->photo_1)) { $partner->photo_1_check = 0; $partner->is_commit_check = 1; } if (!empty($partner->photo_2)) { $partner->photo_2_check = 0; $partner->is_commit_check = 1; } if (!empty($partner->photo_3)) { $partner->photo_3_check = 0; $partner->is_commit_check = 1; } if (!empty($partner->photo_4)) { $partner->photo_4_check = 0; $partner->is_commit_check = 1; } if ($this->isCanSell($partner)) { $partner->is_sell = 1; $partner->upload_at = time(); } if (Redis::exists("storeselfpartner:{$uid}")) { throw new AlertException("请求频繁", 104); } Redis::setex("storeselfpartner:{$uid}", 5, true); if ($partner->save()) { $user->partner_id = $partner->id; $user->save(); // 系统通知 $sex = 1 == $partner->sex ? "小姐姐" : "小哥哥"; NoticeModel::create([ 'uid' => $uid, 'title' => '交友卡片上传完成', 'content' => "你的交友卡片已经完成啦!现在可以去交友大厅邀请你心动的{$sex}啦~ ", 'type' => 5, 'type_id' => 0, 'create_at' => time(), 'update_at' => time(), 'tab_content' => '进入大厅', 'tab_url' => '/pages/index/index', ]); } Redis::del(["storeselfpartner:{$uid}"]); StoreSelfPartnerJob::dispatch($uid); } catch (\Exception $e) { if (Redis::exists("storeselfpartner:{$uid}")) { Redis::del(["storeselfpartner:{$uid}"]); } throw $e; } } public function isCanSell(PartnerModel $partner) { if (empty($partner->qq) && empty($partner->weixin)) { return false; } if ( 1 == $partner->check_photo || 1 == $partner->photo_1_check || 1 == $partner->photo_2_check || 1 == $partner->photo_3_check || 1 == $partner->photo_4_check || 1 == $partner->voice_check ) { return true; } /** @var UserModel $user */ $user = UserModel::findOrFail($partner->uid); if (!empty($user->introduce) || !empty($user->claim_tag)) { return true; } if (0 < $user->height || !empty($user->school) || !empty($user->home) || !empty($user->address)) { return true; } if (!empty($user->tag_2) || !empty($user->tag_3) || !empty($user->tag_3)) { return true; } return false; } /** * 审核用户个人交友卡片 * @param int $partner_id * @param string $field * @param int $check * @return bool * @throws AlertException */ public function check(int $partner_id, string $field, int $check) { /** @var PartnerModel $partner */ $partner = PartnerModel::findOrFail($partner_id); $user = UserModel::find($partner->uid); // 卡片之前是否审核通过 $before_photo_check = $partner->$field; // 语音之前是否审核 $before_voice_check = $partner->voice_check; // 之前是否认证 $before_auth = ($user->identity_auth && $user->wx_auth == 1) ? 1 : 0; // 记录审核失败次数 $checks = ['check_photo', 'photo_1_check', 'photo_2_check', 'photo_3_check', 'photo_4_check', 'voice_check']; if (in_array($field, $checks) && $check == -1) { PartnerModel::where('id', $partner_id)->increment('dechecks', 1); } $partner->{$field} = $check; // 检查审核态 if ( $partner->check_photo != 0 && $partner->photo_1_check != 0 && $partner->photo_2_check != 0 && $partner->photo_3_check != 0 && $partner->photo_4_check != 0 && $partner->voice_check != 0 ) { $partner->is_commit_check = 0; } $partner->save(); // 卡片审核事件 event(new CheckPartner($partner->uid, $field, $check)); // 修正上架状态 // 上架=照片或语音审核通过+QQ或微信 if (1 == $partner->is_sell && !$this->isCanSell($partner)) { $partner->is_sell = 0; Redis::zrem("fpdx:user:locations:sell:boy", $partner->uid); Redis::zrem("fpdx:user:locations:sell:girl", $partner->uid); $partner->save(); } AppearanceUserJob::dispatch($partner->uid)->onQueue('{appearance:user}'); if ($check == 1) { $this->sell($partner_id, 1); } $user = UserModel::find($partner->uid); $partner = PartnerModel::findOrFail($partner_id); // 卡片之前是否审核通过 $after_photo_check = $partner->$field; // 语音之前是否审核 $after_voice_check = $partner->voice_check; // 之前是否认证 $after_auth = ($user->identity_auth && $user->wx_auth == 1) ? 1 : 0; // 卡片审核通知 $noticeService = new NoticeService(); // 审核卡片 if (in_array($field, ['check_photo', 'photo_1_check', 'photo_2_check', 'photo_3_check', 'photo_4_check'])) { if ($before_photo_check != 1 && $after_photo_check == 1) { $noticeService->checkPartnerSuccess($partner->uid); } elseif ($before_photo_check != -1 && $after_photo_check == -1) { $noticeService->checkPartnerFail($partner->uid); } } // 审核语音 if (in_array($field, ['voice_check'])) { if ($before_voice_check != 1 && $after_voice_check == 1) { $noticeService->checkVoiceSuccess($partner->uid); } elseif ($before_voice_check != -1 && $after_voice_check == -1) { $noticeService->checkVoiceFail($partner->uid); } } // 发送认证通知 if ($before_auth == 0 && $after_auth == 1) { $noticeService->authenticationSuccess($partner->uid); } return true; } /** * 上下架卡片 * @param int $partner_id * @param int $is_sell * @return bool * @throws AlertException */ public function sell(int $partner_id, int $is_sell) { /** @var PartnerModel $partner */ $partner = PartnerModel::findOrFail($partner_id); if (1 == $is_sell && ($partner->black_at > time() || 0 != $partner->is_sell)) { if ($partner->black_at > time()) { throw new AlertException("卡片被封禁", 102); } if (0 != $partner->is_sell) { throw new AlertException("卡片被封禁,请修改信息", 102); } } if (1 == $is_sell && $partner->is_sell != 1) { if ($this->isCanSell($partner)) { $partner->is_sell = 1; $partner->upload_at = time(); } else { throw new AlertException("不满足上架条件「没有练习方式」", 103); } } if (1 == $is_sell) { $partner->auto_sell = 1; // 加入redis /** @var UserModel $user */ $user = UserModel::findOrFail($partner->uid); if ($partner->sex == 1) { Redis::geoAdd("fpdx:user:locations:sell:boy", $user->lng, $user->lat, $partner->uid); } else { Redis::geoAdd("fpdx:user:locations:sell:girl", $user->lng, $user->lat, $partner->uid); } } else { Redis::zrem("fpdx:user:locations:sell:boy", $partner->uid); Redis::zrem("fpdx:user:locations:sell:girl", $partner->uid); } $partner->is_sell = $is_sell; $partner->save(); AppearanceUserJob::dispatch($partner->uid)->onQueue('{appearance:user}'); try { if (1 == $is_sell) { $ts = new TaskService(); $ts->task($partner->uid, 3); $noticeService = new NoticeService(); $noticeService->partnerSell($partner->uid); } else { event(new HidePartner($partner->id)); } } catch (\Exception $exception) { app('sentry')->captureException($exception); } return true; } /** * 更新卡片信息 * @param int $partner_id * @param array $data * @throws AlertException */ public function updatePartner(int $partner_id, array $data) { /** @var PartnerModel $partner */ $partner = PartnerModel::findOrFail($partner_id); // 是否上架 $sell = false; if ((array_key_exists('qq', $data) || array_key_exists('weixin', $data))) { if ($partner->is_sell == 0 && empty($partner->qq) && empty($partner->weixin)) { $sell = true; } } if (array_key_exists('voice', $data) && !empty($data['voice'])) { $data['voice_check'] = 0; $data['is_commit_check'] = 1; } if (array_key_exists('voice', $data) && empty($data['voice'])) { $data['voice_check'] = -1; } if (array_key_exists('photo_src', $data) && !empty($data['photo_src'])) { $data['check_photo'] = 0; $data['is_commit_check'] = 1; } if (array_key_exists('photo_src', $data) && empty($data['photo_src'])) { $data['check_photo'] = -1; } if (array_key_exists('photo_1', $data) && !empty($data['photo_1'])) { $data['photo_1_check'] = 0; $data['is_commit_check'] = 1; } if (array_key_exists('photo_1', $data) && empty($data['photo_1'])) { $data['photo_1_check'] = -1; } if (array_key_exists('photo_2', $data) && !empty($data['photo_2'])) { $data['photo_2_check'] = 0; $data['is_commit_check'] = 1; } if (array_key_exists('photo_2', $data) && empty($data['photo_2'])) { $data['photo_2_check'] = -1; } if (array_key_exists('photo_3', $data) && !empty($data['photo_3'])) { $data['photo_3_check'] = 0; $data['is_commit_check'] = 1; } if (array_key_exists('photo_3', $data) && empty($data['photo_3'])) { $data['photo_3_check'] = -1; } if (array_key_exists('photo_4', $data) && !empty($data['photo_4'])) { $data['photo_4_check'] = 0; $data['is_commit_check'] = 1; } if (array_key_exists('photo_4', $data) && empty($data['photo_4'])) { $data['photo_4_check'] = -1; } // 是否属于72小时活动卡片 if (isset($data['is_commit_check']) && 1 == $data['is_commit_check']) { $ings = ActivityModel::getActivitys(); $exists = PairModel::where([ 'uid' => $partner->uid, 'stage_id' => $ings['ing'] ?: 0, ])->exists(); if ($exists) { $data['is_fpdx'] = 1; } else { $data['is_fpdx'] = 0; } } try { if ( 5 <= $partner->feedcheck_cnt && !empty(array_intersect( array_keys($data), ['photo_src', 'photo_1', 'photo_2', 'photo_3', 'photo_4', 'voice'] )) ) { $data['feedcheck_cnt'] = 0; $data['is_push_feed'] = 1; FeedcheckLogModel::where([ ['partner_id', $partner->id], ['expire_at', 0], ])->update(['expire_at' => time()]); } } catch (\Exception $exception) { } $updatekeys = array( 'photo_src', 'photo_1', 'photo_2', 'photo_3', 'photo_4', 'voice', 'sex', 'age', 'weixin', 'qq', 'school', 'height', 'home', 'address', 'introduce', ); if (!empty(array_intersect(array_keys($data), $updatekeys))) { $data['update_at'] = time(); } $partner->fill($data); $this->auditDiscribute($partner, $data); // 修正首页feed流缓存 if (isset($data['sex']) && 1 == $partner->is_sell) { /** @var UserModel $user */ $user = UserModel::findOrFail($partner->uid); if ($partner->sex == 1) { Redis::zrem("fpdx:user:locations:sell:girl", $partner->uid); Redis::geoAdd("fpdx:user:locations:sell:boy", $user->lng, $user->lat, $partner->uid); } else { Redis::zrem("fpdx:user:locations:sell:boy", $partner->uid); Redis::geoAdd("fpdx:user:locations:sell:girl", $user->lng, $user->lat, $partner->uid); } } // 修正上架状态 // 上架=QQ或微信 if (1 == $partner->is_sell && false == $this->isCanSell($partner)) { $partner->is_sell = 0; Redis::zrem("fpdx:user:locations:sell:boy", $partner->uid); Redis::zrem("fpdx:user:locations:sell:girl", $partner->uid); } // 修正首页feed流缓存 if (-1 == $partner->is_sell && 1 == $partner->is_commit_check) { $partner->is_sell = 0; Redis::zrem("fpdx:user:locations:sell:boy", $partner->uid); Redis::zrem("fpdx:user:locations:sell:girl", $partner->uid); } // 修正审核状态 if ( 1 == $partner->is_commit_check && 0 != $partner->check_photo && 0 != $partner->photo_1_check && 0 != $partner->photo_2_check && 0 != $partner->photo_3_check && 0 != $partner->photo_4_check && 0 != $partner->voice_check ) { $partner->is_commit_check = 0; } $partner->save(); if (!empty(array_intersect(array_keys($data), ['sex', 'school', 'is_sell']))) { AppearanceUserJob::dispatch($partner->uid)->onQueue('{appearance:user}'); } if (!empty($partner->voice)) { $ts = new TaskService(); $ts->task($partner->uid, 4); } try { if ($sell) { $this->sell($partner_id, 1); } } catch (\Exception $exception) { } } /** * 提交素材审核事件 * @param $partner * @param $data * @throws AlertException */ private function auditDiscribute($partner, $data) { // 照片 if (array_key_exists('photo_src', $data) && $data['photo_src']) { event(new AuditMedia( $partner->uid, 'image', 'https://oss.pocketuniversity.cn' . $data['photo_src'], 'photo_src', "id={$partner->id}" )); } if (array_key_exists('photo_1', $data) && $data['photo_1']) { event(new AuditMedia( $partner->uid, 'image', 'https://oss.pocketuniversity.cn' . $data['photo_1'], 'photo_1', "id={$partner->id}" )); } if (array_key_exists('photo_2', $data) && $data['photo_2']) { event(new AuditMedia( $partner->uid, 'image', 'https://oss.pocketuniversity.cn' . $data['photo_2'], 'photo_2', "id={$partner->id}" )); } if (array_key_exists('photo_3', $data) && $data['photo_3']) { event(new AuditMedia( $partner->uid, 'image', 'https://oss.pocketuniversity.cn' . $data['photo_3'], 'photo_3', "id={$partner->id}" )); } if (array_key_exists('photo_4', $data) && $data['photo_4']) { event(new AuditMedia( $partner->uid, 'image', 'https://oss.pocketuniversity.cn' . $data['photo_4'], 'photo_4', "id={$partner->id}" )); } // 语音 if (array_key_exists('voice', $data) && $data['voice']) { event(new AuditMedia($partner->uid, 'voice', $data['voice'], 'voice', "id={$partner->id}")); } } /** * 通过uid获取用户卡片信息 * @param int $uid * @return PartnerModel */ public function getUserSelf(int $uid) { /** @var PartnerModel $partner */ $partner = PartnerModel::where('uid', $uid)->firstOrFail([ 'id', 'uid', 'sex', 'age', 'star', 'height', 'school', 'weixin', 'qq', 'address', 'home', 'check_photo', 'photo_src', 'photo_1_check', 'photo_1', 'photo_2_check', 'photo_2', 'photo_3_check', 'photo_3', 'photo_4_check', 'photo_4', 'voice_check', 'voice', 'praises', 'introduce', 'expect', 'education', 'black_at', ]); $partner->black_at = $partner->black_at < time() ? 0 : $partner->black_at; $partner->setHidden([ "check_photo", "photo_1_check", "photo_2_check", "photo_3_check", "photo_4_check", "voice_check", "check_contact", ]); if (1 != $partner->check_photo) { $partner->addHidden("photo_src"); } if (1 != $partner->photo_1_check) { $partner->addHidden("photo_1"); } if (1 != $partner->photo_2_check) { $partner->addHidden("photo_2"); } if (1 != $partner->photo_3_check) { $partner->addHidden("photo_3"); } if (1 != $partner->photo_4_check) { $partner->addHidden("photo_4"); } if (1 != $partner->voice_check) { $partner->addHidden("voice"); } try { /** @var UserModel $user */ $user = UserModel::findOrfail($partner->uid, [ 'uid', 'headimgurl', 'nickname', 'age', 'star', 'pair_voice', 'work_state', 'qq', 'weixin', 'be_vip_at', 'supvip_endat', 'introduce', 'expect', 'height', 'sex', 'school', 'address', 'home', 'logoff_at', 'tag_1', 'tag_2', 'tag_3', 'tag_4', 'claim_tag', 'identity_auth', 'wx_auth', ]); /** @var InviteConfigModel $userInviteConfig */ $userInviteConfig = InviteConfigModel::find($partner->uid); if ($userInviteConfig) { $user->setAttribute("task_paint", $userInviteConfig->task_paint); $user->setAttribute("task_photo", $userInviteConfig->task_photo); $user->setAttribute("task_question", $userInviteConfig->task_question); $user->setAttribute("task_sing", $userInviteConfig->task_sing); $user->setAttribute("task_question_data", $userInviteConfig->task_question_data ? true : false); $user->setAttribute("task_sing_data", $userInviteConfig->task_sing_data ? true : false); } $partner->headimgurl = $user->headimgurl; $partner->nickname = $user->nickname; } catch (\Exception $e) { $user = null; $partner->headimgurl = null; $partner->nickname = null; } $partner->setAttribute("user", $user); return $partner; } /** * 获取卡片信息 * @param int $partner_id * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model */ public function get(int $partner_id) { /** @var PartnerModel $partner */ $partner = PartnerModel::findOrFail($partner_id); if (1 != $partner->check_photo) { $partner->addHidden("photo_src"); } if (1 != $partner->photo_1_check) { $partner->addHidden("photo_1"); } if (1 != $partner->photo_2_check) { $partner->addHidden("photo_2"); } if (1 != $partner->photo_3_check) { $partner->addHidden("photo_3"); } if (1 != $partner->photo_4_check) { $partner->addHidden("photo_4"); } if (1 != $partner->voice_check) { $partner->addHidden("voice"); } $partner->setHidden([ "check_photo", "photo_1_check", "photo_2_check", "photo_3_check", "photo_4_check", "voice_check", "check_contact", ]); return $partner; } /** * 选择封面 * @param int $partner_id * @param $field * @throws AlertException */ public function selectCover(int $partner_id, $field) { if (!in_array($field, ['photo_1', 'photo_2', 'photo_3', 'photo_4'])) { throw new AlertException("未知的输入", 101); } $partner = PartnerModel::findOrFail($partner_id); $check_name = "{$field}_check"; $tmp = $partner->photo_src; $tmp_check = $partner->check_photo; $partner->photo_src = $partner->{$field}; $partner->check_photo = $partner->{$check_name}; $partner->{$field} = $tmp; $partner->{$check_name} = $tmp_check; $partner->save(); } /** * 点赞/无感 对象卡片 * @param int $uid * @param int $partner_id * @param null $thumb 是否点赞 * @return array * @throws AlertException */ public function thumb(int $uid, int $partner_id, $thumb = null) { $res = array('eachlike' => false); $user = UserModel::findOrFail($uid); if ($user->partner_id == $partner_id) { // 操作的是自己的卡片 return $res; } if (0 == $user->partner_id && !in_array($partner_id, [1, 2])) { // 操作用户是游客=>记录游客动作 ThumbActionModel::createdOrDeleted($uid, $partner_id, $thumb); return $res; } $res = array('eachlike' => false); /** @var PartnerModel $partner */ $partner = PartnerModel::findOrFail($partner_id); if ( $praise = PraiseModel::where(array(['partner_id', $partner_id], ['uid', $uid]))->first() ) { if ((int)$praise->type === (int)$thumb) { // 重复操作 return $res; } $praise->type = is_null($thumb) ? abs($praise->type - 1) : $thumb; if (0 == $praise->type && in_array($partner_id, [1, 2])) { throw new AlertException("这是你的专属小象,暂不支持取消心动哟~", 202); } if ($praise->type == 1) { $praiseModel = new PraiseModel(); if ($praiseModel->isLike($partner->uid, $user->partner_id)) { $partnerUser = UserModel::where('partner_id', $partner->id)->first([ 'uid', 'nickname', 'headimgurl', 'sex', 'weixin', 'qq', 'identity_auth', 'wx_auth', 'be_vip_at', 'supvip_endat', ]); $res['eachlike'] = true; $res['user'] = $partnerUser; } event(new ThumbUser($user, $partner)); } else { event(new UnThumbUser($user, $partner)); } } else { if (is_null($thumb) || 1 == $thumb) { $praiseModel = new PraiseModel(); if ($praiseModel->isLike($partner->uid, $user->partner_id)) { $partnerUser = UserModel::where('partner_id', $partner->id)->first([ 'uid', 'nickname', 'headimgurl', 'sex', 'weixin', 'qq', 'identity_auth', 'wx_auth', 'be_vip_at', 'supvip_endat', ]); $res['eachlike'] = true; $res['user'] = $partnerUser; } event(new ThumbUser($user, $partner)); } else { return $res; } } return $res; } /** * 超级喜欢某人 * @param int $uid * @param int $partner_id * @return bool */ public function superLike(int $uid, int $partner_id) { $user = UserModel::findOrFail($uid); if ($user->supvip_endat < time()) { return false; } if (SuperLikeModel::where(array(['uid', $uid], ['partner_id', $partner_id]))->exists()) { return true; } else { PraiseModel::where(array(['uid', $uid], ['partner_id', $partner_id]))->update(['lock' => 100]); SuperLikeModel::create([ 'created_at' => time(), 'updated_at' => time(), 'uid' => $uid, 'partner_id' => $partner_id, ]); return true; } } /** * 解锁喜欢我的卡片 * @param int $uid * @param int $partner_id * @return bool * @throws AlertException */ public function lockLikeme(int $uid, int $partner_id) { $partner = PartnerModel::findOrFail($partner_id); /** @var UserModel $user */ $user = UserModel::findOrFail($uid); if ($user->supvip_endat < time()) { throw new AlertException("你不是超级会员"); } if ($user->partner_id == 0) { throw new AlertException("你还没有生成交友卡片", 100); } $praise = PraiseModel::where([['uid', $partner->uid], ['partner_id', $user->partner_id]])->firstOrFail(); if ($praise->lock >= 100) { throw new AlertException("卡片已经被解锁了", 102); } if ( LocklikemeModel::where(array( ['uid', $uid], ['origin', 'supvip'], ['created_at', '>', mktime(0, 0, 0)], ))->count() >= 5 ) { throw new AlertException("没有解锁次数了", 101); } DB::beginTransaction(); try { $praise->lock = 100; $praise->save(); LocklikemeModel::create([ 'uid' => $uid, 'partner_id' => $partner_id, 'origin' => 'supvip', ]); DB::commit(); return true; } catch (\Exception $exception) { DB::rollBack(); throw $exception; } } /** * app解锁喜欢我的卡片 * @param int $uid * @param int $partner_id * @return bool * @throws AlertException */ public function appLockLikeMe(int $uid, int $partner_id) { $partner = PartnerModel::findOrFail($partner_id); $user = UserModel::findOrFail($uid); if ($user->partner_id == 0) { throw new AlertException("你还没有生成交友卡片", 100); } $praise = PraiseModel::where([['uid', $partner->uid], ['partner_id', $user->partner_id]])->firstOrFail(); if ($praise->lock >= 100) { throw new AlertException("卡片已经被解锁了", 102); } if ($user->app_like_unlock_count == 0) { throw new AlertException("没有解锁次数了", 101); } DB::beginTransaction(); try { $praise->lock = 100; $praise->save(); $user->decrement('app_like_unlock_count', 1); LocklikemeModel::create([ 'uid' => $uid, 'partner_id' => $partner_id, 'origin' => 'app_sign', ]); DB::commit(); return true; } catch (\Exception $exception) { DB::rollBack(); throw $exception; } } /** * 清理过期超级喜欢 */ public function clearSuperlike() { $supers = SuperLikeModel::whereBetween('created_at', [time() - 86400 * 7, time() - 86400 * 3])->get(); foreach ($supers as $super) { Redis::zrem("fpdx:feed:superlike:{$super->uid}", $super->partner_id); } } }