fix : sync issu
This commit is contained in:
parent
d657c48600
commit
95592aa510
|
|
@ -59,7 +59,7 @@ public function getTitle(): string
|
||||||
|
|
||||||
public function getPendingCount(): int
|
public function getPendingCount(): int
|
||||||
{
|
{
|
||||||
return SyncLog::changesSince((int) OsurgInitial::val('our_sync_cursor', 0))->count();
|
return SyncLog::changesSince(OsurgInitial::val('our_sync_cursor') ?: null)->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLastSyncTime(): string
|
public function getLastSyncTime(): string
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,9 @@ public function export(Request $request): JsonResponse
|
||||||
return response()->json(['error' => 'Unauthorized'], 401);
|
return response()->json(['error' => 'Unauthorized'], 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
$since = (int) $request->query('since', 0);
|
$since = $request->query('since') ?: null;
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'last_sync_id' => SyncLog::lastSyncId(),
|
|
||||||
'changes' => SyncLog::changesSince($since),
|
'changes' => SyncLog::changesSince($since),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,22 @@ public static function lastSyncId(): int
|
||||||
return (int) static::where('action', 'synced')->max('id') ?: 0;
|
return (int) static::where('action', 'synced')->max('id') ?: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function changesSince(int $since): \Illuminate\Database\Eloquent\Collection
|
public static function changesSince(?string $since): \Illuminate\Database\Eloquent\Collection
|
||||||
{
|
{
|
||||||
return static::where('id', '>', $since)
|
$query = static::whereIn('action', ['created', 'updated', 'deleted'])
|
||||||
->whereIn('action', ['created', 'updated', 'deleted'])
|
->orderBy('datetime')
|
||||||
->orderBy('id')
|
->orderBy('id');
|
||||||
->get();
|
|
||||||
|
if ($since !== null && $since !== '') {
|
||||||
|
$query->where('datetime', '>', $since);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function serializeDate(\DateTimeInterface $date): string
|
||||||
|
{
|
||||||
|
return $date->format('Y-m-d H:i:s');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function markSynced(string $ip): static
|
public static function markSynced(string $ip): static
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@ public function sync(): array
|
||||||
$report = [];
|
$report = [];
|
||||||
$baseUrl = "http://{$this->peerIp}:{$this->peerPort}";
|
$baseUrl = "http://{$this->peerIp}:{$this->peerPort}";
|
||||||
|
|
||||||
$peerCursor = (int) \App\Models\OsurgInitial::val('sync_peer_cursor', 0);
|
$peerCursor = \App\Models\OsurgInitial::val('sync_peer_cursor') ?: null;
|
||||||
$ourLastSync = (int) \App\Models\OsurgInitial::val('our_sync_cursor', 0);
|
$ourLastSync = \App\Models\OsurgInitial::val('our_sync_cursor') ?: null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$pullResponse = Http::timeout(30)
|
$pullResponse = Http::timeout(30)
|
||||||
|
|
@ -65,14 +65,27 @@ public function sync(): array
|
||||||
if (! empty($peerChanges)) {
|
if (! empty($peerChanges)) {
|
||||||
app()->instance('sync.applying', true);
|
app()->instance('sync.applying', true);
|
||||||
|
|
||||||
DB::transaction(function () use ($peerChanges, &$report) {
|
$pullReport = [];
|
||||||
|
DB::transaction(function () use ($peerChanges, &$pullReport) {
|
||||||
foreach ($peerChanges as $change) {
|
foreach ($peerChanges as $change) {
|
||||||
$this->applyChange($change, 'دریافت', $report);
|
$this->applyChange($change, 'دریافت', $pullReport);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
foreach ($pullReport as $line) {
|
||||||
|
$report[] = $line;
|
||||||
|
}
|
||||||
|
|
||||||
$maxPeerChangeId = max(array_column($peerChanges, 'id'));
|
$pullHasErrors = ! empty(array_filter($pullReport, fn ($l) => str_contains((string) $l, '✗')));
|
||||||
$this->savePeerCursor(max($peerCursor, $maxPeerChangeId));
|
|
||||||
|
if (! $pullHasErrors) {
|
||||||
|
$datetimes = array_filter(array_column($peerChanges, 'datetime'));
|
||||||
|
$maxPeerDatetime = \Carbon\Carbon::parse(max($datetimes))->format('Y-m-d H:i:s');
|
||||||
|
if ($peerCursor === null || $maxPeerDatetime > $peerCursor) {
|
||||||
|
$this->savePeerCursor($maxPeerDatetime);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$report[] = 'هشدار: peer_cursor پیش نرفت — برخی تغییرات دریافتی اعمال نشد و دفعه بعد retry میشه.';
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->isFtpConfigured()) {
|
if ($this->isFtpConfigured()) {
|
||||||
$this->transferFilesViaFtp($peerChanges, 's2c', $report);
|
$this->transferFilesViaFtp($peerChanges, 's2c', $report);
|
||||||
|
|
@ -98,14 +111,22 @@ public function sync(): array
|
||||||
->post("{$baseUrl}/api/sync/apply", ['changes' => $ourChanges]);
|
->post("{$baseUrl}/api/sync/apply", ['changes' => $ourChanges]);
|
||||||
|
|
||||||
if ($pushResponse->successful()) {
|
if ($pushResponse->successful()) {
|
||||||
foreach ($pushResponse->json('report', []) as $line) {
|
$pushReport = $pushResponse->json('report', []);
|
||||||
|
foreach ($pushReport as $line) {
|
||||||
$report[] = 'ارسال: ' . $line;
|
$report[] = 'ارسال: ' . $line;
|
||||||
}
|
}
|
||||||
$report[] = count($ourChanges) . ' تغییر به سیستم مقابل ارسال شد.';
|
$report[] = count($ourChanges) . ' تغییر به سیستم مقابل ارسال شد.';
|
||||||
|
|
||||||
if (! empty($ourChanges)) {
|
$hasErrors = ! empty(array_filter($pushReport, fn ($l) => str_contains((string) $l, '✗')));
|
||||||
$maxOurId = max(array_column($ourChanges, 'id'));
|
|
||||||
$this->saveOurCursor($maxOurId);
|
if (! empty($ourChanges) && ! $hasErrors) {
|
||||||
|
$ourDatetimes = array_filter(array_column($ourChanges, 'datetime'));
|
||||||
|
$maxOurDatetime = \Carbon\Carbon::parse(max($ourDatetimes))->format('Y-m-d H:i:s');
|
||||||
|
if ($ourLastSync === null || $maxOurDatetime > $ourLastSync) {
|
||||||
|
$this->saveOurCursor($maxOurDatetime);
|
||||||
|
}
|
||||||
|
} elseif ($hasErrors) {
|
||||||
|
$report[] = 'هشدار: cursor پیش نرفت — برخی تغییرات روی سیستم مقابل اعمال نشد و دفعه بعد retry میشه.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->isFtpConfigured()) {
|
if ($this->isFtpConfigured()) {
|
||||||
|
|
@ -431,7 +452,7 @@ private function applyChange(array $change, string $prefix, array &$report): voi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function saveOurCursor(int $cursor): void
|
private function saveOurCursor(string $cursor): void
|
||||||
{
|
{
|
||||||
\App\Models\OsurgInitial::updateOrCreate(
|
\App\Models\OsurgInitial::updateOrCreate(
|
||||||
['init_parameter' => 'our_sync_cursor'],
|
['init_parameter' => 'our_sync_cursor'],
|
||||||
|
|
@ -440,7 +461,7 @@ private function saveOurCursor(int $cursor): void
|
||||||
cache()->forget('osurg_initial.our_sync_cursor');
|
cache()->forget('osurg_initial.our_sync_cursor');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function savePeerCursor(int $cursor): void
|
private function savePeerCursor(string $cursor): void
|
||||||
{
|
{
|
||||||
\App\Models\OsurgInitial::updateOrCreate(
|
\App\Models\OsurgInitial::updateOrCreate(
|
||||||
['init_parameter' => 'sync_peer_cursor'],
|
['init_parameter' => 'sync_peer_cursor'],
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ public function run(): void
|
||||||
TreatmentSeeder::class,
|
TreatmentSeeder::class,
|
||||||
SurgeryCenterSeeder::class,
|
SurgeryCenterSeeder::class,
|
||||||
MedicationSeeder::class,
|
MedicationSeeder::class,
|
||||||
|
LabTestSeeder::class,
|
||||||
OsurgInitialSeeder::class,
|
OsurgInitialSeeder::class,
|
||||||
RolePermissionSeeder::class,
|
RolePermissionSeeder::class,
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,17 @@ public function run(): void
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'init_parameter' => 'ftp_remote_path',
|
'init_parameter' => 'ftp_remote_path',
|
||||||
'init_value' => 'C:/wamp64/www/matab-panel/storage/app/public',
|
'init_value' => '/',
|
||||||
|
'attachment' => null,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'init_parameter' => 'sync_peer_cursor',
|
||||||
|
'init_value' => null,
|
||||||
|
'attachment' => null,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'init_parameter' => 'our_sync_cursor',
|
||||||
|
'init_value' => null,
|
||||||
'attachment' => null,
|
'attachment' => null,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue