152 lines
4.3 KiB
PHP
152 lines
4.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace app\common\service;
|
|
|
|
use app\admin\model\split\Number;
|
|
use app\admin\model\split\Ticket;
|
|
|
|
/**
|
|
* 工单本地开启号码数(active_number_count)物化字段维护
|
|
*
|
|
* 统计口径:fa_split_number 中 admin_id + split_link_id + ticket_name 匹配且 status=normal
|
|
*/
|
|
class SplitTicketActiveNumberCountService
|
|
{
|
|
/**
|
|
* 按工单关联键统计并回写 active_number_count
|
|
*/
|
|
public function refreshForTicketKeys(int $adminId, int $linkId, string $ticketName): void
|
|
{
|
|
$ticketName = trim($ticketName);
|
|
if ($adminId <= 0 || $linkId <= 0 || $ticketName === '') {
|
|
return;
|
|
}
|
|
|
|
$count = (int) Number::where('admin_id', $adminId)
|
|
->where('split_link_id', $linkId)
|
|
->where('ticket_name', $ticketName)
|
|
->where('status', 'normal')
|
|
->count();
|
|
|
|
Ticket::where('admin_id', $adminId)
|
|
->where('split_link_id', $linkId)
|
|
->where('ticket_name', $ticketName)
|
|
->update([
|
|
'active_number_count' => $count,
|
|
'updatetime' => time(),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 按工单模型回写
|
|
*/
|
|
public function refreshForTicket(Ticket $ticket): void
|
|
{
|
|
$this->refreshForTicketKeys(
|
|
(int) $ticket['admin_id'],
|
|
(int) $ticket['split_link_id'],
|
|
(string) $ticket['ticket_name']
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 批量号码 ID:去重后刷新涉及工单
|
|
*
|
|
* @param array<int|string> $ids
|
|
*/
|
|
public function refreshForNumberIds(array $ids): void
|
|
{
|
|
$ids = array_values(array_filter(array_map('intval', $ids)));
|
|
if ($ids === []) {
|
|
return;
|
|
}
|
|
|
|
$rows = Number::where('id', 'in', $ids)
|
|
->field('admin_id,split_link_id,ticket_name')
|
|
->select();
|
|
|
|
$this->refreshFromNumberRows($rows);
|
|
}
|
|
|
|
/**
|
|
* 编辑单条号码:关联键变更时刷新旧工单与新工单
|
|
*
|
|
* @param array<string, mixed> $before
|
|
* @param array<string, mixed> $after
|
|
*/
|
|
public function refreshAfterNumberEdit(array $before, array $after): void
|
|
{
|
|
$keys = [];
|
|
$beforeKey = $this->buildTicketKeyFromRow($before);
|
|
if ($beforeKey !== null) {
|
|
$keys[] = $beforeKey;
|
|
}
|
|
$afterKey = $this->buildTicketKeyFromRow($after);
|
|
if ($afterKey !== null) {
|
|
$keys[] = $afterKey;
|
|
}
|
|
$this->refreshForTicketKeyList($keys);
|
|
}
|
|
|
|
/**
|
|
* 批量工单关联键去重后刷新
|
|
*
|
|
* @param array<int, array{0:int,1:int,2:string}> $keys
|
|
*/
|
|
public function refreshForTicketKeyList(array $keys): void
|
|
{
|
|
$seen = [];
|
|
foreach ($keys as $key) {
|
|
if (!is_array($key) || count($key) < 3) {
|
|
continue;
|
|
}
|
|
$adminId = (int) $key[0];
|
|
$linkId = (int) $key[1];
|
|
$ticketName = trim((string) $key[2]);
|
|
if ($adminId <= 0 || $linkId <= 0 || $ticketName === '') {
|
|
continue;
|
|
}
|
|
$hash = $adminId . ':' . $linkId . ':' . $ticketName;
|
|
if (isset($seen[$hash])) {
|
|
continue;
|
|
}
|
|
$seen[$hash] = true;
|
|
$this->refreshForTicketKeys($adminId, $linkId, $ticketName);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param iterable<int, array<string, mixed>|Number> $rows
|
|
*/
|
|
public function refreshFromNumberRows(iterable $rows): void
|
|
{
|
|
$keys = [];
|
|
foreach ($rows as $row) {
|
|
$data = $row instanceof Number ? $row->getData() : (array) $row;
|
|
$key = $this->buildTicketKeyFromRow($data);
|
|
if ($key !== null) {
|
|
$keys[] = $key;
|
|
}
|
|
}
|
|
$this->refreshForTicketKeyList($keys);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $row
|
|
* @return array{0:int,1:int,2:string}|null
|
|
*/
|
|
private function buildTicketKeyFromRow(array $row): ?array
|
|
{
|
|
$adminId = (int) ($row['admin_id'] ?? 0);
|
|
$linkId = (int) ($row['split_link_id'] ?? 0);
|
|
$ticketName = trim((string) ($row['ticket_name'] ?? ''));
|
|
if ($adminId <= 0 || $linkId <= 0 || $ticketName === '') {
|
|
return null;
|
|
}
|
|
|
|
return [$adminId, $linkId, $ticketName];
|
|
}
|
|
}
|