提交同步状态为异步

This commit is contained in:
root
2026-07-02 03:39:29 +08:00
parent 439f79a5ae
commit 638b3c4032
10 changed files with 724 additions and 46 deletions
+74 -20
View File
@@ -8,8 +8,8 @@ use app\admin\model\split\Link as LinkModel;
use app\admin\model\split\Ticket as TicketModel;
use app\common\controller\Backend;
use app\common\service\SplitTicketRuleService;
use app\common\service\SplitTicketSyncDispatchService;
use app\common\service\SplitTicketSyncLogger;
use app\common\service\SplitTicketSyncService;
use think\Db;
use think\Lang;
use think\Loader;
@@ -39,7 +39,7 @@ class Ticket extends Backend
protected $modelSceneValidate = true;
/** @var string[] 无需鉴权的方法 */
protected $noNeedRight = ['script'];
protected $noNeedRight = ['script', 'syncpolling'];
/** @var string patches 视图目录 */
private const PATCH_VIEW_DIR = 'patches/application/admin/view/split/ticket/';
@@ -64,6 +64,7 @@ class Ticket extends Backend
'syncBackgroundStartedMsg' => __('Sync background started'),
'syncInProgressMsg' => __('Sync in progress'),
'syncTicketStartedMsg' => __('Sync ticket started'),
'syncDoneMsg' => __('Sync done'),
]);
$this->setupPatchFrontend();
@@ -284,7 +285,7 @@ class Ticket extends Backend
}
/**
* 手动同步选中工单
* 手动同步选中工单(投递 CLI 后台执行,Web 请求立即返回)
*/
public function sync(): void
{
@@ -307,31 +308,84 @@ class Ticket extends Backend
'appDebug' => SplitTicketSyncLogger::isEnabled(),
]);
$service = new SplitTicketSyncService();
$ok = 0;
$fail = 0;
$messages = [];
/** @var int[] $allowedIds */
$allowedIds = [];
$denied = 0;
foreach ($list as $row) {
if (is_array($adminIds) && !in_array((int) $row[$this->dataLimitField], $adminIds, true)) {
$fail++;
$messages[] = '#' . $row['id'] . ': 无权限';
$denied++;
continue;
}
$result = $service->syncOne((int) $row['id'], true);
if ($result['success']) {
$ok++;
} else {
$fail++;
$messages[] = '#' . $row['id'] . ': ' . ($result['message'] ?? '失败');
$allowedIds[] = (int) $row['id'];
}
if ($allowedIds === []) {
$this->error(__('You have no permission'));
}
// 尽早释放 Session 锁,避免投递等待期间阻塞同账号其它后台请求(如编辑/新增弹窗)
if (function_exists('session_write_close')) {
session_write_close();
}
$dispatch = new SplitTicketSyncDispatchService();
$result = $dispatch->dispatchManual($allowedIds);
$queuedCount = count($result['queued']);
$skippedCount = count($result['skipped']);
$failedCount = count($result['failed']);
if ($queuedCount === 0) {
if ($skippedCount > 0) {
$this->error(__('Sync all skipped busy'));
}
$this->error(__('Sync dispatch failed'));
}
$summary = sprintf(__('Sync dispatch queued'), $queuedCount);
if ($skippedCount > 0) {
$summary .= sprintf(__('Sync dispatch skipped suffix'), $skippedCount);
}
if ($failedCount > 0) {
$summary .= sprintf(__('Sync dispatch failed suffix'), $failedCount);
}
if ($denied > 0) {
$summary .= sprintf(__('Sync dispatch denied suffix'), $denied);
}
$this->success($summary, null, [
'queued' => $result['queued'],
'syncing' => $result['queued'],
]);
}
/**
* 轮询手工同步进度(依据 runtime 文件锁)
*/
public function syncpolling(): void
{
$idsRaw = trim((string) $this->request->request('ids', ''));
if ($idsRaw === '') {
$this->success('', null, ['syncing' => []]);
}
/** @var int[] $ticketIds */
$ticketIds = [];
foreach (explode(',', $idsRaw) as $part) {
$part = trim($part);
if ($part !== '' && ctype_digit($part)) {
$ticketIds[] = (int) $part;
}
}
$summary = sprintf('成功 %d 条,失败 %d 条', $ok, $fail);
if ($fail > 0) {
$summary .= '' . implode('', array_slice($messages, 0, 5));
if ($ticketIds === []) {
$this->success('', null, ['syncing' => []]);
}
$this->success($summary);
$dispatch = new SplitTicketSyncDispatchService();
$syncing = $dispatch->filterSyncingIds($ticketIds);
$this->success('', null, ['syncing' => $syncing]);
}
/**