Files
cunkebao_v3/Server/application/cunkebao/controller/wechat/GetWechatsOnDevicesV1Controller.php
2025-11-14 18:19:08 +08:00

310 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\cunkebao\controller\wechat;
use app\common\model\Device as DeviceModel;
use app\common\model\Device as DevicesModel;
use app\common\model\DeviceUser as DeviceUserModel;
use app\common\model\DeviceWechatLogin as DeviceWechatLoginModel;
use app\common\model\User as UserModel;
use app\common\model\WechatAccount as WechatAccountModel;
use app\common\model\WechatCustomer as WechatCustomerModel;
use app\common\model\WechatFriendShip as WechatFriendShipModel;
use app\cunkebao\controller\BaseController;
use library\ResponseHelper;
use think\Db;
/**
* 微信控制器
*/
class GetWechatsOnDevicesV1Controller extends BaseController
{
/**
* 主操盘手获取项目下所有设备的id
*
* @return array
* @throws \Exception
*/
protected function getCompanyDevicesId(): array
{
return DevicesModel::where(
[
'companyId' => $this->getUserInfo('companyId')
]
)
->column('id');
}
/**
* 非主操盘手获取分配的设备
*
* @return array
*/
protected function getUserDevicesId(): array
{
return DeviceUserModel::where(
[
'userId' => $this->getUserInfo('id'),
'companyId' => $this->getUserInfo('companyId')
]
)
->column('deviceId');
}
/**
* 根据不同角色,显示的设备数量不同
*
* @return array
* @throws \Exception
*/
protected function getDevicesId(): array
{
return ($this->getUserInfo('isAdmin') == UserModel::ADMIN_STP)
? $this->getCompanyDevicesId() // 主操盘手获取所有的设备
: $this->getUserDevicesId(); // 非主操盘手获取分配的设备
}
/**
* 获取有登录设备的微信id
*
* @return array
*/
protected function getWechatIdsOnDevices(): array
{
// 关联设备id查询过滤掉已删除的设备
if (empty($deviceIds = $this->getDevicesId())) {
throw new \Exception('暂无设备数据', 200);
}
return DeviceWechatLoginModel::where(
[
'companyId' => $this->getUserInfo('companyId'),
// 'alive' => DeviceWechatLoginModel::ALIVE_WECHAT_ACTIVE,
]
)
->where('deviceId', 'in', $deviceIds)
->column('wechatId');
}
/**
* 构建查询条件
*
* @param array $params
* @return array
*/
protected function makeWhere(array $params = []): array
{
if (empty($wechatIds = $this->getWechatIdsOnDevices())) {
throw new \Exception('设备尚未有登录微信', 200);
}
// 关键词搜索(同时搜索微信号和昵称)
if (!empty($keyword = $this->request->param('keyword'))) {
$where[] = ["w.wechatId|w.alias|w.nickname", 'LIKE', '%' . $keyword . '%'];
}
$where['w.wechatId'] = array('in', implode(',', $wechatIds));
return array_merge($where, $params);
}
/**
* 获取在线微信账号列表
*
* @param array $where
* @return \think\Paginator 分页对象
*/
protected function getOnlineWechatList(array $where): \think\Paginator
{
$query = WechatAccountModel::alias('w')
->field(
[
'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',
'l.deviceId','l.alive'
]
)
->join('device_wechat_login l', 'w.wechatId = l.wechatId AND l.companyId = '. $this->getUserInfo('companyId'))
->order('w.id desc')
->group('w.wechatId');
foreach ($where as $key => $value) {
if (is_numeric($key) && is_array($value) && isset($value[0]) && $value[0] === 'exp') {
$query->whereExp('', $value[1]);
continue;
}
if (is_array($value)) {
$query->where($key, ...$value);
continue;
}
$query->where($key, $value);
}
return $query->paginate($this->request->param('limit/d', 10), false, ['page' => $this->request->param('page/d', 1)]);
}
/**
* 构建返回数据
*
* @param \think\Paginator $result
* @return array
*/
protected function makeResultedSet(\think\Paginator $result): array
{
$resultSets = [];
$items = $result->items();
if (empty($items)) {
return $resultSets;
}
$wechatIds = array_values(array_unique(array_map(function ($item) {
return $item->wechatId ?? ($item['wechatId'] ?? '');
}, $items)));
$metrics = $this->collectWechatMetrics($wechatIds);
foreach ($items as $item) {
$sections = $item->toArray() + [
'times' => $metrics['addLimit'][$item->wechatId] ?? 0,
'addedCount' => $metrics['todayAdded'][$item->wechatId] ?? 0,
'wechatStatus' => $metrics['wechatStatus'][$item->wechatId] ?? 0,
'totalFriend' => $metrics['totalFriend'][$item->wechatId] ?? 0,
'deviceMemo' => $metrics['deviceMemo'][$item->wechatId] ?? '',
'activeTime' => $metrics['activeTime'][$item->wechatId] ?? '-',
];
array_push($resultSets, $sections);
}
return $resultSets;
}
/**
* 批量收集微信账号的统计信息
* @param array $wechatIds
* @return array
*/
protected function collectWechatMetrics(array $wechatIds): array
{
$metrics = [
'addLimit' => [],
'todayAdded' => [],
'totalFriend' => [],
'wechatStatus' => [],
'deviceMemo' => [],
'activeTime' => [],
];
if (empty($wechatIds)) {
return $metrics;
}
$companyId = $this->getUserInfo('companyId');
// 可添加好友额度
$weightRows = WechatCustomerModel::where('companyId', $companyId)
->whereIn('wechatId', $wechatIds)
->column('weight', 'wechatId');
foreach ($weightRows as $wechatId => $weight) {
$decoded = json_decode($weight, true);
$metrics['addLimit'][$wechatId] = $decoded['addLimit'] ?? 0;
}
// 今日新增好友
$start = strtotime(date('Y-m-d 00:00:00'));
$end = strtotime(date('Y-m-d 23:59:59'));
$todayRows = WechatFriendShipModel::whereIn('ownerWechatId', $wechatIds)
->whereBetween('createTime', [$start, $end])
->field('ownerWechatId, COUNT(*) as total')
->group('ownerWechatId')
->select();
foreach ($todayRows as $row) {
$wechatId = is_array($row) ? ($row['ownerWechatId'] ?? '') : ($row->ownerWechatId ?? '');
if ($wechatId) {
$metrics['todayAdded'][$wechatId] = (int)(is_array($row) ? ($row['total'] ?? 0) : ($row->total ?? 0));
}
}
// 总好友
$friendRows = WechatFriendShipModel::whereIn('ownerWechatId', $wechatIds)
->field('ownerWechatId, COUNT(*) as total')
->group('ownerWechatId')
->select();
foreach ($friendRows as $row) {
$wechatId = is_array($row) ? ($row['ownerWechatId'] ?? '') : ($row->ownerWechatId ?? '');
if ($wechatId) {
$metrics['totalFriend'][$wechatId] = (int)(is_array($row) ? ($row['total'] ?? 0) : ($row->total ?? 0));
}
}
// 设备状态与备注
$loginRows = Db::name('device_wechat_login')
->alias('l')
->leftJoin('device d', 'd.id = l.deviceId')
->field('l.wechatId,l.alive,d.memo')
->where('l.companyId', $companyId)
->whereIn('l.wechatId', $wechatIds)
->order('l.id', 'desc')
->select();
foreach ($loginRows as $row) {
$wechatId = is_array($row) ? ($row['wechatId'] ?? '') : ($row->wechatId ?? '');
if (empty($wechatId) || isset($metrics['wechatStatus'][$wechatId])) {
continue;
}
$metrics['wechatStatus'][$wechatId] = (int)(is_array($row) ? ($row['alive'] ?? 0) : ($row->alive ?? 0));
$metrics['deviceMemo'][$wechatId] = is_array($row) ? ($row['memo'] ?? '') : ($row->memo ?? '');
}
// 活跃时间
$accountMap = Db::table('s2_wechat_account')
->whereIn('wechatId', $wechatIds)
->column('id', 'wechatId');
if (!empty($accountMap)) {
$accountRows = Db::table('s2_wechat_message')
->whereIn('wechatAccountId', array_values($accountMap))
->field('wechatAccountId, MAX(wechatTime) as lastTime')
->group('wechatAccountId')
->select();
$accountLastTime = [];
foreach ($accountRows as $row) {
$accountId = is_array($row) ? ($row['wechatAccountId'] ?? 0) : ($row->wechatAccountId ?? 0);
if ($accountId) {
$accountLastTime[$accountId] = (int)(is_array($row) ? ($row['lastTime'] ?? 0) : ($row->lastTime ?? 0));
}
}
foreach ($accountMap as $wechatId => $accountId) {
if (isset($accountLastTime[$accountId]) && $accountLastTime[$accountId] > 0) {
$metrics['activeTime'][$wechatId] = date('Y-m-d H:i:s', $accountLastTime[$accountId]);
}
}
}
return $metrics;
}
/**
* 获取在线微信账号列表
*
* @return \think\response\Json
*/
public function index()
{
try {
$result = $this->getOnlineWechatList(
$this->makeWhere()
);
return ResponseHelper::success(
[
'list' => $this->makeResultedSet($result),
'total' => $result->total(),
]
);
} catch (\Exception $e) {
return ResponseHelper::error($e->getMessage(), $e->getCode());
}
}
}