Friend.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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 Illuminate\Support\Collection;
  8. use Illuminate\Support\Facades\DB;
  9. use Illuminate\Support\Facades\Log;
  10. /**
  11. * 好友关系逻辑类
  12. *
  13. * 实现好友关系的核心业务逻辑,包括好友添加、删除、查询等功能。
  14. * 该类仅供内部使用,不对外提供服务。
  15. */
  16. class Friend
  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. $query = FriendRelation::where('user_id', $userId);
  37. // 应用状态过滤
  38. if (isset($filters['status'])) {
  39. $query->where('status', $filters['status']);
  40. } else {
  41. // 默认只查询正常状态的好友
  42. $query->where('status', FRIEND_STATUS::NORMAL);
  43. }
  44. // 应用分组过滤
  45. if (isset($filters['group_id'])) {
  46. $query->where('group_id', $filters['group_id']);
  47. }
  48. // 应用关键词搜索(好友备注)
  49. if (isset($filters['keyword']) && !empty($filters['keyword'])) {
  50. $query->where('remark', 'like', '%' . $filters['keyword'] . '%');
  51. }
  52. // 应用排序
  53. if (isset($filters['sort_by']) && isset($filters['sort_order'])) {
  54. $query->orderBy($filters['sort_by'], $filters['sort_order']);
  55. } else {
  56. // 默认按亲密度降序排列
  57. $query->orderBy('intimacy', 'desc');
  58. }
  59. // 执行分页查询
  60. $relations = $query->with('friend')->paginate($limit, ['*'], 'page', $page);
  61. // 格式化数据
  62. $items = [];
  63. foreach ($relations as $relation) {
  64. if (!$relation->friend) {
  65. continue;
  66. }
  67. $items[] = [
  68. 'user_id' => $relation->friend_id,
  69. 'nickname' => $relation->friend->nickname ?? '',
  70. 'avatar' => $relation->friend->avatar ?? '',
  71. 'level' => $relation->friend->level ?? 1,
  72. 'status' => $this->getUserOnlineStatus($relation->friend_id),
  73. 'last_login' => $relation->friend->last_login_at ?? 0,
  74. 'remark' => $relation->remark,
  75. 'intimacy' => $relation->intimacy,
  76. ];
  77. }
  78. return [
  79. 'total' => $relations->total(),
  80. 'per_page' => $relations->perPage(),
  81. 'current_page' => $relations->currentPage(),
  82. 'last_page' => $relations->lastPage(),
  83. 'items' => $items
  84. ];
  85. }
  86. /**
  87. * 创建好友关系
  88. *
  89. * @param int $userId 用户ID
  90. * @param int $friendId 好友ID
  91. * @param string|null $remark 备注名
  92. * @return array 操作结果
  93. */
  94. public function createFriendRelation(int $userId, int $friendId, ?string $remark = null): array
  95. {
  96. try {
  97. // 检查是否已经是好友
  98. $existingRelation = FriendRelation::where('user_id', $userId)
  99. ->where('friend_id', $friendId)
  100. ->first();
  101. if ($existingRelation) {
  102. if ($existingRelation->status == FRIEND_STATUS::NORMAL) {
  103. return [
  104. 'success' => false,
  105. 'code' => ERROR_CODE::ALREADY_FRIEND,
  106. 'message' => '已经是好友关系'
  107. ];
  108. } else {
  109. // 如果是黑名单状态,则更新为正常状态
  110. $existingRelation->status = FRIEND_STATUS::NORMAL;
  111. $existingRelation->save();
  112. return [
  113. 'success' => true,
  114. 'data' => $existingRelation
  115. ];
  116. }
  117. }
  118. // 检查好友数量是否达到上限
  119. $friendCount = FriendRelation::where('user_id', $userId)
  120. ->where('status', FRIEND_STATUS::NORMAL)
  121. ->count();
  122. if ($friendCount >= $this->friendLimit) {
  123. return [
  124. 'success' => false,
  125. 'code' => ERROR_CODE::FRIEND_LIMIT_REACHED,
  126. 'message' => '好友数量已达上限'
  127. ];
  128. }
  129. // 创建好友关系(双向)
  130. DB::beginTransaction();
  131. // 创建A->B的关系
  132. $relationAB = FriendRelation::create([
  133. 'user_id' => $userId,
  134. 'friend_id' => $friendId,
  135. 'remark' => $remark,
  136. 'group_id' => 0,
  137. 'intimacy' => 0,
  138. 'status' => FRIEND_STATUS::NORMAL,
  139. ]);
  140. // 创建B->A的关系
  141. $relationBA = FriendRelation::create([
  142. 'user_id' => $friendId,
  143. 'friend_id' => $userId,
  144. 'remark' => null,
  145. 'group_id' => 0,
  146. 'intimacy' => 0,
  147. 'status' => FRIEND_STATUS::NORMAL,
  148. ]);
  149. DB::commit();
  150. return [
  151. 'success' => true,
  152. 'data' => $relationAB
  153. ];
  154. } catch (\Exception $e) {
  155. DB::rollBack();
  156. Log::error('创建好友关系失败: ' . $e->getMessage());
  157. return [
  158. 'success' => false,
  159. 'code' => ERROR_CODE::PARAM_ERROR,
  160. 'message' => '创建好友关系失败'
  161. ];
  162. }
  163. }
  164. /**
  165. * 删除好友关系
  166. *
  167. * @param int $userId 用户ID
  168. * @param int $friendId 好友ID
  169. * @return array 操作结果
  170. */
  171. public function deleteFriend(int $userId, int $friendId): array
  172. {
  173. try {
  174. // 检查是否存在好友关系
  175. $relation = FriendRelation::where('user_id', $userId)
  176. ->where('friend_id', $friendId)
  177. ->where('status', FRIEND_STATUS::NORMAL)
  178. ->first();
  179. if (!$relation) {
  180. return [
  181. 'success' => false,
  182. 'code' => ERROR_CODE::RELATION_NOT_EXIST,
  183. 'message' => '好友关系不存在'
  184. ];
  185. }
  186. // 删除双向好友关系
  187. DB::beginTransaction();
  188. // 删除A->B的关系
  189. FriendRelation::where('user_id', $userId)
  190. ->where('friend_id', $friendId)
  191. ->delete();
  192. // 删除B->A的关系
  193. FriendRelation::where('user_id', $friendId)
  194. ->where('friend_id', $userId)
  195. ->delete();
  196. DB::commit();
  197. return [
  198. 'success' => true
  199. ];
  200. } catch (\Exception $e) {
  201. DB::rollBack();
  202. Log::error('删除好友关系失败: ' . $e->getMessage());
  203. return [
  204. 'success' => false,
  205. 'code' => ERROR_CODE::PARAM_ERROR,
  206. 'message' => '删除好友关系失败'
  207. ];
  208. }
  209. }
  210. /**
  211. * 更新好友备注
  212. *
  213. * @param int $userId 用户ID
  214. * @param int $friendId 好友ID
  215. * @param string $remark 备注名
  216. * @return array 操作结果
  217. */
  218. public function updateFriendRemark(int $userId, int $friendId, string $remark): array
  219. {
  220. try {
  221. // 检查是否存在好友关系
  222. $relation = FriendRelation::where('user_id', $userId)
  223. ->where('friend_id', $friendId)
  224. ->where('status', FRIEND_STATUS::NORMAL)
  225. ->first();
  226. if (!$relation) {
  227. return [
  228. 'success' => false,
  229. 'code' => ERROR_CODE::RELATION_NOT_EXIST,
  230. 'message' => '好友关系不存在'
  231. ];
  232. }
  233. // 更新备注
  234. $relation->remark = $remark;
  235. $relation->save();
  236. return [
  237. 'success' => true
  238. ];
  239. } catch (\Exception $e) {
  240. Log::error('更新好友备注失败: ' . $e->getMessage());
  241. return [
  242. 'success' => false,
  243. 'code' => ERROR_CODE::PARAM_ERROR,
  244. 'message' => '更新好友备注失败'
  245. ];
  246. }
  247. }
  248. /**
  249. * 获取用户在线状态
  250. *
  251. * @param int $userId 用户ID
  252. * @return int 状态:1在线,2离线
  253. */
  254. protected function getUserOnlineStatus(int $userId): int
  255. {
  256. // TODO: 实现获取用户在线状态的逻辑
  257. // 这里可以调用用户模块的相关服务或者查询缓存
  258. return 2; // 默认离线
  259. }
  260. }