PairManager.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. <?php
  2. namespace App\Managers;
  3. use App\Exceptions\DBException;
  4. use App\Generated\Exceptions\CustomErrorMessageException;
  5. use App\Models\Fpdx\GroupMemberModel;
  6. use App\Models\Fpdx\GroupModel;
  7. use App\Exceptions\AlertException;
  8. use App\Models\Fpdx\ActivityModel;
  9. use App\Models\Fpdx\MediaOrderModel;
  10. use App\Models\Fpdx\PairModel;
  11. use App\Models\Fpdx\RoomModel;
  12. use App\Models\Friends\PairContactApply;
  13. use App\Models\OrderModel;
  14. use App\Models\Share\PairApplyListShareHelpLog;
  15. use App\Models\User\UserModel;
  16. use App\Services\Pay\OrderService;
  17. use Carbon\Carbon;
  18. use Illuminate\Database\Eloquent\Collection;
  19. use Illuminate\Support\Facades\Redis;
  20. use Illuminate\Support\Facades\DB;
  21. class PairManager
  22. {
  23. private $pairModel;
  24. private $orderModel;
  25. private $orderManager;
  26. public function __construct()
  27. {
  28. $this->pairModel = new PairModel();
  29. $this->orderModel = new OrderModel();
  30. $this->orderManager = new OrderManager();
  31. }
  32. public function getRecommendPairApplyContacts(int $uid, array $filterUsers): array
  33. {
  34. }
  35. /**
  36. * 用户报名匹配并签到
  37. * @param int $stage_id
  38. * @param int $uid
  39. * @param int $pairUid
  40. * @throws \Throwable
  41. */
  42. public function matchUserAndEnrollAndSign(int $stage_id, int $uid, int $pairUid)
  43. {
  44. DB::transaction(function () use ($stage_id, $uid, $pairUid) {
  45. $userPair = PairModel::firstOrNew([
  46. 'uid' => $uid, 'stage_id' => $stage_id
  47. ], [
  48. 'state' => 103
  49. ]);
  50. $pairPair = PairModel::firstOrNew([
  51. 'uid' => $pairUid, 'stage_id' => $stage_id
  52. ], [
  53. 'state' => 103
  54. ]);
  55. if ($pairPair->assoc_id || $userPair->assoc_id) {
  56. throw new DBException('用户已有匹配对象');
  57. }
  58. $userPair->assoc_id = $pairPair->id;
  59. $userPair->confirm = time();
  60. $userPair->state = 400 + $userPair->state % 100;
  61. $pairPair->assoc_id = $userPair->id;
  62. $pairPair->confirm = time();
  63. $pairPair->state = 400 + $pairPair->state % 100;
  64. $userPair->save() && $pairPair->save();
  65. });
  66. }
  67. private function getGoods()
  68. {
  69. $goods = $this->orderModel::GOODS[3];
  70. return $goods;
  71. }
  72. /**
  73. * 获取某人最近一期的状态
  74. * @param int $uid
  75. * @return array
  76. */
  77. public function getRecentState(int $uid): array
  78. {
  79. $next = PairModel::where('uid', $uid)->OrderBy('stage_id', 'desc')->first();
  80. if (collect($next)->isEmpty()) {
  81. return [];
  82. } else {
  83. $result = $next->toArray();
  84. $activity = ActivityModel::findOrFail($next->stage_id, [
  85. 'activity_name',
  86. 'activity_time',
  87. 'close_time',
  88. 'signbegin_time',
  89. 'signend_time',
  90. 'open_time',
  91. 'rematched_at',
  92. 'qbj_stage_id'
  93. ]);
  94. $result = array_merge($result, $activity->toArray());
  95. try {
  96. $progress = $next->progress();
  97. $result['progress'] = $progress;
  98. } catch (\Exception $e) {
  99. app('sentry')->captureException($e);
  100. }
  101. $result['pair_info'] = array();
  102. $result['activity'] = $activity;
  103. if (empty($result['assoc_id'])) {
  104. return $result;
  105. }
  106. $result['pair_info']['room_info'] = RoomModel::find($result['room_id']) ?? [];
  107. $partner_pair = PairModel::findOrFail($result['assoc_id']);
  108. $partner_user = UserModel::findOrFail($partner_pair->uid);
  109. $result['pair_info']['partner_info'] = array_merge($partner_pair->toArray(), $partner_user->toArray());
  110. $user = UserModel::findOrFail($uid);
  111. $result['pair_info']['user_info'] = array_merge($next->toArray(), $user->toArray());
  112. return $result;
  113. }
  114. }
  115. /**
  116. * 获取某人最近一期的状态
  117. * @param int $uid
  118. * @param int $stage_id
  119. * @return array
  120. */
  121. public function getActivityInfo(int $uid, int $stage_id): array
  122. {
  123. $next = PairModel::where([
  124. ['uid', $uid],
  125. ['stage_id', $stage_id]
  126. ])->first();
  127. if (collect($next)->isEmpty()) {
  128. return array();
  129. } else {
  130. $result = $next->toArray();
  131. $activity = ActivityModel::find($next->stage_id, [
  132. 'stage_id',
  133. 'activity_name',
  134. 'activity_time',
  135. 'close_time',
  136. 'signbegin_time',
  137. 'signend_time',
  138. 'open_time',
  139. 'rematch_begin_at',
  140. 'rematched_at'
  141. ]);
  142. $result['activity'] = $activity;
  143. $result = array_merge($result, $activity->toArray());
  144. $result['pair_info'] = array();
  145. $user = UserModel::find($uid);
  146. try {
  147. $progress = $next->progress();
  148. $result['progress'] = $progress;
  149. } catch (\Exception $e) {
  150. app('sentry')->captureException($e);
  151. }
  152. $result['pair_info']['user_info'] = array_merge($next->toArray(), $user->toArray());
  153. if (empty($result['assoc_id'])) {
  154. return $result;
  155. }
  156. $result['pair_info']['room_info'] = RoomModel::find($result['room_id']) ?? [];
  157. $result['pair_info']['group'] = GroupModel::find($result['group_id']);
  158. $partner_pair = PairModel::find($result['assoc_id']);
  159. $partner_user = UserModel::find($partner_pair->uid);
  160. $result['pair_info']['partner_info'] = array_merge($partner_pair->toArray(), $partner_user->toArray());
  161. return $result;
  162. }
  163. }
  164. /**
  165. * 获取保持关联的房间
  166. * @param int $uid
  167. * @return int $room_id | null
  168. */
  169. public function getKeepRoom(int $uid)
  170. {
  171. $keep_rooms = Redis::smembers("keep_rooms");
  172. $room_id = PairModel::where('uid', $uid)->whereIn("room_id", $keep_rooms)->value('room_id');
  173. return $room_id;
  174. }
  175. /**
  176. * 保持关系
  177. * @param int $uid
  178. * @param int $room_id
  179. * @throws AlertException
  180. */
  181. public function keepRoom(int $uid, int $room_id)
  182. {
  183. $pair = PairModel::where(['uid' => $uid, 'keep' => 1])->first();
  184. if ($pair) {
  185. //
  186. if (RoomModel::where('room_id', $pair->room_id)->where('keep', 1)->first()) {
  187. throw new AlertException("只能跟一个CP保持关系", 403);
  188. } else {
  189. $this->unKeep($uid, $pair->room_id);
  190. }
  191. }
  192. $pair = PairModel::where(['uid' => $uid, 'room_id' => $room_id])->first();
  193. if (!$pair) {
  194. throw new AlertException("不存在", 404);
  195. }
  196. $activity = ActivityModel::findOrFail($pair->stage_id);
  197. if ($activity->open_time > time() && $activity->close_time <= time()) {
  198. throw new AlertException("只能在活动期间保持关系", 410);
  199. }
  200. $pair->keep = 1;
  201. $pair->save();
  202. $other = PairModel::find($pair->assoc_id);
  203. if ($other->keep == 1) {
  204. Redis::sadd("keep_rooms", [$room_id]);
  205. }
  206. }
  207. /**
  208. * 移除关联房间
  209. * @param $uid
  210. * @param $room_id
  211. * @throws CustomErrorMessageException
  212. */
  213. public function removeKeepRoom($uid, $room_id)
  214. {
  215. $pair = PairModel::where(['uid' => $uid, 'keep' => 1, 'room_id' => $room_id])->first();
  216. if (!$pair) {
  217. throw new CustomErrorMessageException('');
  218. }
  219. $pair->keep = 0;
  220. $pair->save();
  221. Redis::srem("keep_rooms", $room_id);
  222. }
  223. /**
  224. * 获取落单群
  225. * @param $uid
  226. * @param $stage_id
  227. * @return mixed
  228. * @throws AlertException
  229. */
  230. public function getAloneGroup($uid, $stage_id)
  231. {
  232. $activity_type = '72h';
  233. $group_id = GroupMemberModel::where([
  234. 'stage_id' => $stage_id,
  235. 'uid' => $uid,
  236. 'activity_type' => $activity_type,
  237. 'type' => 'alone'
  238. ])->value('group_id');
  239. if (!$group_id) {
  240. $groups = GroupModel::where([
  241. 'stage_id' => $stage_id,
  242. 'type' => 'alone',
  243. 'activity_type' => $activity_type
  244. ])->get();
  245. foreach ($groups as $group) {
  246. $number = GroupMemberModel::where([
  247. 'stage_id' => $stage_id,
  248. 'group_id' => $group->id,
  249. 'activity_type' => $activity_type,
  250. 'type' => 'alone'
  251. ])->count();
  252. if ($number < $group->number) {
  253. $group_id = $group->id;
  254. break;
  255. }
  256. }
  257. if (empty($group_id)) {
  258. throw new AlertException("落单群已经满", 401);
  259. }
  260. GroupMemberModel::create([
  261. 'uid' => $uid,
  262. 'stage_id' => $stage_id,
  263. 'group_id' => $group_id,
  264. 'activity_type' => $activity_type,
  265. 'type' => 'alone'
  266. ]);
  267. }
  268. return $group_id;
  269. }
  270. /**
  271. * 免费报名
  272. * @param int $uid
  273. * @param $stageId
  274. * @param array $attach
  275. * @return PairModel|\Illuminate\Database\Eloquent\Model
  276. * @throws CustomErrorMessageException
  277. */
  278. public function enrollFree(int $uid, $stageId, array $attach)
  279. {
  280. if (PairModel::where([['uid', $uid], ['stage_id', $stageId]])->exists()) {
  281. throw new CustomErrorMessageException("你已经报名了72小时恋爱体验,请勿重复报名哦");
  282. }
  283. $pair = PairModel::create($attach);
  284. // 通知
  285. if ($pair->state > 100) {
  286. try {
  287. $notice = new \App\Services\Pair\NoticeService();
  288. $notice->inviteToSuccess($uid);
  289. } catch (\Exception $e) {
  290. app('sentry')->captureException($e);
  291. }
  292. }
  293. return $pair;
  294. }
  295. /**
  296. * 退款
  297. * @param PairModel $pair
  298. * @throws CustomErrorMessageException
  299. */
  300. public function refund(PairModel $pair)
  301. {
  302. if (!in_array(floor($pair->state / 100), [3, 5, 9])) {
  303. throw new CustomErrorMessageException("订单不可退");
  304. }
  305. try {
  306. DB::beginTransaction();
  307. switch ($pair->state % 100) {
  308. case 1:
  309. case 4:
  310. if ($pair->pay > 0) {
  311. $pair->pay = 0;
  312. $pair->state = 600 + $pair->state % 100;
  313. $pair->save();
  314. $order = new OrderService();
  315. $order->refund($pair->order_id, $pair->pay * 100, "72小时CP退款", true);
  316. if ($pair->fx_money) {
  317. MediaOrderModel::create([
  318. 'media_id' => $pair->media_id,
  319. 'type' => 'refund',
  320. 'amount' => -($pair->fx_money * 100),
  321. 'tag' => '分配对象',
  322. 'describe' => "用户分配对象活动第{$pair->stage_id}期退款(订单ID:{$pair->order_id})",
  323. ]);
  324. }
  325. } else {
  326. if ($pair->state > 900 && $pair->state < 1000) {
  327. $pair->state = 1101;
  328. $pair->save();
  329. } else {
  330. $pair->state = 601;
  331. $pair->save();
  332. }
  333. }
  334. DB::commit();
  335. break;
  336. case 2:
  337. $pair->state = 1102;
  338. $pair->save();
  339. DB::commit();
  340. break;
  341. case 3:
  342. if ($pair->pay > 0) {
  343. $pair->pay = 0;
  344. if ($pair->state > 900 && $pair->state < 1000) {
  345. $pair->state = 1103;
  346. } else {
  347. $pair->state = 603;
  348. }
  349. $pair->save();
  350. $order = new OrderService();
  351. $order->refund($pair->order_id, $pair->pay * 100, "72小时CP退款", true);
  352. if ($pair->fx_money) {
  353. MediaOrderModel::create([
  354. 'media_id' => $pair->media_id,
  355. 'type' => 'refund',
  356. 'amount' => -($pair->fx_money * 100),
  357. 'tag' => '分配对象',
  358. 'describe' => "用户分配对象活动第{$pair->stage_id}期退款(订单ID:{$pair->order_id})",
  359. ]);
  360. }
  361. } else {
  362. if ($pair->state > 900 && $pair->state < 1000) {
  363. $pair->state = 1103;
  364. } else {
  365. $pair->state = 603;
  366. }
  367. $pair->save();
  368. }
  369. DB::commit();
  370. break;
  371. }
  372. } catch (\Exception $e) {
  373. DB::rollBack();
  374. throw new CustomErrorMessageException('退款失败请尝试联系运营人员');
  375. }
  376. }
  377. /**
  378. * 报名下一期
  379. * @param PairModel $pair
  380. * @param array $attribute
  381. * @throws CustomErrorMessageException
  382. */
  383. public function enrollNext(PairModel $pair, array $attribute)
  384. {
  385. switch ($pair / 100) {
  386. case "3":
  387. $attribute['state'] = 100 + intval($pair->state) % 100; // 自动报名成功
  388. $attribute['order_id'] = $pair->order_id; // 携带报名费用
  389. $attribute['pay'] = $pair->pay; // 携带报名费用
  390. $attribute['score'] = $pair->score; // 携带报名分数
  391. $attribute['add_score'] = $pair->add_score; // 携带报名分数
  392. $pair->state = 700 + intval($pair->state) % 100;
  393. break;
  394. case "5":
  395. $attribute['state'] = 100 + intval($pair->state) % 100; // 自动报名成功
  396. $attribute['order_id'] = $pair->order_id; // 携带报名费用
  397. $attribute['pay'] = $pair->pay; // 携带报名费用
  398. $attribute['score'] = $pair->score; // 携带报名分数
  399. $attribute['add_score'] = $pair->add_score;
  400. $pair->state = 700 + intval($pair->state) % 100; // 本期状态 => 70x
  401. break;
  402. case "4":
  403. case "8":
  404. $attribute['state'] = 100 + intval($pair->state) % 100; // 自动报名成功: 是
  405. $attribute['score'] = $pair->score; // 携带报名分数: 是
  406. $attribute['add_score'] = $pair->add_score;
  407. $pair->state = 700 + intval($pair->state) % 100; // 本期状态 => 70x
  408. break;
  409. default:
  410. throw new CustomErrorMessageException("不支持报名下一期");
  411. break;
  412. }
  413. $pair->save();
  414. $newPair = $this->pairModel->fill($attribute);
  415. $newPair->save();
  416. }
  417. }