手动关闭状态不要自动打开重启同步

This commit is contained in:
root
2026-07-07 14:56:39 +08:00
parent 2e621bf970
commit 92b4faf61f
12 changed files with 166 additions and 14 deletions
@@ -19,6 +19,31 @@ class SplitTicketRuleService
$this->ratioDeferredService = $ratioDeferredService ?? new SplitNumberRatioDeferredService();
}
/**
* 手动关闭的工单(manual_manage=1):禁止自动同步改写 status,须用户手动开启
*/
public function isManuallyClosed(Ticket $ticket): bool
{
return (int) ($ticket['manual_manage'] ?? 0) === 1;
}
/**
* 列表/编辑切换状态时同步 manual_manage 标记
*
* @param array<string, mixed> $values
*/
public function applyManualManageForStatusChange(array &$values): void
{
if (!isset($values['status'])) {
return;
}
if ((string) $values['status'] === 'hidden') {
$values['manual_manage'] = 1;
} elseif ((string) $values['status'] === 'normal') {
$values['manual_manage'] = 0;
}
}
/**
* 同步后应用工单开关规则;号码开关由 applyNumberRules 综合裁决(平台在线 + 单号上限 + 下号比率)
*/
@@ -190,10 +215,13 @@ class SplitTicketRuleService
}
/**
* 完成量、时间窗口决定工单开关(定时与手动同步均适用)
* 完成量、时间窗口决定工单开关(定时与手动同步均适用;手动关闭工单除外
*/
public function applyTicketStatusRules(Ticket $ticket, int $completeCount): void
{
if ($this->isManuallyClosed($ticket)) {
return;
}
$status = $this->resolveTicketStatus($ticket, $completeCount);
if ($status !== (string) ($ticket['status'] ?? 'hidden')) {
Ticket::where('id', (int) $ticket['id'])->update([
@@ -38,6 +38,10 @@ class SplitTicketSyncDispatchService
foreach ($metaList as $meta) {
$ticketId = (int) $meta['id'];
if ((int) ($meta['manual_manage'] ?? 0) === 1) {
$skipped[] = $ticketId;
continue;
}
if ($lockService->isLocked($ticketId)) {
$skipped[] = $ticketId;
continue;
@@ -326,15 +330,16 @@ class SplitTicketSyncDispatchService
$rows = Db::name('split_ticket')
->where('id', 'in', $ids)
->field('id,ticket_type,ticket_url')
->field('id,ticket_type,ticket_url,manual_manage')
->select();
$list = [];
foreach ($rows as $row) {
$list[] = [
'id' => (int) $row['id'],
'ticket_type' => (string) ($row['ticket_type'] ?? ''),
'ticket_url' => (string) ($row['ticket_url'] ?? ''),
'id' => (int) $row['id'],
'ticket_type' => (string) ($row['ticket_type'] ?? ''),
'ticket_url' => (string) ($row['ticket_url'] ?? ''),
'manual_manage' => (int) ($row['manual_manage'] ?? 0),
];
}
@@ -51,12 +51,19 @@ class SplitTicketSyncService
'force' => $force,
'syncMode' => $syncMode,
'status' => (string) $ticket['status'],
'manualManage' => (int) ($ticket['manual_manage'] ?? 0),
'syncFailCount' => (int) ($ticket['sync_fail_count'] ?? 0),
'syncTime' => (int) ($ticket['sync_time'] ?? 0),
'pageUrl' => (string) $ticket['ticket_url'],
'nodeHost' => SplitSyncConfigService::getNodeHost(),
]);
if ($this->ruleService->isManuallyClosed($ticket)) {
SplitTicketSyncLogger::log('sync', 'skipped', ['reason' => '工单已手动关闭']);
SplitTicketSyncLogger::clearTicketContext();
return ['success' => false, 'message' => '工单已手动关闭,暂停同步', 'skipped' => true];
}
if (!$force && !$dueValidated) {
$skip = $this->shouldSkip($ticket);
if ($skip !== null) {
@@ -389,7 +396,9 @@ class SplitTicketSyncService
return [];
}
$query = Ticket::where('status', 'normal')->whereIn('ticket_type', $types);
$query = Ticket::where('status', 'normal')
->where('manual_manage', 0)
->whereIn('ticket_type', $types);
if ($failThreshold > 0) {
$query->where('sync_fail_count', '<', $failThreshold);
}
@@ -503,6 +512,15 @@ class SplitTicketSyncService
*/
private function doSync(Ticket $ticket, string $syncMode): array
{
$freshTicket = Ticket::get((int) $ticket['id']);
if (!$freshTicket) {
return ['success' => false, 'message' => '工单不存在', 'skipped' => true];
}
if ($this->ruleService->isManuallyClosed($freshTicket)) {
return ['success' => false, 'message' => '工单已手动关闭,暂停同步', 'skipped' => true];
}
$ticket = $freshTicket;
$ticketType = (string) $ticket['ticket_type'];
$pageUrl = trim((string) $ticket['ticket_url']);
if ($pageUrl === '') {
@@ -589,6 +607,9 @@ class SplitTicketSyncService
private function shouldSkip(Ticket $ticket): ?string
{
if ($this->ruleService->isManuallyClosed($ticket)) {
return '工单已手动关闭,暂停同步';
}
if ((string) $ticket['status'] === 'hidden') {
return '工单已关闭';
}