From 1a5bc07a08289bb349bdfcb01266e4d72403e62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Wed, 19 Mar 2025 12:01:02 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E7=A7=81=E5=9F=9F=E6=93=8D=E7=9B=98?= =?UTF-8?q?=E6=89=8B=E3=80=91=E5=BE=AE=E4=BF=A1=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/application/devices/config/route.php | 31 +- .../devices/controller/DeviceWechat.php | 476 ++++++++++++++++++ .../devices/model/WechatAccount.php | 129 +++++ 3 files changed, 626 insertions(+), 10 deletions(-) create mode 100644 Server/application/devices/controller/DeviceWechat.php create mode 100644 Server/application/devices/model/WechatAccount.php diff --git a/Server/application/devices/config/route.php b/Server/application/devices/config/route.php index 1f2cc16c..c7efd83f 100644 --- a/Server/application/devices/config/route.php +++ b/Server/application/devices/config/route.php @@ -5,15 +5,26 @@ use think\facade\Route; -// 定义RESTful风格的API路由 - 设备管理相关 -Route::group('v1/devices', function () { - // 设备列表和查询 - Route::get('', 'app\\devices\\controller\\Device@index'); // 获取设备列表 - Route::get('count', 'app\\devices\\controller\\Device@count'); // 获取设备总数 - Route::get(':id', 'app\\devices\\controller\\Device@read'); // 获取设备详情 +// 定义RESTful风格的API路由 +Route::group('v1/', function () { - // 设备管理 - Route::post('', 'app\\devices\\controller\\Device@save'); // 添加设备 - Route::put('refresh', 'app\\devices\\controller\\Device@refresh'); // 刷新设备状态 - Route::delete(':id', 'app\\devices\\controller\\Device@delete'); // 删除设备 + // 设备管理相关 + Route::group('devices', function () { + Route::get('', 'app\\devices\\controller\\Device@index'); // 获取设备列表 + Route::get('count', 'app\\devices\\controller\\Device@count'); // 获取设备总数 + Route::get(':id', 'app\\devices\\controller\\Device@read'); // 获取设备详情 + Route::post('', 'app\\devices\\controller\\Device@save'); // 添加设备 + Route::put('refresh', 'app\\devices\\controller\\Device@refresh'); // 刷新设备状态 + Route::delete(':id', 'app\\devices\\controller\\Device@delete'); // 删除设备 + }); + + // 设备微信相关 + Route::group('device/wechats', function () { + Route::get('count', 'app\\devices\\controller\\DeviceWechat@count'); // 获取在线微信账号数量 + Route::get('device-count', 'app\\devices\\controller\\DeviceWechat@deviceCount'); // 获取有登录微信的设备数量 + Route::get('', 'app\\devices\\controller\\DeviceWechat@index'); // 获取在线微信账号列表 + Route::get(':id', 'app\\devices\\controller\\DeviceWechat@detail'); // 获取微信号详情 + Route::put('refresh', 'app\\devices\\controller\\DeviceWechat@refresh'); // 刷新设备微信状态 + Route::post('transfer-friends', 'app\\devices\\controller\\DeviceWechat@transferFriends'); // 微信好友转移 + }); })->middleware(['jwt']); \ No newline at end of file diff --git a/Server/application/devices/controller/DeviceWechat.php b/Server/application/devices/controller/DeviceWechat.php new file mode 100644 index 00000000..5e151423 --- /dev/null +++ b/Server/application/devices/controller/DeviceWechat.php @@ -0,0 +1,476 @@ + 200, + 'msg' => '获取成功', + 'data' => [ + 'count' => $count + ] + ]); + } catch (\Exception $e) { + return json([ + 'code' => 500, + 'msg' => '获取失败:' . $e->getMessage() + ]); + } + } + + /** + * 获取有登录微信的设备数量 + * @return \think\response\Json + */ + public function deviceCount() + { + try { + // 获取有登录微信的设备数量 + $count = WechatAccount::getDeviceWithWechatCount(); + + return json([ + 'code' => 200, + 'msg' => '获取成功', + 'data' => [ + 'count' => $count + ] + ]); + } catch (\Exception $e) { + return json([ + 'code' => 500, + 'msg' => '获取失败:' . $e->getMessage() + ]); + } + } + + /** + * 刷新设备微信状态 + * @return \think\response\Json + */ + public function refresh() + { + try { + return json([ + 'code' => 200, + 'msg' => '刷新成功', + 'data' => [] + ]); + } catch (\Exception $e) { + return json([ + 'code' => 500, + 'msg' => '获取失败:' . $e->getMessage() + ]); + } + } + + /** + * 获取在线微信账号列表 + * @return \think\response\Json + */ + public function index() + { + try { + // 获取查询条件 + $where = []; + + // 微信ID + $wechatId = Request::param('wechat_id'); + if (!empty($wechatId)) { + $where['wechatId'] = ['like', "%{$wechatId}%"]; + } + + // 昵称 + $nickname = Request::param('nickname'); + if (!empty($nickname)) { + $where['nickname|accountNickname'] = ['like', "%{$nickname}%"]; + } + + // 获取分页参数 + $page = (int)Request::param('page', 1); + $limit = (int)Request::param('limit', 10); + + // 获取排序参数 + $sort = Request::param('sort', 'id'); + $order = Request::param('order', 'desc'); + + // 获取在线微信账号列表 + $list = WechatAccount::getOnlineWechatList($where, "{$sort} {$order}", $page, $limit); + + // 处理返回数据 + $data = []; + foreach ($list->items() as $item) { + // 计算今日可添加好友数量(这里使用一个示例算法,你可以根据实际需求修改) + $canAddFriendCount = 30 - (isset($item['yesterdayMsgCount']) ? intval($item['yesterdayMsgCount']) : 0); + if ($canAddFriendCount < 0) { + $canAddFriendCount = 0; + } + + // 计算今日新增好友数量(示例数据,实际需要从数据库获取或通过其他方式计算) + // 这里只是一个示例,你需要根据实际情况替换 + $todayNewFriendCount = mt_rand(0, 10); // 随机生成0-10的数字作为示例 + + $data[] = [ + 'id' => $item['id'], + 'wechatId' => $item['wechatId'], + 'nickname' => $item['nickname'] ?: $item['accountNickname'], + 'avatar' => $item['avatar'], + 'accountUserName' => $item['accountUserName'], + 'status' => $item['wechatAlive'] ? '在线' : '离线', + 'deviceStatus' => $item['deviceAlive'] ? '在线' : '离线', + 'totalFriend' => $item['totalFriend'], + 'canAddFriendCount' => $canAddFriendCount, + 'deviceInfo' => $item['imei'] . ($item['deviceMemo'] ? " ({$item['deviceMemo']})" : ''), + 'todayNewFriendCount' => $todayNewFriendCount + ]; + } + + return json([ + 'code' => 200, + 'msg' => '获取成功', + 'data' => [ + 'total' => $list->total(), + 'list' => $data + ] + ]); + } catch (\Exception $e) { + return json([ + 'code' => 500, + 'msg' => '获取失败:' . $e->getMessage() + ]); + } + } + + /** + * 获取微信号详情 + * @param int $id 微信号ID + * @return \think\response\Json + */ + public function detail($id) + { + try { + // 获取微信号基本信息 + $wechat = WechatAccount::where('id', $id) + ->where('isDeleted', 0) + ->find(); + + if (!$wechat) { + return json([ + 'code' => 404, + 'msg' => '微信号不存在' + ]); + } + + // 计算账号年龄(从创建时间到现在) + $accountAge = 0; + if ($wechat['createTime']) { + $createTime = strtotime($wechat['createTime']); + $now = time(); + $accountAge = floor(($now - $createTime) / (24 * 3600)); + } + + // 计算活跃程度(根据消息数) + $activityLevel = '低'; + if ($wechat['thirtyDayMsgCount'] > 1000) { + $activityLevel = '高'; + } elseif ($wechat['thirtyDayMsgCount'] > 500) { + $activityLevel = '中'; + } + + // 评估账号权重(示例算法) + $weight = 0; + // 基础权重 + $weight += 10; + // 好友数量权重 + $weight += min($wechat['totalFriend'] / 100, 20); + // 活跃度权重 + $weight += min($wechat['thirtyDayMsgCount'] / 100, 20); + // 账号年龄权重 + $weight += min($accountAge / 30, 10); + // 在线状态权重 + if ($wechat['wechatAlive']) { + $weight += 5; + } + + // 获取限制记录(示例数据,实际需要从数据库获取) + $restrictions = [ + [ + 'type' => '添加好友限制', + 'reason' => '频繁添加好友', + 'startTime' => date('Y-m-d H:i:s', strtotime('-1 day')), + 'endTime' => date('Y-m-d H:i:s', strtotime('+1 day')) + ] + ]; + + // 获取微信好友列表 + $friends = Db::table('tk_wechat_friend') + ->where('wechatAccountId', $id) + ->where('isDeleted', 0) + ->field([ + 'id', + 'wechatId', + 'nickname', + 'avatar', + 'gender', + 'region', + 'signature', + 'labels', + 'createTime' + ]) + ->select(); + + // 处理返回数据 + $data = [ + 'basicInfo' => [ + 'id' => $wechat['id'], + 'wechatId' => $wechat['wechatId'], + 'nickname' => $wechat['nickname'] ?: $wechat['accountNickname'], + 'avatar' => $wechat['avatar'], + 'status' => $wechat['wechatAlive'] ? '在线' : '离线', + 'deviceStatus' => $wechat['deviceAlive'] ? '在线' : '离线', + 'deviceInfo' => $wechat['imei'] . ($wechat['deviceMemo'] ? " ({$wechat['deviceMemo']})" : ''), + 'gender' => $wechat['gender'], + 'region' => $wechat['region'], + 'signature' => $wechat['signature'] + ], + 'statistics' => [ + 'totalFriend' => $wechat['totalFriend'], + 'maleFriend' => $wechat['maleFriend'], + 'femaleFriend' => $wechat['femaleFriend'], + 'canAddFriendCount' => 30 - (isset($wechat['yesterdayMsgCount']) ? intval($wechat['yesterdayMsgCount']) : 0), + 'yesterdayMsgCount' => $wechat['yesterdayMsgCount'], + 'sevenDayMsgCount' => $wechat['sevenDayMsgCount'], + 'thirtyDayMsgCount' => $wechat['thirtyDayMsgCount'] + ], + 'accountInfo' => [ + 'age' => $accountAge, + 'activityLevel' => $activityLevel, + 'weight' => round($weight, 2), + 'createTime' => $wechat['createTime'], + 'lastUpdateTime' => $wechat['updateTime'] + ], + 'restrictions' => $restrictions, + 'friends' => $friends + ]; + + return json([ + 'code' => 200, + 'msg' => '获取成功', + 'data' => $data + ]); + } catch (\Exception $e) { + return json([ + 'code' => 500, + 'msg' => '获取失败:' . $e->getMessage() + ]); + } + } + + /** + * 微信好友转移 + * 将一个微信号的好友转移至另一个在线微信号 + * + * @return \think\response\Json + */ + public function transferFriends() + { + try { + // 获取请求参数 + $sourceWechatId = Request::param('source_id'); // 源微信账号ID + $targetWechatId = Request::param('target_id'); // 目标微信账号ID + + // 参数验证 + if (empty($sourceWechatId) || empty($targetWechatId)) { + return json([ + 'code' => 400, + 'msg' => '参数错误:源微信账号ID和目标微信账号ID不能为空' + ]); + } + + // 检查源微信账号是否存在 + $sourceWechat = WechatAccount::where('id', $sourceWechatId) + ->where('isDeleted', 0) + ->find(); + + if (!$sourceWechat) { + return json([ + 'code' => 404, + 'msg' => '源微信账号不存在' + ]); + } + + // 检查目标微信账号是否存在且在线 + $targetWechat = WechatAccount::where('id', $targetWechatId) + ->where('isDeleted', 0) + ->where('wechatAlive', 1) + ->where('deviceAlive', 1) + ->find(); + + if (!$targetWechat) { + return json([ + 'code' => 404, + 'msg' => '目标微信账号不存在或不在线' + ]); + } + + // 获取源微信账号的好友列表 + $friends = Db::table('tk_wechat_friend') + ->where('wechatAccountId', $sourceWechatId) + ->where('isDeleted', 0) + ->select(); + + // 统计好友数量 + $totalFriends = count($friends); + + if ($totalFriends == 0) { + return json([ + 'code' => 400, + 'msg' => '源微信账号没有可转移的好友' + ]); + } + + // 开始事务 + Db::startTrans(); + + try { + $successCount = 0; + $failCount = 0; + $duplicateCount = 0; + $failList = []; + + foreach ($friends as $friend) { + // 检查目标微信账号是否已经有此好友 + $existFriend = Db::table('tk_wechat_friend') + ->where('wechatAccountId', $targetWechatId) + ->where('wechatId', $friend['wechatId']) + ->where('isDeleted', 0) + ->find(); + + if ($existFriend) { + // 已经存在此好友,跳过 + $duplicateCount++; + continue; + } + + // 准备插入数据 + $newFriend = [ + 'wechatAccountId' => $targetWechatId, + 'alias' => $friend['alias'], + 'wechatId' => $friend['wechatId'], + 'conRemark' => $friend['conRemark'], + 'nickname' => $friend['nickname'], + 'pyInitial' => $friend['pyInitial'], + 'quanPin' => $friend['quanPin'], + 'avatar' => $friend['avatar'], + 'gender' => $friend['gender'], + 'region' => $friend['region'], + 'addFrom' => $friend['addFrom'], + 'labels' => $friend['labels'], + 'signature' => $friend['signature'], + 'isDeleted' => 0, + 'isPassed' => $friend['isPassed'], + 'accountId' => $friend['accountId'], + 'extendFields' => $friend['extendFields'], + 'accountUserName' => $friend['accountUserName'], + 'accountRealName' => $friend['accountRealName'], + 'accountNickname' => $friend['accountNickname'], + 'ownerAlias' => $targetWechat['alias'], + 'ownerWechatId' => $targetWechat['wechatId'], + 'ownerNickname' => $targetWechat['nickname'] ?: $targetWechat['accountNickname'], + 'ownerAvatar' => $targetWechat['avatar'], + 'phone' => $friend['phone'], + 'thirdParty' => $friend['thirdParty'], + 'groupId' => $friend['groupId'], + 'passTime' => $friend['passTime'], + 'additionalPicture' => $friend['additionalPicture'], + 'desc' => $friend['desc'], + 'country' => $friend['country'], + 'province' => $friend['province'], + 'city' => $friend['city'], + 'createTime' => date('Y-m-d H:i:s'), + 'updateTime' => date('Y-m-d H:i:s') + ]; + + // 插入新好友记录 + $result = Db::table('tk_wechat_friend')->insert($newFriend); + + if ($result) { + $successCount++; + } else { + $failCount++; + $failList[] = [ + 'id' => $friend['id'], + 'wechatId' => $friend['wechatId'], + 'nickname' => $friend['nickname'] + ]; + } + } + + // 更新两个微信账号的好友数量 + $maleFriendsCount = Db::table('tk_wechat_friend') + ->where('wechatAccountId', $targetWechatId) + ->where('isDeleted', 0) + ->where('gender', 1) + ->count(); + + $femaleFriendsCount = Db::table('tk_wechat_friend') + ->where('wechatAccountId', $targetWechatId) + ->where('isDeleted', 0) + ->where('gender', 2) + ->count(); + + $totalFriendsCount = $maleFriendsCount + $femaleFriendsCount; + + // 更新目标微信账号的好友数量 + WechatAccount::where('id', $targetWechatId) + ->update([ + 'totalFriend' => $totalFriendsCount, + 'maleFriend' => $maleFriendsCount, + 'femaleFriend' => $femaleFriendsCount, + 'updateTime' => date('Y-m-d H:i:s') + ]); + + // 提交事务 + Db::commit(); + + return json([ + 'code' => 200, + 'msg' => '好友转移成功', + 'data' => [ + 'total' => $totalFriends, + 'success' => $successCount, + 'fail' => $failCount, + 'duplicate' => $duplicateCount, + 'failList' => $failList + ] + ]); + } catch (\Exception $e) { + // 回滚事务 + Db::rollback(); + throw $e; + } + } catch (\Exception $e) { + return json([ + 'code' => 500, + 'msg' => '好友转移失败:' . $e->getMessage() + ]); + } + } +} \ No newline at end of file diff --git a/Server/application/devices/model/WechatAccount.php b/Server/application/devices/model/WechatAccount.php new file mode 100644 index 00000000..64fc8a64 --- /dev/null +++ b/Server/application/devices/model/WechatAccount.php @@ -0,0 +1,129 @@ + 'integer', + 'deviceAccountId' => 'integer', + 'keFuAlive' => 'integer', + 'deviceAlive' => 'integer', + 'wechatAlive' => 'integer', + 'yesterdayMsgCount' => 'integer', + 'sevenDayMsgCount' => 'integer', + 'thirtyDayMsgCount' => 'integer', + 'totalFriend' => 'integer', + 'maleFriend' => 'integer', + 'femaleFriend' => 'integer', + 'gender' => 'integer', + 'currentDeviceId' => 'integer', + 'isDeleted' => 'integer', + 'groupId' => 'integer' + ]; + + /** + * 获取在线微信账号数量 + * + * @param array $where 额外的查询条件 + * @return int 微信账号数量 + */ + public static function getOnlineWechatCount($where = []) + { + $condition = [ + 'deviceAlive' => 1, + 'wechatAlive' => 1, + 'isDeleted' => 0 + ]; + + // 合并额外条件 + if (!empty($where)) { + $condition = array_merge($condition, $where); + } + + return self::where($condition)->count(); + } + + /** + * 获取有登录微信的设备数量 + * + * @param array $where 额外的查询条件 + * @return int 设备数量 + */ + public static function getDeviceWithWechatCount($where = []) + { + $condition = [ + 'deviceAlive' => 1, + 'isDeleted' => 0 + ]; + + // 合并额外条件 + if (!empty($where)) { + $condition = array_merge($condition, $where); + } + + return self::where($condition)->count(); + } + + /** + * 获取在线微信账号列表 + * + * @param array $where 额外的查询条件 + * @param string $order 排序方式 + * @param int $page 页码 + * @param int $limit 每页数量 + * @return \think\Paginator 分页对象 + */ + public static function getOnlineWechatList($where = [], $order = 'id desc', $page = 1, $limit = 10) + { + $condition = [ + 'wechatAlive' => 1, + 'deviceAlive' => 1, + 'isDeleted' => 0 + ]; + + // 合并额外条件 + if (!empty($where)) { + $condition = array_merge($condition, $where); + } + + return self::where($condition) + ->field([ + 'id', + 'wechatId', + 'accountNickname', + 'nickname', + 'accountUserName', + 'avatar', + 'wechatAlive', + 'deviceAlive', + 'totalFriend', + 'maleFriend', + 'femaleFriend', + 'imei', + 'deviceMemo', + 'yesterdayMsgCount' + ]) + ->order($order) + ->paginate($limit, false, ['page' => $page]); + } +} \ No newline at end of file