This commit is contained in:
Your Name
2026-08-28 18:24:37 +08:00
parent 43ad07208f
commit ed48f8be31
383 changed files with 8673 additions and 2222 deletions
@@ -20,7 +20,12 @@ class WecomAcquisitionCustomerLogic
->whereNull('l.delete_time')
->where('l.remote_link_id', '<>', '')
->where('l.remote_status', 1);
self::applyScope($query, 'l', DataScopeService::getVisibleAdminIds($adminId, $adminInfo));
self::applyScope(
$query,
'l',
DataScopeService::getVisibleAdminIds($adminId, $adminInfo),
self::operatorPoolIds($adminId)
);
if ($localLinkId > 0) {
$query->where('l.id', $localLinkId);
}
@@ -56,7 +61,8 @@ class WecomAcquisitionCustomerLogic
$page = max(1, (int) ($params['page_no'] ?? $params['page'] ?? 1));
$pageSize = min(100, max(1, (int) ($params['page_size'] ?? 20)));
$visibleIds = DataScopeService::getVisibleAdminIds($adminId, $adminInfo);
$base = self::customerQuery($params, $visibleIds);
$operatorPoolIds = self::operatorPoolIds($adminId);
$base = self::customerQuery($params, $visibleIds, $operatorPoolIds);
$total = (int) (clone $base)->count();
$rows = $base
->field('c.id,c.promotion_link_id,c.link_id,c.external_userid,c.userid,c.owner_admin_id,c.dept_id,c.state,c.chat_status,c.recv_msg_cnt,c.message_count_known,c.first_acquired_time,c.last_chat_time,c.last_sync_time,c.create_time,c.update_time,a.name as owner_name,d.name as dept_name,l.name as link_name,p.name as pool_name')
@@ -71,7 +77,7 @@ class WecomAcquisitionCustomerLogic
}
unset($row);
$summaryQuery = self::customerQuery($params, $visibleIds);
$summaryQuery = self::customerQuery($params, $visibleIds, $operatorPoolIds);
$summaryRow = $summaryQuery->fieldRaw(
'COUNT(*) AS customer_count, '
. 'COALESCE(SUM(CASE WHEN c.message_count_known = 1 THEN c.recv_msg_cnt ELSE 0 END),0) AS recv_msg_cnt, '
@@ -98,14 +104,14 @@ class WecomAcquisitionCustomerLogic
];
}
private static function customerQuery(array $params, ?array $visibleIds)
private static function customerQuery(array $params, ?array $visibleIds, array $operatorPoolIds)
{
$query = Db::name('qywx_customer_acquisition_customer')->alias('c')
->leftJoin('admin a', 'a.id = c.owner_admin_id AND a.delete_time IS NULL')
->leftJoin('dept d', 'd.id = c.dept_id')
->leftJoin('qywx_promotion_link l', 'l.id = c.promotion_link_id')
->leftJoin('qywx_promotion_pool p', 'p.id = l.pool_id');
self::applyCustomerScope($query, $visibleIds);
self::applyCustomerScope($query, $visibleIds, $operatorPoolIds);
$localLinkId = max(0, (int) ($params['promotion_link_id'] ?? 0));
if ($localLinkId > 0) {
$query->where('c.promotion_link_id', $localLinkId);
@@ -131,35 +137,69 @@ class WecomAcquisitionCustomerLogic
* 企微 customer_list 的 state/customer_channel 允许为空,不能因此丢掉已返回的客户;
* 同时也不能直接放开全部 owner_admin_id=0 的记录,否则会跨部门泄露未映射客户。
*/
private static function applyCustomerScope($query, ?array $visibleIds): void
private static function applyCustomerScope($query, ?array $visibleIds, array $operatorPoolIds): void
{
if ($visibleIds === null) {
return;
}
if ($visibleIds === []) {
if ($visibleIds === [] && $operatorPoolIds === []) {
$query->whereRaw('1 = 0');
return;
}
$ids = array_values(array_unique(array_map('intval', $visibleIds)));
$query->where(function ($scope) use ($ids): void {
$scope->whereIn('c.owner_admin_id', $ids)
->whereOr(function ($unmapped) use ($ids): void {
$unmapped->where('c.owner_admin_id', 0)
->whereIn('l.owner_admin_id', $ids);
});
$query->where(function ($scope) use ($ids, $operatorPoolIds): void {
if ($ids !== []) {
$scope->whereIn('c.owner_admin_id', $ids)
->whereOr(function ($unmapped) use ($ids): void {
$unmapped->where('c.owner_admin_id', 0)
->whereIn('l.owner_admin_id', $ids);
});
if ($operatorPoolIds !== []) {
$scope->whereOr('p.id', 'in', $operatorPoolIds);
}
return;
}
$scope->whereIn('p.id', $operatorPoolIds);
});
}
private static function applyScope($query, string $alias, ?array $visibleIds): void
private static function applyScope($query, string $alias, ?array $visibleIds, array $operatorPoolIds): void
{
if ($visibleIds === null) {
return;
}
if ($visibleIds === []) {
if ($visibleIds === [] && $operatorPoolIds === []) {
$query->whereRaw('1 = 0');
return;
}
$query->whereIn($alias . '.owner_admin_id', array_values(array_unique(array_map('intval', $visibleIds))));
$ids = array_values(array_unique(array_map('intval', $visibleIds)));
$query->where(function ($scope) use ($alias, $ids, $operatorPoolIds): void {
if ($ids !== []) {
$scope->whereIn($alias . '.owner_admin_id', $ids);
if ($operatorPoolIds !== []) {
$scope->whereOr($alias . '.pool_id', 'in', $operatorPoolIds);
}
return;
}
$scope->whereIn($alias . '.pool_id', $operatorPoolIds);
});
}
/** @return list<int> */
private static function operatorPoolIds(int $adminId): array
{
if ($adminId <= 0) {
return [];
}
$ids = Db::name('qywx_promotion_pool_operator')
->where('admin_id', $adminId)
->whereNull('delete_time')
->column('pool_id');
return array_values(array_unique(array_filter(array_map(
static fn ($value): int => (int) $value,
$ids
), static fn (int $value): bool => $value > 0)));
}
private static function maskIdentifier(string $value): string