更新
This commit is contained in:
@@ -1445,6 +1445,203 @@ class YejiStatsLogic
|
||||
return $byAdmin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 进线事件查询公共条件(与 countLeads / countLeadsByAdmin 一致)。
|
||||
*
|
||||
* @param \think\db\BaseQuery $query
|
||||
*/
|
||||
private static function applyLeadEventBaseFilter($query, int $startTs, int $endTs, string $tagFilterId): void
|
||||
{
|
||||
$query->where('e.change_type', 'add_external_contact')
|
||||
->where('e.event_time', 'between', [$startTs, $endTs])
|
||||
->where('e.user_id', '<>', '');
|
||||
if ($tagFilterId !== '') {
|
||||
$tagTable = self::tableWithPrefix('qywx_external_contact_tag');
|
||||
$query->whereRaw(
|
||||
"EXISTS (SELECT 1 FROM {$tagTable} t WHERE t.external_userid = e.external_userid AND t.tag_id = ?)",
|
||||
[$tagFilterId]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 归属到指定展示「中心」行部门的接待成员企微 userid 列表。
|
||||
*
|
||||
* @param array<int, int> $adminToPrimary
|
||||
*
|
||||
* @return list<string>
|
||||
*/
|
||||
private static function collectWorkWxUserIdsForYejiDeptRow(int $deptRowId, array $adminToPrimary): array
|
||||
{
|
||||
$adminIds = [];
|
||||
foreach ($adminToPrimary as $aid => $pid) {
|
||||
if ((int) $pid === $deptRowId) {
|
||||
$adminIds[] = (int) $aid;
|
||||
}
|
||||
}
|
||||
if ($adminIds === []) {
|
||||
return [];
|
||||
}
|
||||
$wids = Db::name('admin')
|
||||
->whereIn('id', $adminIds)
|
||||
->whereNull('delete_time')
|
||||
->column('work_wechat_userid');
|
||||
$out = [];
|
||||
foreach ($wids as $w) {
|
||||
$w = trim((string) $w);
|
||||
if ($w !== '') {
|
||||
$out[] = $w;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values(array_unique($out));
|
||||
}
|
||||
|
||||
/**
|
||||
* 进线明细:与看板「进线数据」同口径的 add_external_contact 逐条列表。
|
||||
*
|
||||
* @param array{
|
||||
* start_date?: string,
|
||||
* end_date?: string,
|
||||
* dept_ids?: int[]|string,
|
||||
* channel_code?: string,
|
||||
* tag_id?: string,
|
||||
* dept_id?: int|string,
|
||||
* page?: int|string,
|
||||
* page_size?: int|string
|
||||
* } $params
|
||||
*
|
||||
* @return array{
|
||||
* start_date: string,
|
||||
* end_date: string,
|
||||
* dept_id: int,
|
||||
* dept_name: string,
|
||||
* channel_code: string,
|
||||
* count: int,
|
||||
* lists: list<array<string, mixed>>,
|
||||
* note: string
|
||||
* }
|
||||
*/
|
||||
public static function leadLineList(array $params, int $viewerAdminId = 0, array $viewerAdminInfo = []): array
|
||||
{
|
||||
$c = self::resolveYejiContext($params);
|
||||
if ($viewerAdminId > 0) {
|
||||
self::applyYejiDataScope($c, $viewerAdminId, $viewerAdminInfo);
|
||||
}
|
||||
|
||||
$deptId = (int) ($params['dept_id'] ?? 0);
|
||||
$empty = static function (array $c, int $deptId, string $deptName, string $note) {
|
||||
return [
|
||||
'start_date' => (string) $c['startDate'],
|
||||
'end_date' => (string) $c['endDate'],
|
||||
'dept_id' => $deptId,
|
||||
'dept_name' => $deptName,
|
||||
'channel_code' => (string) $c['channelCode'],
|
||||
'count' => 0,
|
||||
'lists' => [],
|
||||
'note' => $note,
|
||||
];
|
||||
};
|
||||
|
||||
if ($deptId <= 0) {
|
||||
return $empty($c, 0, '', '未归属中心无进线明细(看板该行进线为 0)。');
|
||||
}
|
||||
|
||||
if (!in_array($deptId, $c['tableRowDeptIds'], true)) {
|
||||
return $empty(
|
||||
$c,
|
||||
$deptId,
|
||||
self::formatYejiDeptRowDisplayName($deptId, $c['deptById']),
|
||||
'该部门不在当前展示部门筛选或数据权限范围内。'
|
||||
);
|
||||
}
|
||||
|
||||
$deptNameMap = $c['deptNameMap'];
|
||||
$channelCode = (string) $c['channelCode'];
|
||||
if ($channelCode !== '' && self::isErCenterDisplayPrimaryName((string) ($deptNameMap[$deptId] ?? ''))) {
|
||||
return $empty(
|
||||
$c,
|
||||
$deptId,
|
||||
self::formatYejiDeptRowDisplayName($deptId, $c['deptById']),
|
||||
'与看板一致:名称含「二中心」的展示部门在选定渠道下进线计 0,无明细。'
|
||||
);
|
||||
}
|
||||
|
||||
$startTs = (int) $c['startTs'];
|
||||
$endTs = (int) $c['endTs'];
|
||||
$tagFilterId = (string) $c['tagFilterId'];
|
||||
$page = max(1, (int) ($params['page'] ?? 1));
|
||||
$limit = min(100, max(1, (int) ($params['page_size'] ?? 20)));
|
||||
$offset = ($page - 1) * $limit;
|
||||
|
||||
$wxUserIds = self::collectWorkWxUserIdsForYejiDeptRow($deptId, $c['adminToPrimary']);
|
||||
$deptName = self::formatYejiDeptRowDisplayName($deptId, $c['deptById']);
|
||||
$ecTable = self::tableWithPrefix('qywx_external_contact');
|
||||
|
||||
if ($wxUserIds === []) {
|
||||
return [
|
||||
'start_date' => (string) $c['startDate'],
|
||||
'end_date' => (string) $c['endDate'],
|
||||
'dept_id' => $deptId,
|
||||
'dept_name' => $deptName,
|
||||
'channel_code' => $channelCode,
|
||||
'count' => 0,
|
||||
'lists' => [],
|
||||
'note' => '当前部门下没有可映射到接待企微成员的管理员,无进线流水。',
|
||||
];
|
||||
}
|
||||
|
||||
$countQuery = Db::name('qywx_external_contact_event')->alias('e');
|
||||
self::applyLeadEventBaseFilter($countQuery, $startTs, $endTs, $tagFilterId);
|
||||
$countQuery->whereIn('e.user_id', $wxUserIds);
|
||||
$count = (int) $countQuery->count();
|
||||
|
||||
$listQuery = Db::name('qywx_external_contact_event')->alias('e')
|
||||
->leftJoin('admin a', 'a.work_wechat_userid = e.user_id AND a.delete_time IS NULL')
|
||||
->leftJoin("{$ecTable} ec", 'ec.external_userid = e.external_userid AND ec.delete_time IS NULL');
|
||||
self::applyLeadEventBaseFilter($listQuery, $startTs, $endTs, $tagFilterId);
|
||||
$listQuery->whereIn('e.user_id', $wxUserIds);
|
||||
$rawList = $listQuery
|
||||
->field(
|
||||
'e.id,e.event_time,e.external_userid,e.user_id,e.state,'
|
||||
. 'a.name AS reception_admin_name,ec.name AS external_contact_name'
|
||||
)
|
||||
->order('e.event_time', 'desc')
|
||||
->order('e.id', 'desc')
|
||||
->limit($offset, $limit)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$lists = [];
|
||||
foreach ($rawList as $rw) {
|
||||
$ts = (int) ($rw['event_time'] ?? 0);
|
||||
$lists[] = [
|
||||
'id' => (int) ($rw['id'] ?? 0),
|
||||
'event_time' => $ts,
|
||||
'event_time_text' => $ts > 0 ? date('Y-m-d H:i:s', $ts) : '',
|
||||
'external_userid' => (string) ($rw['external_userid'] ?? ''),
|
||||
'user_id' => (string) ($rw['user_id'] ?? ''),
|
||||
'state' => (string) ($rw['state'] ?? ''),
|
||||
'reception_admin_name' => (string) ($rw['reception_admin_name'] ?? ''),
|
||||
'external_contact_name' => (string) ($rw['external_contact_name'] ?? ''),
|
||||
];
|
||||
}
|
||||
|
||||
$note = '与看板「进线数据」同口径:企微 change_type=add_external_contact,按接待成员归属当前部门行;'
|
||||
. ($tagFilterId !== '' ? '已按所选渠道标签过滤客户。' : '未选渠道时不限制客户标签。');
|
||||
|
||||
return [
|
||||
'start_date' => (string) $c['startDate'],
|
||||
'end_date' => (string) $c['endDate'],
|
||||
'dept_id' => $deptId,
|
||||
'dept_name' => $deptName,
|
||||
'channel_code' => $channelCode,
|
||||
'count' => $count,
|
||||
'lists' => $lists,
|
||||
'note' => $note,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 与 sumPerformance 对应,按 admin 维度返回全量/渠道业绩金额(不按部门折叠)。
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user