belongsTo(ActivityModel::class, 'stage_id', 'stage_id'); } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() { return $this->belongsTo(\App\Models\User\UserModel::class, 'uid', 'uid') ->select( 'nickname', 'headimgurl', 'sex', 'sxo', 'height', 'age', 'home', 'address', 'school', 'qq', 'weixin', 'pair_min_age', 'pair_max_age', 'wxkf' ); } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function media() { return $this->belongsTo(MediaModel::class, 'media_id', 'media_id'); } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function room() { return $this->belongsTo(RoomModel::class, 'room_id', 'room_id'); } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function group() { return $this->belongsTo(GroupModel::class, 'group_id', 'id'); } /** * 没有隐藏的列表 * @param $query * @return mixed */ public function scopeHidden(/** @var Builder $query */$query) { return $query->where('hidden_at', 0); } /** * 获取匹配范围内的用户 * @return array */ public function getMatchRadiusUids(): array { $lbsCacheKey = "pair:{$this->stageId}:lsb"; $uids = Redis::geoRadius($lbsCacheKey, $this->lng, $this->lat, $this->match_raduis, 'km'); return $uids; } /** * 获取报名信息 * @param $stage_id * @param $uid * @return mixed * @throws AlertException */ public function getPairByStageUid($stage_id, $uid) { $where = [ ['stage_id', '=', $stage_id], ['uid', '=', $uid] ]; $pair = $this->where($where)->first(); if (collect($pair)->isEmpty()) { throw new AlertException("未能找到报名记录"); } else { return $pair; } } /** * 获取「某期」待匹配的队列 * @param int $stage_id 期数 * @param string $activity_type * @param string|null $city * @return Collection */ public function getPairQuery(int $stage_id, string $activity_type = "72h", string $city = null) { $pairs = $this->where([['stage_id', $stage_id], ['activity_type', $activity_type]]) ->whereNull('assoc_id') ->whereBetween('state', [100, 299]) ->get(['uid']); /** @var Collection $users */ $users = UserModel::whereIn('uid', $pairs->pluck('uid')) ->when(!is_null($city), function (/** @var Builder $query */ $query) use ($city) { return $query->where('address', $city); })->get([ 'uid', 'sex', 'sxo', 'height', 'age', 'home', 'address', 'school', 'fpdx_like', 'pair_min_age', 'pair_max_age', 'pair_province', 'pair_all' ]); foreach ($users as &$user) { $pair = $this->where([['stage_id', $stage_id], ['uid', $user->uid]])->first(['id', 'score']); if (!collect($pair)->isEmpty()) { $user->pair_id = $pair->id; $user->score = $pair->score; $pairs = Redis::smembers("fpdx_pairs_{$user->uid}"); if (empty($pairs)) { $pairs = array(); } $user->pairs = $pairs; } } $users = $users->sortByDesc("score"); return $users; } /** * 重新匹配列表 * @param int $stage_id * @param string $activity_type * @param string|null $city * @return Collection */ public function getRematchPair(int $stage_id, string $activity_type = "72h", string $city = null) { $pairs = $this->where([ ['stage_id', $stage_id], ['rematch', 1], ['activity_type', $activity_type] ])->whereNull('assoc_id')->get(['uid']); /** @var Collection $users */ $users = UserModel::whereIn('uid', $pairs->pluck('uid')) ->when(!is_null($city), function (/** @var Builder $query */ $query) use ($city) { return $query->where('address', $city); })->get([ 'uid', 'sex', 'sxo', 'height', 'age', 'home', 'address', 'school', 'fpdx_like', 'pair_min_age', 'pair_max_age', 'pair_province', 'pair_all' ]); foreach ($users as &$user) { $pair = $this->where([['stage_id', $stage_id], ['uid', $user->uid]])->first(['id', 'score']); if (!collect($pair)->isEmpty()) { $user->pair_id = $pair->id; $user->score = $pair->score; $pairs = Redis::smembers("fpdx_pairs_{$user->uid}"); if (empty($pairs)) { $pairs = array(); } $user->pairs = $pairs; } } $users = $users->sortByDesc("score"); return $users; } /** * 获取某期匹配对象的回复情况 * @param int stage_id 期数 * @return object data * [ * { * id: 匹配id * uid: 用户id * stage_id: 报名期数 * media_id: 报名公众号id * assoc_id: 匹配对象匹配id * receive: 是否回复过 [true | false] * pair: { * id: 匹配id * uid: 用户id * stage_id: 报名期数 * media_id: 报名公众号id * assoc_id: 匹配对象匹配id * receive: 是否回复过 [true | false] * } * } * ] */ public function getAllReceiveState(int $stage_id) { $where = array( ['stage_id', $stage_id], ['sex', 2], ['assoc_id', '!=', null] ); $girls = self::where($where)->get(); $where = array( ['stage_id', $stage_id], ['sex', 1], ['assoc_id', '!=', null] ); $boys = self::where($where)->get(); $boys = $boys->keyBy('id'); foreach ($girls as &$girl) { if (isset($girl->receives) && $girl->receives > 0) { $girl->receive = true; } else { $girl->receive = false; } $pair = $boys->get($girl->assoc_id); if (isset($pair->receives) && $pair->receives > 0) { $pair->receive = true; } else { $pair->receive = false; } $girl->pair = $pair; } return $girls; } /** * 获取某期某人及其对象回复情况 * @param int $stage_id * @param int $uid * @return object data * { * id: 匹配id * uid: 用户id * stage_id: 报名期数 * media_id: 报名公众号id * assoc_id: 匹配对象匹配id * receive: 是否回复过 [true | false] * pair: { * id: 匹配id * uid: 用户id * stage_id: 报名期数 * media_id: 报名公众号id * assoc_id: 匹配对象匹配id * receive: 是否回复过 [true | false] * } * } * @throws AlertException */ public function getReceiveState(int $stage_id, int $uid) { $where = array( ['stage_id', $stage_id], ['uid', $uid], ['assoc_id', '!=', null] ); $data = self::where($where)->first(); if (collect($data)->isEmpty()) { throw new AlertException("未找到报名纪录"); } if (isset($data->receives) && $data->receives > 0) { $data->receive = true; } else { $data->receive = false; } $pair = self::find($data->assoc_id); if (isset($pair->receives) && $pair->receives > 0) { $pair->receive = true; } else { $pair->receive = false; } $data->pair = $pair; return $data; } /** * 维护发送信息条数 * @param int uid 发送消息的用户uid * @param int room_id 房间号 * @param int message_id 消息id * @return void */ public static function receiveMsg(int $uid, int $room_id, int $message_id) { $room = RoomModel::find($room_id); if (collect($room)->isEmpty()) { return; } else { $msg = MessageModel::find($message_id); if (isset($msg->msg_type) && $msg->msg_type == -1) { self::where('stage_id', $room->stage_id)->where('uid', $uid)->increment('receives', 1); } return; } } /** * 获取某期不满意的报名集合 * @param int stage_id 期数 * @return array result [1,2,3,8,...] */ public static function getNotSatisfactions(int $stage_id) { $result = array(); $where = array( ['stage_id', $stage_id], ['sex', 2], ['assoc_id', '!=', null] ); $girls = self::where($where)->get(); $where = array( ['stage_id', $stage_id], ['sex', 1], ['assoc_id', '!=', null] ); $boys = self::where($where)->get(); $boys = $boys->keyBy('id'); foreach ($girls as &$girl) { try { $pair = $boys->get($girl->assoc_id); if ($girl->receives > 0 && 0 == $pair->receives) { array_push($result, $girl->id); } if ($pair->receives > 0 && 0 == $girl->receives) { array_push($result, $pair->id); } } catch (\Exception $e) { continue; } } return $result; } /** * 获取某期匹配成功的对象的信息 * @param int stage_id 期数 * @return Collection * { * [ * "id": 报名纪录id, * "uid": 用户id, * "stage_id": 期数, * "room": { * "room_id": 房间id, * "room_name": 房间名称, * "stage_id": 期数, * "uid": 用户id, * "pair_uid": 匹配对象uid, * "create_time": unix时间戳 * } * ] * } */ public function getStageNumber($stage_id) { $pairs = $this->where('stage_id', $stage_id)->whereBetween('state', [400, 499])->get(['id', 'uid', 'stage_id']); $roomModel = new RoomModel(); foreach ($pairs as $key => &$value) { try { $value->room = $roomModel->getRoom($value->room_id, $value->uid); } catch (\ApiException $e) { $pairs->forget($key); continue; } } return json_decode($pairs->toJson()); } /** * 获取分配对象收益明细 * @param string media_id 公众号id * @param int $stage_id 期数 * @return object 明细信息 */ public function fxIncome(string $media_id, int $stage_id = 0) { $data = $this->with([ 'user' => function (/** @var Builder $query */ $query) { $query->select(['uid', 'nickname']); } ])->where(array( ['media_id', $media_id], ['stage_id', '>', 26] ))->whereBetween('state', [100, 899])->when( $stage_id, function (/** @var Builder $query */ $query) use ($stage_id) { return $query->where('stage_id', $stage_id); } )->orderBy('create_time', 'desc')->get([ 'uid', 'stage_id', 'sex', 'create_time', 'state', 'fx_money', 'completed_at' ]); return $data; } /** * 分销排行 * @param int stage_id 期数 * @return array [ * { * 'count': 数量, * 'fx_money': 收益, * 'media_id': 公众号id, * 'public_name': '公众号名称‘, * 'expect_money': '期望收益' * } * ] */ public function fxrank(int $stage_id = 0) { $hides = Redis::lrange("{pair_hides}", 0, -1); $hidesql = ""; foreach ($hides as $value) { $hidesql .= "'{$value}',"; } if ($stage_id != 0) { $sql = "select count(*) as count, p.media_id, public_name from kdgx_partner_charge_pair as p join kdgx_partner_charge_media as m on p.media_id=m.media_id where `stage_id`= ? and `state` between 100 and 899 and m.`type` = 0 and p.`media_id` not in ({$hidesql}'+') GROUP BY p.`media_id`"; $result = DB::select($sql, [$stage_id]); foreach ($result as &$data) { $media_id = $data->media_id; $data->expect_money = DB::table('kdgx_partner_charge_pair')->where(array( ['stage_id', $stage_id], ['media_id', $media_id], ['sex', 1] ))->whereBetween('state', [100, 199])->count() * 2.5; $data->expect_money += DB::table('kdgx_partner_charge_pair')->where(array( ['stage_id', $stage_id], ['media_id', $media_id], ['sex', 2] ))->whereBetween('state', [100, 199])->count() * 3.5; $data->expect_money += DB::table('kdgx_partner_charge_pair')->where(array( ['stage_id', $stage_id], ['media_id', $media_id] ))->whereBetween('state', [300, 399])->count() * 0.5; $data->expect_money += DB::table('kdgx_partner_charge_pair')->where(array( ['stage_id', $stage_id], ['media_id', $media_id], ['sex', 1] ))->whereBetween('state', [400, 499])->count() * 2.5; $data->expect_money += DB::table('kdgx_partner_charge_pair')->where(array( ['stage_id', $stage_id], ['media_id', $media_id], ['sex', 2] ))->whereBetween('state', [400, 499])->count() * 3.5; $data->expect_money += DB::table('kdgx_partner_charge_pair')->where(array( ['stage_id', $stage_id], ['media_id', $media_id], ))->whereBetween('state', [500, 599])->count() * 0.5; $data->expect_money += DB::table('kdgx_partner_charge_pair')->where(array( ['stage_id', $stage_id], ['media_id', $media_id], ))->whereBetween('state', [600, 699])->count() * 0.5; $data->expect_money += \DB::table('kdgx_partner_charge_pair')->where(array( ['stage_id', $stage_id], ['media_id', $media_id], ))->whereBetween('state', [700, 799])->count() * 0.5; $data->expect_money += \DB::table('kdgx_partner_charge_pair')->where(array( ['stage_id', $stage_id], ['media_id', $media_id], ['sex', 1] ))->whereBetween('state', [800, 899])->count() * 2.5; $data->expect_money += \DB::table('kdgx_partner_charge_pair')->where(array( ['stage_id', $stage_id], ['media_id', $media_id], ['sex', 2] ))->whereBetween('state', [800, 899])->count() * 3.5; } } else { $sql = "select count(*) as count, media_id from kdgx_partner_charge_pair where `state` between 100 and 899 and `media_id` not in ({$hidesql}'+') GROUP BY `media_id` ORDER BY count desc"; $result = \DB::select($sql); } usort($result, function ($x, $y) { if ($x->count > $y->count) { return false; } else { return true; } }); return $result; } /** * 当前的进度 * @return int */ public function progress() { if (empty($this->id)) { return self::NOT_ENROLL; } $activity = ActivityModel::find($this->stage_id); // dump($activity->getProgress()); // 报名中 if ($activity->getProgress() == ActivityModel::ENROLLING) { return self::ENROLLING; } // 匹配中 if ($activity->getProgress() == ActivityModel::MATCHING) { return self::MATCHING; } if ($this->state >= 0 && $this->state < 100) { return self::INVALID; } if ($this->state >= 300 && $this->state < 400) { return self::MATCH_FAIL; } if ($this->state >= 500 && $this->state < 600) { return self::DISSATISFIED; } if ($this->state >= 600 && $this->state < 700) { return self::REFUND; } if ($this->state >= 700 && $this->state < 800) { return self::NEXT_ISSUE; } if ($this->state >= 900 && $this->state < 1000) { return self::INVALID; } if ($this->state >= 1000 && $this->state < 1100) { return self::NEXT_ISSUE; } // 40x or 80x if ( ($this->state >= 400 && $this->state < 500) or ($this->state >= 800 && $this->state < 900) ) { // 确认期间 if ($activity->getProgress() == ActivityModel::CONFIRMING) { // 另一半 $other = PairModel::find($this->assoc_id); if ($this->confirm == 0) { return self::MATCH_SUCCESS; } if ($this->confirm < 0) { return self::REMATCHING; } if ($this->confirm > 0 && $other->confirm == 0) { return self::MATCH_SUCCESS; } if ($this->confirm > 0 && $other->confirm < 0) { return self::REMATCHING; } if ($this->confirm > 0 && $other->confirm > 0) { return self::CHATTING; } } # 重匹期间 if ($activity->getProgress() == ActivityModel::REMATCHING) { # 我操作重匹 (一定是重匹中) if ($this->confirm < 0) { return self::REMATCHING; } // 重匹期间有last_accoc(一定是重匹中) if ($this->last_assoc) { return self::REMATCHING; } # 我操作确认 if ($this->confirm > 0) { $other = PairModel::find($this->assoc_id); if ($other->confirm > 0) { return self::CHATTING; } else { return self::REMATCHING; } } # 我未操作时 if ($this->confirm == 0) { if (!$this->assoc_id) { return self::MISS; } $other = PairModel::find($this->assoc_id); // 判断对方是否操作 if ($other->confirm == 0) { return self::STALEMATE; } else { return self::MISS; } } } // 活动期间 if ($activity->getProgress() == ActivityModel::CHATTING) { if ($this->assoc_id) { return self::CHATTING; } else { # 我未操作时 if ($this->confirm == 0) { return self::MISS; } else { return self::REMATCH_FAIL; } } } // 活动结束后 if ($activity->getProgress() == ActivityModel::END) { if ($this->assoc_id) { return self::END; } else { # 我未操作时 if ($this->confirm == 0) { return self::MISS; } else { return self::REMATCH_FAIL; } } } } } /** * 未报名 */ public const NOT_ENROLL = 0; /** * 报名中 */ public const ENROLLING = 1; /** * 匹配中 */ public const MATCHING = 2; /** * 匹配失败 */ public const MATCH_FAIL = 3; /** * 匹配成功&待确认 */ public const MATCH_SUCCESS = 4; /** * 不满意 */ public const DISSATISFIED = 5; /** * 已退款 */ public const REFUND = 6; /** * 报名下一期 */ public const NEXT_ISSUE = 7; /** * 活动已完成 */ public const END = 8; /** * 报名失效 */ public const INVALID = 9; /** * 重匹中 */ public const REMATCHING = 10; /** * 重匹失败 */ public const REMATCH_FAIL = 11; /** * 匹配成功&活动中 */ public const CHATTING = 12; /** * 错过时间 */ public const MISS = 13; /** * 双方未操作 */ public const STALEMATE = 14; }