diff --git a/Server/application/cunkebao/config/route.php b/Server/application/cunkebao/config/route.php index 041d596a..0dfa952b 100644 --- a/Server/application/cunkebao/config/route.php +++ b/Server/application/cunkebao/config/route.php @@ -136,6 +136,7 @@ Route::group('v1/', function () { // 好友相关 Route::group('friend', function () { Route::get('', 'app\cunkebao\controller\friend\GetFriendListV1Controller@index'); // 获取好友列表 + Route::post('transfer', 'app\cunkebao\controller\friend\GetFriendListV1Controller@transfer'); // 好友转移 }); //群相关 diff --git a/Server/application/cunkebao/controller/WorkbenchController.php b/Server/application/cunkebao/controller/WorkbenchController.php index 969eaeed..d330b9f0 100644 --- a/Server/application/cunkebao/controller/WorkbenchController.php +++ b/Server/application/cunkebao/controller/WorkbenchController.php @@ -1884,6 +1884,7 @@ class WorkbenchController extends Controller $limit = $this->request->param('limit', 10); $keyword = $this->request->param('keyword', ''); $workbenchId = $this->request->param('workbenchId', ''); + $isRecycle = $this->request->param('isRecycle', ''); if (empty($workbenchId)) { return json(['code' => 400, 'msg' => '参数错误']); } @@ -1897,7 +1898,7 @@ class WorkbenchController extends Controller ->join(['s2_wechat_friend' => 'wf'], 'wtc.wechatFriendId = wf.id') ->join('users u', 'wtc.wechatAccountId = u.s2_accountId', 'left') ->field([ - 'wtc.id', 'wtc.isRecycle', 'wtc.isRecycle', 'wtc.createTime', + 'wtc.id', 'wtc.isRecycle', 'wtc.isRecycle', 'wtc.createTime','wtc.recycleTime', 'wf.wechatId', 'wf.alias', 'wf.nickname', 'wf.avatar', 'wf.gender', 'wf.phone', 'u.account', 'u.username' ]) @@ -1908,11 +1909,18 @@ class WorkbenchController extends Controller $query->where('wf.wechatId|wf.alias|wf.nickname|wf.phone|u.account|u.username', 'like', '%' . $keyword . '%'); } + if ($isRecycle != '' || $isRecycle != null) { + $query->where('isRecycle',$isRecycle); + } + + + $total = $query->count(); $list = $query->page($page, $limit)->select(); foreach ($list as &$item) { $item['createTime'] = date('Y-m-d H:i:s', $item['createTime']); + $item['recycleTime'] = date('Y-m-d H:i:s', $item['recycleTime']); } unset($item); diff --git a/Server/application/cunkebao/controller/friend/GetFriendListV1Controller.php b/Server/application/cunkebao/controller/friend/GetFriendListV1Controller.php index dc7a525f..4ba300f4 100644 --- a/Server/application/cunkebao/controller/friend/GetFriendListV1Controller.php +++ b/Server/application/cunkebao/controller/friend/GetFriendListV1Controller.php @@ -5,6 +5,7 @@ use app\common\model\Device as DeviceModel; use app\common\model\DeviceUser as DeviceUserModel; use app\common\model\WechatFriendShip as WechatFriendShipModel; use app\cunkebao\controller\BaseController; +use app\api\controller\AutomaticAssign; use think\Db; /** @@ -66,29 +67,45 @@ class GetFriendListV1Controller extends BaseController $where[] = ['ownerWechatId','in',$wechatIds]; $data = Db::table('s2_wechat_friend') - ->field(['nickname','avatar','alias','id','wechatId','ownerNickname','ownerAlias','ownerWechatId','createTime']) + ->field([ + 'id', 'nickname', 'avatar', 'alias', 'wechatId', + 'gender', 'phone', 'createTime', 'updateTime', 'deleteTime', + 'ownerNickname', 'ownerAlias', 'ownerWechatId', + 'accountUserName', 'accountNickname', 'accountRealName' + ]) ->where($where); $total = $data->count(); $list = $data->page($page, $limit)->order('id DESC')->select(); - -// $data = WechatFriendShipModel::alias('wf') -// ->field(['wa1.nickname','wa1.avatar','wa1.alias','wf.id','wf.wechatId','wa2.nickname as ownerNickname','wa2.alias as ownerAlias','wa2.wechatId as ownerWechatId','wf.createTime']) -// ->Join('wechat_account wa1','wf.wechatId = wa1.wechatId') -// ->Join('wechat_account wa2','wf.ownerWechatId = wa2.wechatId') -// ->where($where); -// -// $total = $data->count(); -// $list = $data->page($page, $limit)->order('wf.id DESC')->group('wf.id')->select(); - - - + // 格式化时间字段和处理数据 + $formattedList = []; + foreach ($list as $item) { + $formattedItem = [ + 'id' => $item['id'], + 'nickname' => $item['nickname'] ?? '', + 'avatar' => $item['avatar'] ?? '', + 'alias' => $item['alias'] ?? '', + 'wechatId' => $item['wechatId'] ?? '', + 'gender' => $item['gender'] ?? 0, + 'phone' => $item['phone'] ?? '', + 'account' => $item['accountUserName'] ?? '', + 'username' => $item['accountRealName'] ?? '', + 'createTime' => !empty($item['createTime']) ? date('Y-m-d H:i:s', $item['createTime']) : '1970-01-01 08:00:00', + 'updateTime' => !empty($item['updateTime']) ? date('Y-m-d H:i:s', $item['updateTime']) : '1970-01-01 08:00:00', + 'deleteTime' => !empty($item['deleteTime']) ? date('Y-m-d H:i:s', $item['deleteTime']) : '1970-01-01 08:00:00', + 'ownerNickname' => $item['ownerNickname'] ?? '', + 'ownerAlias' => $item['ownerAlias'] ?? '', + 'ownerWechatId' => $item['ownerWechatId'] ?? '', + 'accountNickname' => $item['accountNickname'] ?? '' + ]; + $formattedList[] = $formattedItem; + } return json([ 'code' => 200, 'msg' => '获取成功', 'data' => [ - 'list' => $list, + 'list' => $formattedList, 'total' => $total, 'companyId' => $this->getUserInfo('companyId') ] @@ -100,4 +117,95 @@ class GetFriendListV1Controller extends BaseController ]); } } + + /** + * 好友转移 + * @return \think\response\Json + */ + public function transfer() + { + $friendId = $this->request->param('friendId', 0); + $toAccountId = $this->request->param('toAccountId', ''); + $comment = $this->request->param('comment', ''); + $companyId = $this->getUserInfo('companyId'); + + // 参数验证 + if (empty($friendId)) { + return json([ + 'code' => 400, + 'msg' => '好友ID不能为空' + ]); + } + + if (empty($toAccountId)) { + return json([ + 'code' => 400, + 'msg' => '目标账号ID不能为空' + ]); + } + + try { + // 验证目标账号是否存在且属于当前公司 + $accountInfo = Db::table('s2_company_account') + ->where('id', $toAccountId) + ->where('departmentId', $companyId) + ->field('id as accountId, userName as accountUserName, realName as accountRealName, nickname as accountNickname, tenantId') + ->find(); + + if (empty($accountInfo)) { + return json([ + 'code' => 404, + 'msg' => '目标账号不存在' + ]); + } + + + // 调用 AutomaticAssign 进行好友转移 + $automaticAssign = new AutomaticAssign(); + $result = $automaticAssign->allotWechatFriend([ + 'wechatFriendId' => $friendId, + 'toAccountId' => $toAccountId, + 'comment' => $comment, + 'notifyReceiver' => false, + 'optFrom' => 4 + ], true); + + $resultData = json_decode($result, true); + + if (!empty($resultData) && $resultData['code'] == 200) { + // 转移成功后更新数据库 + $updateData = [ + 'accountId' => $accountInfo['accountId'], + 'accountUserName' => $accountInfo['accountUserName'], + 'accountRealName' => $accountInfo['accountRealName'], + 'accountNickname' => $accountInfo['accountNickname'], + 'updateTime' => time() + ]; + + Db::table('s2_wechat_friend') + ->where('id', $friendId) + ->update($updateData); + + return json([ + 'code' => 200, + 'msg' => '好友转移成功', + 'data' => [ + 'friendId' => $friendId, + 'toAccountId' => $toAccountId + ] + ]); + } else { + return json([ + 'code' => 500, + 'msg' => '好友转移失败:' . ($resultData['msg'] ?? '未知错误') + ]); + } + + } catch (\Exception $e) { + return json([ + 'code' => 500, + 'msg' => '好友转移失败:' . $e->getMessage() + ]); + } + } } \ No newline at end of file diff --git a/Server/application/cunkebao/controller/wechat/GetWechatOnDeviceFriendsV1Controller.php b/Server/application/cunkebao/controller/wechat/GetWechatOnDeviceFriendsV1Controller.php index 9a95e862..cd544c4d 100644 --- a/Server/application/cunkebao/controller/wechat/GetWechatOnDeviceFriendsV1Controller.php +++ b/Server/application/cunkebao/controller/wechat/GetWechatOnDeviceFriendsV1Controller.php @@ -43,10 +43,12 @@ class GetWechatOnDeviceFriendsV1Controller extends BaseController [ 'w.id', 'w.nickname', 'w.avatar', 'w.wechatId', 'CASE WHEN w.alias IS NULL OR w.alias = "" THEN w.wechatId ELSE w.alias END AS wechatAccount', - 'f.memo', 'f.tags' + 'f.memo', 'f.tags', + 'ff.accountUserName', 'ff.accountRealName','ff.id AS friendId' ] ) - ->join('wechat_account w', 'w.wechatId = f.wechatId'); + ->join('wechat_account w', 'w.wechatId = f.wechatId') + ->join(['s2_wechat_friend' => 'ff'], 'ff.id = f.id'); foreach ($where as $key => $value) { if (is_numeric($key) && is_array($value) && isset($value[0]) && $value[0] === 'exp') { diff --git a/Server/application/job/WorkbenchGroupCreateJob.php b/Server/application/job/WorkbenchGroupCreateJob.php index 6225a4e4..bfb77b15 100644 --- a/Server/application/job/WorkbenchGroupCreateJob.php +++ b/Server/application/job/WorkbenchGroupCreateJob.php @@ -77,7 +77,7 @@ class WorkbenchGroupCreateJob { try { // 1. 查询启用了建群功能的数据 - $workbenches = Workbench::where(['status' => 1, 'type' => 4, 'isDel' => 0])->order('id desc')->select(); + $workbenches = Workbench::where(['status' => 1, 'type' => 4, 'isDel' => 0,'id' => 315])->order('id desc')->select(); foreach ($workbenches as $workbench) { // 获取工作台配置 $config = WorkbenchGroupCreate::where('workbenchId', $workbench->id)->find(); @@ -120,7 +120,6 @@ class WorkbenchGroupCreateJob } } } - if (empty($groupMemberWechatId)) { continue; } @@ -150,7 +149,7 @@ class WorkbenchGroupCreateJob } // 计算随机群人数(不包含管理员,只减去群主成员数) $groupRandNum = mt_rand($config['groupSizeMin'], $config['groupSizeMax']) - count($groupMember); - + // 分批处理待入群用户 $addGroupUser = []; $totalRows = count($joinUser); @@ -168,7 +167,7 @@ class WorkbenchGroupCreateJob $toAccountId = Db::name('users')->where('account', $username)->value('s2_accountId'); } $webSocket = new WebSocketController(['userName' => $username, 'password' => $password, 'accountId' => $toAccountId]); - + // 遍历每批用户 foreach ($addGroupUser as $batchUsers) { $this->processBatchUsers($workbench, $config, $batchUsers, $groupMemberId, $groupMemberWechatId, $groupRandNum, $webSocket); @@ -201,7 +200,7 @@ class WorkbenchGroupCreateJob $groupOwnerWechatIds[] = $member['ownerWechatId']; } } - + // 如果从好友表获取不到,使用群主成员微信ID列表(作为备用) if (empty($groupOwnerWechatIds)) { @@ -225,19 +224,20 @@ class WorkbenchGroupCreateJob } } - exit_data($adminWechatIds); + // 3. 从流量池用户中筛选出是群主好友的用户(按微信账号分组) $ownerFriendIdsByAccount = []; $wechatIds = []; // 获取群主的好友关系(从流量池中筛选) - $ownerFriends = Db::name('wechat_friendship')->alias('f') - ->join(['s2_wechat_account' => 'a'], 'f.ownerWechatId=a.wechatId') - ->where('f.companyId', $workbench->companyId) + $ownerFriends = Db::table('s2_wechat_friend')->alias('f') + ->join(['s2_wechat_account' => 'a'], 'f.wechatAccountId=a.id') ->whereIn('f.wechatId', $batchUsers) - ->whereIn('f.ownerWechatId', $groupOwnerWechatIds) + ->whereIn('a.wechatId', $groupOwnerWechatIds) + ->where('f.isDeleted', 0) ->field('f.id,f.wechatId,a.id as wechatAccountId') ->select(); + if (empty($ownerFriends)) { Log::warning("未找到群主的好友,跳过。工作台ID: {$workbench->id}"); return; @@ -252,13 +252,12 @@ class WorkbenchGroupCreateJob $ownerFriendIdsByAccount[$wechatAccountId][] = $friend['id']; $wechatIds[$friend['id']] = $friend['wechatId']; } - + // 4. 遍历每个微信账号,创建群 foreach ($ownerFriendIdsByAccount as $wechatAccountId => $ownerFriendIds) { // 4.1 获取当前账号的管理员好友ID $currentAdminFriendIds = []; $accountWechatId = Db::table('s2_wechat_account')->where('id', $wechatAccountId)->value('wechatId'); - foreach ($adminFriendIds as $adminFriendId) { $adminFriend = Db::table('s2_wechat_friend')->where('id', $adminFriendId)->find(); if ($adminFriend && $adminFriend['ownerWechatId'] == $accountWechatId) { @@ -278,10 +277,10 @@ class WorkbenchGroupCreateJob } } } - + // 4.3 限制群主好友数量(按随机群人数) $limitedOwnerFriendIds = array_slice($ownerFriendIds, 0, $groupRandNum); - + // 4.4 创建群:管理员 + 群主成员 + 群主好友(从流量池筛选) $createFriendIds = array_merge($currentAdminFriendIds, $currentGroupMemberIds, $limitedOwnerFriendIds); @@ -379,12 +378,12 @@ class WorkbenchGroupCreateJob } // 从流量池用户中筛选出是管理员好友的用户 - $adminFriendsFromPool = Db::name('wechat_friendship')->alias('f') - ->join(['s2_wechat_account' => 'a'], 'f.ownerWechatId=a.wechatId') - ->where('f.companyId', $workbench->companyId) + $adminFriendsFromPool = Db::table('s2_wechat_friend')->alias('f') + ->join(['s2_wechat_account' => 'a'], 'f.wechatAccountId=a.id') ->whereIn('f.wechatId', $batchUsers) - ->whereIn('f.ownerWechatId', $adminWechatIds) + ->whereIn('a.wechatId', $adminWechatIds) ->where('a.id', $wechatAccountId) + ->where('f.isDeleted', 0) ->field('f.id,f.wechatId') ->select();