FriendLogic.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. <?php
  2. namespace App\Module\Friend\Logics;
  3. use App\Module\Friend\Enums\ERROR_CODE;
  4. use App\Module\Friend\Enums\FRIEND_STATUS;
  5. use App\Module\Friend\Models\FriendRelation;
  6. use App\Module\User\Models\User;
  7. use App\Module\User\Services\UserService;
  8. use Illuminate\Pagination\LengthAwarePaginator;
  9. use Illuminate\Support\Facades\Log;
  10. /**
  11. * 好友逻辑类
  12. *
  13. * 实现好友关系的核心业务逻辑,包括好友添加、删除、查询等功能。
  14. * 该类仅供内部使用,不对外提供服务。
  15. */
  16. class FriendLogic
  17. {
  18. /**
  19. * 好友数量上限
  20. *
  21. * @var int
  22. */
  23. protected $friendLimit = 100;
  24. /**
  25. * 获取用户的好友列表
  26. *
  27. * @param int $userId 用户ID
  28. * @param int $page 页码
  29. * @param int $limit 每页数量
  30. * @param array $filters 过滤条件
  31. * @return array 好友列表数据
  32. */
  33. public function getFriendList(int $userId, int $page = 1, int $limit = 20, array $filters = []): array
  34. {
  35. // 构建查询条件
  36. $where = [
  37. 'user_id' => $userId,
  38. 'status' => $filters['status'] ?? FRIEND_STATUS::NORMAL
  39. ];
  40. if (isset($filters['group_id'])) {
  41. $where['group_id'] = $filters['group_id'];
  42. }
  43. // 设置排序
  44. if (isset($filters['sort_by']) && isset($filters['sort_order'])) {
  45. $where['_sort_field'] = $filters['sort_by'];
  46. $where['_sort_order'] = $filters['sort_order'];
  47. } else {
  48. $where['_sort_field'] = 'intimacy';
  49. $where['_sort_order'] = 'desc';
  50. }
  51. // 查询好友关系
  52. $relations = FriendRelation::where($where)
  53. ->with('friend')
  54. ->paginate($limit, ['*'], 'page', $page);
  55. // 格式化数据
  56. $items = [];
  57. foreach ($relations as $relation) {
  58. if (!$relation->friend) {
  59. continue;
  60. }
  61. $items[] = [
  62. 'user_id' => $relation->friend_id,
  63. 'nickname' => $relation->friend->nickname ?? '',
  64. 'avatar' => $relation->friend->avatar ?? '',
  65. 'level' => $relation->friend->level ?? 1,
  66. 'status' => $this->getUserOnlineStatus($relation->friend_id),
  67. 'last_login' => $relation->friend->last_login_at ?? 0,
  68. 'remark' => $relation->remark,
  69. 'intimacy' => $relation->intimacy,
  70. ];
  71. }
  72. return [
  73. 'total' => $relations->total(),
  74. 'per_page' => $relations->perPage(),
  75. 'current_page' => $relations->currentPage(),
  76. 'last_page' => $relations->lastPage(),
  77. 'items' => $items
  78. ];
  79. }
  80. /**
  81. * 搜索可添加为好友的用户
  82. *
  83. * @param int $userId 当前用户ID
  84. * @param string $keyword 搜索关键词
  85. * @param int $page 页码
  86. * @param int $limit 每页数量
  87. * @return array 搜索结果
  88. */
  89. public function searchUsers(int $userId, string $keyword, int $page = 1, int $limit = 20): array
  90. {
  91. // 构建查询条件
  92. $query = User::query();
  93. // 排除当前用户
  94. $query->where('id', '!=', $userId);
  95. // 根据关键词搜索
  96. if (is_numeric($keyword)) {
  97. // 如果是数字,则按ID搜索
  98. $query->where('id', $keyword);
  99. } else {
  100. // 否则按昵称搜索
  101. $query->where('nickname', 'like', "%{$keyword}%");
  102. }
  103. // 执行分页查询
  104. $users = $query->paginate($limit, ['id', 'nickname', 'avatar', 'level'], 'page', $page);
  105. // 获取当前用户的好友ID列表
  106. $friendIds = FriendRelation::where('user_id', $userId)
  107. ->where('status', FRIEND_STATUS::NORMAL)
  108. ->pluck('friend_id')
  109. ->toArray();
  110. // 获取当前用户已发送申请的用户ID列表
  111. $requestLogic = new RequestLogic();
  112. $requestedIds = $requestLogic->getSentRequestUserIds($userId);
  113. // 格式化数据
  114. $items = [];
  115. foreach ($users as $user) {
  116. $relation = 0; // 0:无关系, 1:已是好友, 2:已申请
  117. if (in_array($user->id, $friendIds)) {
  118. $relation = 1;
  119. } elseif (in_array($user->id, $requestedIds)) {
  120. $relation = 2;
  121. }
  122. $items[] = [
  123. 'user_id' => $user->id,
  124. 'nickname' => $user->nickname ?? '',
  125. 'avatar' => $user->avatar ?? '',
  126. 'level' => $user->level ?? 1,
  127. 'relation' => $relation
  128. ];
  129. }
  130. return [
  131. 'total' => $users->total(),
  132. 'per_page' => $users->perPage(),
  133. 'current_page' => $users->currentPage(),
  134. 'last_page' => $users->lastPage(),
  135. 'items' => $items
  136. ];
  137. }
  138. /**
  139. * 创建好友关系
  140. *
  141. * @param int $userId 用户ID
  142. * @param int $friendId 好友ID
  143. * @param string|null $remark 备注名
  144. * @return array 操作结果
  145. */
  146. public function createFriendRelation(int $userId, int $friendId, ?string $remark = null): array
  147. {
  148. try {
  149. // 检查是否已经是好友
  150. $existingRelation = FriendRelation::where('user_id', $userId)
  151. ->where('friend_id', $friendId)
  152. ->first();
  153. if ($existingRelation) {
  154. if ($existingRelation->status == FRIEND_STATUS::NORMAL) {
  155. return [
  156. 'success' => false,
  157. 'code' => ERROR_CODE::ALREADY_FRIEND,
  158. 'message' => '已经是好友关系'
  159. ];
  160. } else {
  161. // 如果是黑名单状态,则更新为正常状态
  162. $existingRelation->status = FRIEND_STATUS::NORMAL;
  163. $existingRelation->save();
  164. return [
  165. 'success' => true,
  166. 'data' => $existingRelation
  167. ];
  168. }
  169. }
  170. // 检查好友数量是否达到上限
  171. $friendCount = FriendRelation::where('user_id', $userId)
  172. ->where('status', FRIEND_STATUS::NORMAL)
  173. ->count();
  174. if ($friendCount >= $this->friendLimit) {
  175. return [
  176. 'success' => false,
  177. 'code' => ERROR_CODE::FRIEND_LIMIT_REACHED,
  178. 'message' => '好友数量已达上限'
  179. ];
  180. }
  181. // 检查事务是否已开启
  182. \UCore\Db\Helper::check_tr();
  183. // 创建A->B的关系
  184. $relationAB = FriendRelation::create([
  185. 'user_id' => $userId,
  186. 'friend_id' => $friendId,
  187. 'remark' => $remark,
  188. 'group_id' => 0,
  189. 'intimacy' => 0,
  190. 'status' => FRIEND_STATUS::NORMAL,
  191. ]);
  192. // 创建B->A的关系
  193. $relationBA = FriendRelation::create([
  194. 'user_id' => $friendId,
  195. 'friend_id' => $userId,
  196. 'remark' => null,
  197. 'group_id' => 0,
  198. 'intimacy' => 0,
  199. 'status' => FRIEND_STATUS::NORMAL,
  200. ]);
  201. return [
  202. 'success' => true,
  203. 'data' => $relationAB
  204. ];
  205. } catch (\Exception $e) {
  206. Log::error('创建好友关系失败: ' . $e->getMessage());
  207. return [
  208. 'success' => false,
  209. 'code' => ERROR_CODE::PARAM_ERROR,
  210. 'message' => '创建好友关系失败'
  211. ];
  212. }
  213. }
  214. /**
  215. * 删除好友关系
  216. *
  217. * @param int $userId 用户ID
  218. * @param int $friendId 好友ID
  219. * @return array 操作结果
  220. */
  221. public function deleteFriend(int $userId, int $friendId): array
  222. {
  223. try {
  224. // 检查是否存在好友关系
  225. $relation = FriendRelation::where('user_id', $userId)
  226. ->where('friend_id', $friendId)
  227. ->where('status', FRIEND_STATUS::NORMAL)
  228. ->first();
  229. if (!$relation) {
  230. return [
  231. 'success' => false,
  232. 'code' => ERROR_CODE::RELATION_NOT_EXIST,
  233. 'message' => '好友关系不存在'
  234. ];
  235. }
  236. // 检查事务是否已开启
  237. \UCore\Db\Helper::check_tr();
  238. // 删除A->B的关系
  239. FriendRelation::where('user_id', $userId)
  240. ->where('friend_id', $friendId)
  241. ->delete();
  242. // 删除B->A的关系
  243. FriendRelation::where('user_id', $friendId)
  244. ->where('friend_id', $userId)
  245. ->delete();
  246. return [
  247. 'success' => true
  248. ];
  249. } catch (\Exception $e) {
  250. Log::error('删除好友关系失败: ' . $e->getMessage());
  251. return [
  252. 'success' => false,
  253. 'code' => ERROR_CODE::PARAM_ERROR,
  254. 'message' => '删除好友关系失败'
  255. ];
  256. }
  257. }
  258. /**
  259. * 更新好友备注
  260. *
  261. * @param int $userId 用户ID
  262. * @param int $friendId 好友ID
  263. * @param string $remark 备注名
  264. * @return array 操作结果
  265. */
  266. public function updateFriendRemark(int $userId, int $friendId, string $remark): array
  267. {
  268. try {
  269. // 检查是否存在好友关系
  270. $relation = FriendRelation::where('user_id', $userId)
  271. ->where('friend_id', $friendId)
  272. ->where('status', FRIEND_STATUS::NORMAL)
  273. ->first();
  274. if (!$relation) {
  275. return [
  276. 'success' => false,
  277. 'code' => ERROR_CODE::RELATION_NOT_EXIST,
  278. 'message' => '好友关系不存在'
  279. ];
  280. }
  281. // 更新备注
  282. $relation->remark = $remark;
  283. $relation->save();
  284. return [
  285. 'success' => true
  286. ];
  287. } catch (\Exception $e) {
  288. Log::error('更新好友备注失败: ' . $e->getMessage());
  289. return [
  290. 'success' => false,
  291. 'code' => ERROR_CODE::PARAM_ERROR,
  292. 'message' => '更新好友备注失败'
  293. ];
  294. }
  295. }
  296. /**
  297. * 获取用户在线状态
  298. *
  299. * @param int $userId 用户ID
  300. * @return int 状态:1在线,2离线
  301. */
  302. protected function getUserOnlineStatus(int $userId): int
  303. {
  304. // TODO: 实现获取用户在线状态的逻辑
  305. // 这里可以调用用户模块的相关服务或者查询缓存
  306. return 2; // 默认离线
  307. }
  308. }