更新
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\lists\qywx;
|
||||
|
||||
use app\adminapi\lists\BaseAdminDataLists;
|
||||
use app\common\lists\ListsSearchInterface;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\model\QywxExternalContact;
|
||||
use app\common\model\QywxMsgArchive;
|
||||
use app\common\model\QywxMsgArchiveMedia;
|
||||
|
||||
/**
|
||||
* 单会话消息历史
|
||||
*
|
||||
* 两种查询模式,二选一:
|
||||
* 1) session_id 传 QywxMsgSession.id(推荐)
|
||||
* 2) staff_userid + external_userid(单聊)/ roomid(群聊)
|
||||
*
|
||||
* 消息默认按 send_time 升序,便于前端从下往上追加。
|
||||
* 支持 before_time / after_time 游标翻页。
|
||||
*/
|
||||
class MsgArchiveLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
{
|
||||
public function setSearch(): array
|
||||
{
|
||||
return [
|
||||
'=' => ['roomid', 'msgtype'],
|
||||
];
|
||||
}
|
||||
|
||||
private function resolveScope(): array
|
||||
{
|
||||
$sessionId = (int) ($this->params['session_id'] ?? 0);
|
||||
if ($sessionId > 0) {
|
||||
$session = \app\common\model\QywxMsgSession::find($sessionId);
|
||||
if ($session) {
|
||||
return [
|
||||
'staff_userid' => (string) $session['staff_userid'],
|
||||
'external_userid' => (string) $session['external_userid'],
|
||||
'roomid' => (string) $session['roomid'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'staff_userid' => trim((string) ($this->params['staff_userid'] ?? '')),
|
||||
'external_userid' => trim((string) ($this->params['external_userid'] ?? '')),
|
||||
'roomid' => trim((string) ($this->params['roomid'] ?? '')),
|
||||
];
|
||||
}
|
||||
|
||||
private function baseQuery()
|
||||
{
|
||||
$scope = $this->resolveScope();
|
||||
$query = QywxMsgArchive::where($this->searchWhere);
|
||||
|
||||
if ($scope['roomid'] !== '') {
|
||||
$query->where('roomid', $scope['roomid']);
|
||||
} else {
|
||||
// 单聊:两端顺序不定,from_user/tolist 都可能为员工或客户
|
||||
$staff = $scope['staff_userid'];
|
||||
$external = $scope['external_userid'];
|
||||
if ($staff === '' && $external === '') {
|
||||
$query->where('id', 0);
|
||||
} else {
|
||||
$query->where('roomid', '');
|
||||
if ($staff !== '' && $external !== '') {
|
||||
$query->where(function ($q) use ($staff, $external) {
|
||||
$q->where(function ($sub) use ($staff, $external) {
|
||||
$sub->where('from_user', $staff)->whereLike('to_list', '%"' . $external . '"%');
|
||||
})->whereOr(function ($sub) use ($staff, $external) {
|
||||
$sub->where('from_user', $external)->whereLike('to_list', '%"' . $staff . '"%');
|
||||
});
|
||||
});
|
||||
} elseif ($staff !== '') {
|
||||
$query->where(function ($q) use ($staff) {
|
||||
$q->where('from_user', $staff)->whereOr('to_list', 'like', '%"' . $staff . '"%');
|
||||
});
|
||||
} else {
|
||||
$query->where(function ($q) use ($external) {
|
||||
$q->where('from_user', $external)->whereOr('to_list', 'like', '%"' . $external . '"%');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->params['before_time'])) {
|
||||
$query->where('send_time', '<', (int) $this->params['before_time']);
|
||||
}
|
||||
if (!empty($this->params['after_time'])) {
|
||||
$query->where('send_time', '>', (int) $this->params['after_time']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function lists(): array
|
||||
{
|
||||
$rows = $this->baseQuery()
|
||||
->order('send_time', 'desc')
|
||||
->order('id', 'desc')
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
if (empty($rows)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = array_reverse($rows); // 前端按时间升序渲染
|
||||
|
||||
$users = [];
|
||||
foreach ($rows as $r) {
|
||||
$users[$r['from_user']] = true;
|
||||
$toList = $r['to_list'];
|
||||
if (is_array($toList)) {
|
||||
foreach ($toList as $to) {
|
||||
$users[$to] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$users = array_keys(array_filter($users, fn ($_, $k) => $k !== '', ARRAY_FILTER_USE_BOTH));
|
||||
|
||||
$adminMap = [];
|
||||
$extMap = [];
|
||||
if ($users) {
|
||||
$adminMap = Admin::whereIn('work_wechat_userid', $users)
|
||||
->column('id,name,avatar,work_wechat_userid', 'work_wechat_userid');
|
||||
$extMap = QywxExternalContact::whereIn('external_userid', $users)
|
||||
->column('external_userid,name,avatar,type,unionid', 'external_userid');
|
||||
}
|
||||
|
||||
$msgIds = array_column($rows, 'msgid');
|
||||
$mediaMap = [];
|
||||
if ($msgIds) {
|
||||
$mediaList = QywxMsgArchiveMedia::whereIn('msgid', $msgIds)->select()->toArray();
|
||||
foreach ($mediaList as $m) {
|
||||
$mediaMap[$m['msgid']][] = $m;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($rows as &$r) {
|
||||
$fromId = (string) $r['from_user'];
|
||||
$r['from_is_staff'] = isset($adminMap[$fromId]);
|
||||
$r['from_profile'] = $adminMap[$fromId] ?? ($extMap[$fromId] ?? null);
|
||||
$r['media'] = $mediaMap[$r['msgid']] ?? [];
|
||||
}
|
||||
unset($r);
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return $this->baseQuery()->count();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\lists\qywx;
|
||||
|
||||
use app\adminapi\lists\BaseAdminDataLists;
|
||||
use app\common\lists\ListsSearchInterface;
|
||||
use app\common\model\QywxMsgSendTask;
|
||||
|
||||
class MsgSendTaskLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
{
|
||||
public function setSearch(): array
|
||||
{
|
||||
return [
|
||||
'=' => ['sender_userid', 'status', 'admin_id'],
|
||||
];
|
||||
}
|
||||
|
||||
public function lists(): array
|
||||
{
|
||||
return QywxMsgSendTask::where($this->searchWhere)
|
||||
->order('id', 'desc')
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return QywxMsgSendTask::where($this->searchWhere)->count();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\lists\qywx;
|
||||
|
||||
use app\adminapi\lists\BaseAdminDataLists;
|
||||
use app\common\lists\ListsSearchInterface;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\model\QywxExternalContact;
|
||||
use app\common\model\QywxMsgSession;
|
||||
|
||||
/**
|
||||
* 企微消息会话列表
|
||||
*
|
||||
* 查询参数:
|
||||
* staff_userid - 过滤某员工的会话(支持传 admin_id 反查)
|
||||
* external_userid- 过滤某客户
|
||||
* keyword - 按客户名 / 摘要 模糊搜索
|
||||
* only_unread - 仅未读
|
||||
*/
|
||||
class MsgSessionLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
{
|
||||
public function setSearch(): array
|
||||
{
|
||||
return [
|
||||
'=' => ['staff_userid', 'external_userid', 'roomid', 'session_type'],
|
||||
];
|
||||
}
|
||||
|
||||
private function baseQuery()
|
||||
{
|
||||
$query = QywxMsgSession::where($this->searchWhere);
|
||||
|
||||
$adminId = (int) ($this->params['admin_id'] ?? 0);
|
||||
if ($adminId > 0) {
|
||||
$wxId = Admin::where('id', $adminId)->value('work_wechat_userid');
|
||||
if ($wxId) {
|
||||
$query->where('staff_userid', $wxId);
|
||||
} else {
|
||||
// 找不到对应企微 userid 时不返回任何会话
|
||||
$query->where('id', 0);
|
||||
}
|
||||
}
|
||||
|
||||
$keyword = trim((string) ($this->params['keyword'] ?? ''));
|
||||
if ($keyword !== '') {
|
||||
$kw = addcslashes($keyword, '%_\\');
|
||||
$extIds = QywxExternalContact::whereLike('name', '%' . $kw . '%')->column('external_userid');
|
||||
$query->where(function ($q) use ($kw, $extIds) {
|
||||
$q->whereLike('last_msg_summary', '%' . $kw . '%');
|
||||
if ($extIds) {
|
||||
$q->whereOr('external_userid', 'in', $extIds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!empty($this->params['only_unread'])) {
|
||||
$query->where('unread_staff', '>', 0);
|
||||
}
|
||||
|
||||
return $query->order('last_msg_time', 'desc');
|
||||
}
|
||||
|
||||
public function lists(): array
|
||||
{
|
||||
$rows = $this->baseQuery()
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
if (empty($rows)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$extIds = array_values(array_unique(array_filter(array_map(
|
||||
fn ($r) => (string) ($r['external_userid'] ?? ''),
|
||||
$rows
|
||||
))));
|
||||
$extMap = [];
|
||||
if ($extIds) {
|
||||
$extMap = QywxExternalContact::whereIn('external_userid', $extIds)
|
||||
->column('name,avatar,type,gender,corp_name,unionid', 'external_userid');
|
||||
}
|
||||
|
||||
$staffIds = array_values(array_unique(array_filter(array_map(
|
||||
fn ($r) => (string) ($r['staff_userid'] ?? ''),
|
||||
$rows
|
||||
))));
|
||||
$staffMap = [];
|
||||
if ($staffIds) {
|
||||
$staffMap = Admin::whereIn('work_wechat_userid', $staffIds)
|
||||
->column('id,name,avatar', 'work_wechat_userid');
|
||||
}
|
||||
|
||||
foreach ($rows as &$r) {
|
||||
$r['customer'] = $extMap[$r['external_userid']] ?? null;
|
||||
$r['staff'] = $staffMap[$r['staff_userid']] ?? null;
|
||||
}
|
||||
unset($r);
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return $this->baseQuery()->count();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user