123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788 |
- <?php
- namespace App\Models\Fpdx;
- use Illuminate\Database\Eloquent\Builder;
- use Illuminate\Database\Eloquent\Collection;
- use App\Exceptions\AlertException;
- use App\Models\User\UserModel;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Redis;
- class PairModel extends Model
- {
- protected $table = 'kdgx_partner_charge_pair';
- protected $dateFormat = 'U';
- public const CREATED_AT = 'create_time';
- protected $fillable = [
- 'uid',
- 'stage_id',
- 'activity_type',
- 'assoc_id',
- 'partner',
- 'pair_type',
- 'state',
- 'order_id',
- 'media_id',
- 'sex',
- 'sxo',
- 'min_age',
- 'max_age',
- 'height',
- 'birthday',
- 'device',
- 'km',
- 'lng',
- 'lat',
- 'location',
- 'data',
- 'score',
- 'pay',
- 'add_score',
- 'allow_photo',
- 'confirm',
- 'repair',
- 'last_assoc',
- 'rematch',
- 'keep',
- 'hidden_at'
- ];
- /**
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
- */
- public function activity()
- {
- return $this->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;
- }
|