连续同步失败后触发重试时间点

This commit is contained in:
root
2026-07-13 23:06:53 +08:00
parent 76692e0021
commit 98fc6d9e3d
17 changed files with 759 additions and 13 deletions
@@ -14,9 +14,13 @@ SELECT 'split_scrm_session_ttl_minutes', 'split', '云控 antiBot 会话 TTL(分
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `fa_config` WHERE `name` = 'split_scrm_session_ttl_minutes' LIMIT 1);
INSERT INTO `fa_config` (`name`, `group`, `title`, `tip`, `type`, `visible`, `value`, `content`, `rule`, `extend`, `setting`)
SELECT 'split_sync_fail_pause_threshold', 'split', '连续同步失败暂停阈值', '连续同步失败达到该次数后自动关闭工单并暂停定时同步;同步成功后将清零重新计数;0 表示不因失败自动暂停', 'number', '', '5', '', '', '', NULL
SELECT 'split_sync_fail_pause_threshold', 'split', '连续同步失败暂停阈值', '连续同步失败达到该次数后暂停定时同步;同步成功后将清零重新计数;0 表示不因失败自动暂停', 'number', '', '5', '', '', '', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `fa_config` WHERE `name` = 'split_sync_fail_pause_threshold' LIMIT 1);
INSERT INTO `fa_config` (`name`, `group`, `title`, `tip`, `type`, `visible`, `value`, `content`, `rule`, `extend`, `setting`)
SELECT 'split_sync_fail_retry_minutes', 'split', '失败重试时间点(分钟)', '逗号分隔、升序,相对首次达失败暂停阈值后的绝对分钟数,如 10,20,30,50;留空则达阈值后永久暂停自动同步', 'string', '', '', '', '', ' placeholder="10,20,30,50"', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `fa_config` WHERE `name` = 'split_sync_fail_retry_minutes' LIMIT 1);
INSERT INTO `fa_config` (`name`, `group`, `title`, `tip`, `type`, `visible`, `value`, `content`, `rule`, `extend`, `setting`)
SELECT 'split_sync_interval_a2c', 'split', 'A2C云控同步周期(分钟)', '0 表示不自动同步', 'number', '', '5', '', '', '', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `fa_config` WHERE `name` = 'split_sync_interval_a2c' LIMIT 1);
@@ -0,0 +1,11 @@
-- 同步失败分阶段重试:系统配置 + 工单状态字段
SET NAMES utf8mb4;
INSERT INTO `fa_config` (`name`, `group`, `title`, `tip`, `type`, `visible`, `value`, `content`, `rule`, `extend`, `setting`)
SELECT 'split_sync_fail_retry_minutes', 'split', '失败重试时间点(分钟)', '逗号分隔、升序,相对首次达失败暂停阈值后的绝对分钟数,如 10,20,30,50;留空则达阈值后永久暂停自动同步', 'string', '', '', '', '', ' placeholder="10,20,30,50"', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `fa_config` WHERE `name` = 'split_sync_fail_retry_minutes' LIMIT 1);
ALTER TABLE `fa_split_ticket`
ADD COLUMN `sync_fail_pause_at` bigint(16) DEFAULT NULL COMMENT '达阈值进入重试的锚点时间' AFTER `sync_fail_count`,
ADD COLUMN `sync_fail_retry_index` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '已完成的重试次数(0=尚未重试)' AFTER `sync_fail_pause_at`,
ADD COLUMN `sync_auto_sync_stopped` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '1=全部重试失败,永久终止自动同步' AFTER `sync_fail_retry_index`;
@@ -278,6 +278,9 @@ class Ticket extends Backend
$params['sync_success_time'],
$params['sync_success_mode'],
$params['sync_fail_count'],
$params['sync_fail_pause_at'],
$params['sync_fail_retry_index'],
$params['sync_auto_sync_stopped'],
$params['speed_snapshot_count'],
$params['speed_snapshot_time'],
$params['click_count'],
@@ -44,10 +44,14 @@ return [
'Sync display pending' => '待同步',
'Sync display error' => '同步异常',
'Sync display auto paused' => '自动同步已暂停',
'Sync display auto sync stopped' => '自动同步已终止(重试已用尽)',
'Sync display retry waiting' => '自动同步已暂停,将于 %s 第 %d 次重试',
'Sync success time' => '最近同步成功',
'Sync mode auto' => '自动',
'Sync mode manual' => '手动',
'Sync tooltip auto paused' => '连续失败 %s 次,已达暂停阈值 %s,自动同步已暂停',
'Sync tooltip auto sync stopped' => '分阶段重试已全部失败,自动同步已永久终止;手动同步成功后可恢复',
'Sync tooltip retry waiting' => '连续失败 %s 次,将于 %s 进行第 %d 次自动重试',
'Sync tooltip error prefix' => '异常原因:',
'Cron log path hint' => '汇总日志已写入 runtime/log/split_sync.log',
'Createtime' => '创建时间',
@@ -6,6 +6,7 @@ namespace app\admin\model\split;
use app\common\service\SplitSyncConfigService;
use app\common\service\SplitTicketRuleService;
use app\common\service\SplitTicketSyncFailRetryService;
use app\common\service\SplitTicketSyncLockService;
use think\Db;
use think\Model;
@@ -176,10 +177,23 @@ class Ticket extends Model
if ((string) ($data['status'] ?? '') !== 'normal') {
return false;
}
$retryService = new SplitTicketSyncFailRetryService();
if ($retryService->isPermanentlyStopped($data)) {
return true;
}
if ($retryService->isInRetryMode($data)) {
return true;
}
$threshold = SplitSyncConfigService::getFailPauseThreshold();
if ($threshold <= 0) {
return false;
}
if (SplitSyncConfigService::hasFailRetrySchedule()) {
return false;
}
return (int) ($data['sync_fail_count'] ?? 0) >= $threshold;
}
@@ -191,9 +205,26 @@ class Ticket extends Model
*/
public function getSyncDisplayTextAttr($value, $data): string
{
$retryService = new SplitTicketSyncFailRetryService();
if ($retryService->isPermanentlyStopped($data)) {
return (string) __('Sync display auto sync stopped');
}
if ($retryService->isInRetryMode($data)) {
$nextAt = $retryService->getNextRetryAt($data);
$attempt = (int) ($data['sync_fail_retry_index'] ?? 0) + 1;
if ($nextAt !== null) {
return sprintf(
(string) __('Sync display retry waiting'),
date('H:i', $nextAt),
$attempt
);
}
}
if (self::isAutoSyncPaused($data)) {
$threshold = SplitSyncConfigService::getFailPauseThreshold();
return sprintf((string) __('Sync display auto paused'), $threshold);
return (string) __('Sync display auto paused');
}
$status = (string) ($data['sync_status'] ?? 'pending');
@@ -216,7 +247,22 @@ class Ticket extends Model
public function getSyncTooltipTextAttr($value, $data): string
{
$parts = [];
if (self::isAutoSyncPaused($data)) {
$retryService = new SplitTicketSyncFailRetryService();
if ($retryService->isPermanentlyStopped($data)) {
$parts[] = (string) __('Sync tooltip auto sync stopped');
} elseif ($retryService->isInRetryMode($data)) {
$nextAt = $retryService->getNextRetryAt($data);
$attempt = (int) ($data['sync_fail_retry_index'] ?? 0) + 1;
if ($nextAt !== null) {
$parts[] = sprintf(
(string) __('Sync tooltip retry waiting'),
(int) ($data['sync_fail_count'] ?? 0),
date('Y-m-d H:i:s', $nextAt),
$attempt
);
}
} elseif (self::isAutoSyncPaused($data)) {
$threshold = SplitSyncConfigService::getFailPauseThreshold();
$parts[] = sprintf(
(string) __('Sync tooltip auto paused'),