同步失败原因,最近同步成功的时间记录
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
-- 工单同步日志增强:最近成功时间/方式、完整失败原因
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
ALTER TABLE `fa_split_ticket`
|
||||
MODIFY COLUMN `sync_message` text COMMENT '同步失败完整原因',
|
||||
ADD COLUMN `sync_success_time` bigint(16) DEFAULT NULL COMMENT '最近一次同步成功时间' AFTER `sync_time`,
|
||||
ADD COLUMN `sync_success_mode` enum('auto','manual') DEFAULT NULL COMMENT '最近成功同步方式:auto=自动,manual=手动' AFTER `sync_success_time`;
|
||||
|
||||
-- 历史成功记录回填最近成功时间(方式未知留空)
|
||||
UPDATE `fa_split_ticket`
|
||||
SET `sync_success_time` = `sync_time`
|
||||
WHERE `sync_status` = 'success'
|
||||
AND `sync_success_time` IS NULL
|
||||
AND `sync_time` IS NOT NULL
|
||||
AND `sync_time` > 0;
|
||||
@@ -62,12 +62,13 @@ class SplitSyncTickets extends Command
|
||||
try {
|
||||
$count = $service->syncDueTickets();
|
||||
$output->writeln('<info>本次处理工单数: ' . $count . '</info>');
|
||||
$output->writeln('<comment>汇总日志已写入 runtime/log/split_sync.log</comment>');
|
||||
} finally {
|
||||
$cronLock->release();
|
||||
}
|
||||
|
||||
if (SplitTicketSyncLogger::isEnabled()) {
|
||||
$output->writeln('<comment>调试日志已写入 runtime/log/split_sync.log</comment>');
|
||||
$output->writeln('<comment>详细调试日志已写入 runtime/log/split_sync.log</comment>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,6 +273,8 @@ class Ticket extends Backend
|
||||
$params['sync_status'],
|
||||
$params['sync_time'],
|
||||
$params['sync_message'],
|
||||
$params['sync_success_time'],
|
||||
$params['sync_success_mode'],
|
||||
$params['sync_fail_count'],
|
||||
$params['speed_snapshot_count'],
|
||||
$params['speed_snapshot_time'],
|
||||
|
||||
@@ -37,6 +37,13 @@ return [
|
||||
'Sync display success' => '同步成功 / 在线 %s',
|
||||
'Sync display pending' => '待同步',
|
||||
'Sync display error' => '同步异常',
|
||||
'Sync display auto paused' => '自动同步已暂停',
|
||||
'Sync success time' => '最近同步成功',
|
||||
'Sync mode auto' => '自动',
|
||||
'Sync mode manual' => '手动',
|
||||
'Sync tooltip auto paused' => '连续失败 %s 次,已达暂停阈值 %s,自动同步已暂停',
|
||||
'Sync tooltip error prefix' => '异常原因:',
|
||||
'Cron log path hint' => '汇总日志已写入 runtime/log/split_sync.log',
|
||||
'Createtime' => '创建时间',
|
||||
'Copy' => '拷贝',
|
||||
'Summary row' => '汇总',
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace app\admin\model\split;
|
||||
|
||||
use app\common\service\SplitSyncConfigService;
|
||||
use think\Db;
|
||||
use think\Model;
|
||||
|
||||
@@ -31,6 +32,9 @@ class Ticket extends Model
|
||||
'ticket_progress_text',
|
||||
'inbound_ratio_text',
|
||||
'sync_display_text',
|
||||
'sync_success_text',
|
||||
'sync_tooltip_text',
|
||||
'sync_auto_paused',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -152,13 +156,35 @@ class Ticket extends Model
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步状态展示文案
|
||||
* 是否因连续失败暂停自动同步(工单仍为开启状态)
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public static function isAutoSyncPaused(array $data): bool
|
||||
{
|
||||
if ((string) ($data['status'] ?? '') !== 'normal') {
|
||||
return false;
|
||||
}
|
||||
$threshold = SplitSyncConfigService::getFailPauseThreshold();
|
||||
if ($threshold <= 0) {
|
||||
return false;
|
||||
}
|
||||
return (int) ($data['sync_fail_count'] ?? 0) >= $threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步状态展示文案(列表列默认显示,异常详情见 tooltip)
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public function getSyncDisplayTextAttr($value, $data): string
|
||||
{
|
||||
if (self::isAutoSyncPaused($data)) {
|
||||
$threshold = SplitSyncConfigService::getFailPauseThreshold();
|
||||
return sprintf((string) __('Sync display auto paused'), $threshold);
|
||||
}
|
||||
|
||||
$status = (string) ($data['sync_status'] ?? 'pending');
|
||||
$online = (int) ($data['online_count'] ?? 0);
|
||||
if ($status === 'success') {
|
||||
@@ -170,6 +196,66 @@ class Ticket extends Model
|
||||
return (string) __('Sync display error');
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步状态列 tooltip 完整说明
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public function getSyncTooltipTextAttr($value, $data): string
|
||||
{
|
||||
$parts = [];
|
||||
if (self::isAutoSyncPaused($data)) {
|
||||
$threshold = SplitSyncConfigService::getFailPauseThreshold();
|
||||
$parts[] = sprintf(
|
||||
(string) __('Sync tooltip auto paused'),
|
||||
(int) ($data['sync_fail_count'] ?? 0),
|
||||
$threshold
|
||||
);
|
||||
}
|
||||
|
||||
$message = trim((string) ($data['sync_message'] ?? ''));
|
||||
if ($message !== '') {
|
||||
$parts[] = (string) __('Sync tooltip error prefix') . $message;
|
||||
}
|
||||
|
||||
return implode("\n", $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否暂停自动同步(供前端样式判断)
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public function getSyncAutoPausedAttr($value, $data): bool
|
||||
{
|
||||
return self::isAutoSyncPaused($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 最近一次同步成功时间及方式
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public function getSyncSuccessTextAttr($value, $data): string
|
||||
{
|
||||
$ts = (int) ($data['sync_success_time'] ?? 0);
|
||||
if ($ts <= 0) {
|
||||
return '';
|
||||
}
|
||||
$timeText = date('Y-m-d H:i:s', $ts);
|
||||
$mode = (string) ($data['sync_success_mode'] ?? '');
|
||||
if ($mode === 'auto') {
|
||||
return $timeText . ' (' . (string) __('Sync mode auto') . ')';
|
||||
}
|
||||
if ($mode === 'manual') {
|
||||
return $timeText . ' (' . (string) __('Sync mode manual') . ')';
|
||||
}
|
||||
return $timeText;
|
||||
}
|
||||
|
||||
public function setStartTimeAttr($value): ?int
|
||||
{
|
||||
return self::parseTimeValue($value);
|
||||
|
||||
@@ -67,6 +67,24 @@
|
||||
font-size: 14px;
|
||||
color: #0f172a;
|
||||
}
|
||||
.split-sync-success-normal {
|
||||
color: #3c763d;
|
||||
font-weight: 600;
|
||||
}
|
||||
.split-sync-success-stopped {
|
||||
color: #a94442;
|
||||
font-weight: 600;
|
||||
}
|
||||
.split-ticket-sync-status-paused {
|
||||
color: #8a6d3b;
|
||||
font-weight: 600;
|
||||
cursor: help;
|
||||
border-bottom: 1px dotted #8a6d3b;
|
||||
}
|
||||
.split-ticket-sync-status-error {
|
||||
cursor: help;
|
||||
border-bottom: 1px dotted #a94442;
|
||||
}
|
||||
</style>
|
||||
<div class="panel panel-default panel-intro">
|
||||
<div class="panel-heading">
|
||||
|
||||
Reference in New Issue
Block a user