From 9370e2fb3ca905ebd3df87f66ce9a991e141f525 Mon Sep 17 00:00:00 2001
From: antv
Date: Tue, 14 Jul 2026 10:46:34 +0700
Subject: [PATCH] update
---
app/Services/Admin/AdminService.php | 20 ++++-
docs/crob-job.md | 77 ++++++++++++++++---
.../components/user-avatar-section.blade.php | 14 ++--
.../views/components/user-form.blade.php | 5 --
tests/Feature/AdminUserListStatsTest.php | 72 ++++++++++++++++-
5 files changed, 159 insertions(+), 29 deletions(-)
diff --git a/app/Services/Admin/AdminService.php b/app/Services/Admin/AdminService.php
index c510739..bd1ecb4 100644
--- a/app/Services/Admin/AdminService.php
+++ b/app/Services/Admin/AdminService.php
@@ -244,10 +244,22 @@ class AdminService implements AdminServiceInterface
$user->card += $diff;
$user->save();
- $addCard->num_card = $newNumCard;
- $addCard->seller = $data['seller'];
- $addCard->date = $data['date'];
- $addCard->save();
+ $targetRecord = AddCard::where('buyer', $addCard->buyer)
+ ->where('seller', $data['seller'])
+ ->whereDate('date', $data['date'])
+ ->where('id', '!=', $addCard->id)
+ ->first();
+
+ if ($targetRecord) {
+ $targetRecord->num_card += $newNumCard;
+ $targetRecord->save();
+ $addCard->delete();
+ } else {
+ $addCard->num_card = $newNumCard;
+ $addCard->seller = $data['seller'];
+ $addCard->date = $data['date'];
+ $addCard->save();
+ }
});
}
diff --git a/docs/crob-job.md b/docs/crob-job.md
index 4770c4f..2b621cb 100644
--- a/docs/crob-job.md
+++ b/docs/crob-job.md
@@ -1,28 +1,81 @@
-# Hướng dẫn thiết lập Cron Job cho Laravel trên Ubuntu Server
+# Hướng dẫn thiết lập Cron Job cho Laravel trên Server (Ubuntu)
-Để hệ thống tự động chạy các tác vụ định kỳ (bao gồm tác vụ tự động reset thẻ vào cuối tháng qua lệnh `cards:reset`), bạn cần cấu hình Cron Job trên hệ điều hành Ubuntu Server trỏ đến bộ lập lịch (Task Scheduler) của Laravel.
+Để hệ thống tự động thực hiện các tác vụ định kỳ (bao gồm việc tự động reset thẻ vào lúc 23:59 ngày cuối tháng thông qua lệnh `cards:reset`), bạn cần cấu hình Cron Job trên hệ điều hành Ubuntu Server.
-## Các bước thiết lập
+Dưới đây là hướng dẫn chi tiết cho cả hai trường hợp: **Chạy qua Docker Compose** (mặc định của dự án) và **Chạy trực tiếp trên Host (Không dùng Docker)**.
-1. **Mở cấu hình Crontab:**
- Truy cập vào terminal của máy chủ Ubuntu dưới quyền của user chạy web (thường là `www-data` hoặc user deploy của bạn) và chạy lệnh:
+---
+
+## TRƯỜNG HỢP 1: Chạy qua Docker Compose (Khuyên dùng cho dự án này)
+
+Vì dự án chạy trong container Docker, Cron Job trên server Ubuntu (máy Host) cần gọi lệnh của Laravel vào bên trong container `app`.
+
+### Các bước thiết lập:
+
+1. **Mở file cấu hình Crontab của Ubuntu:**
+ Mở terminal của Ubuntu Server và chạy lệnh:
```bash
crontab -e
```
-2. **Thêm cấu hình chạy Scheduler:**
- Thêm dòng dưới đây vào cuối file cấu hình crontab để gọi Laravel scheduler kiểm tra tác vụ mỗi phút:
+2. **Thêm cấu hình chạy Laravel Scheduler:**
+ Thêm dòng dưới đây vào cuối file crontab:
```bash
- * * * * * cd /đường-dẫn-đến-thư-mục-dự-án && php artisan schedule:run >> /dev/null 2>&1
+ * * * * * cd /đường-dẫn-đến-thư-mục-dự-án && docker compose -f docker/docker-compose.yml exec -T app php artisan schedule:run >> /dev/null 2>&1
```
- *Lưu ý:* Thay thế `/đường-dẫn-đến-thư-mục-dự-án` bằng đường dẫn tuyệt đối đến thư mục chứa dự án trên server (Ví dụ: `/var/www/thankcard-system`).
+ *Lưu ý quan trọng:*
+ - Thay `/đường-dẫn-đến-thư-mục-dự-án` thành đường dẫn tuyệt đối đến dự án trên server (Ví dụ: `/var/www/thankcard-system`).
+ - Tham số **`-T`** (trong `exec -T`) là bắt buộc để tắt chế độ TTY (Tương tác nhập liệu), giúp cron chạy ngầm thành công mà không bị lỗi TTY error.
3. **Lưu và Thoát:**
- Nếu bạn dùng trình soạn thảo `nano`: Nhấn `Ctrl + O` -> nhấn `Enter` để lưu, sau đó bấm `Ctrl + X` để thoát.
- - Hệ thống sẽ hiển thị thông báo `crontab: installing new crontab`.
-4. **Kiểm tra trạng thái:**
- Chạy lệnh sau để hiển thị danh sách các cron job đang hoạt động trên user đó:
+---
+
+## TRƯỜNG HỢP 2: Chạy trực tiếp trên Ubuntu Host (Nếu deploy dạng truyền thống)
+
+Nếu bạn cấu hình chạy PHP và Web Server (Nginx/Apache) trực tiếp trên Ubuntu mà không qua Docker.
+
+### Các bước thiết lập:
+
+1. **Mở cấu hình Crontab:**
+ Truy cập terminal của Ubuntu Server dưới quyền của user chạy Web (thường là `www-data` hoặc user deploy) và chạy lệnh:
+ ```bash
+ crontab -e
+ ```
+
+2. **Thêm cấu hình chạy Laravel Scheduler:**
+ Thêm dòng dưới đây vào cuối file crontab:
+ ```bash
+ * * * * * cd /đường-dẫn-đến-thư-mục-dự-án && php artisan schedule:run >> /dev/null 2>&1
+ ```
+ *Lưu ý:* Thay `/đường-dẫn-đến-thư-mục-dự-án` bằng đường dẫn tuyệt đối đến thư mục chứa dự án.
+
+3. **Lưu và Thoát.**
+
+---
+
+## Hướng dẫn kiểm tra trạng thái Cron Job
+
+1. **Xem danh sách cron job đang hoạt động:**
```bash
crontab -l
```
+
+2. **Kiểm tra danh sách các tác vụ đã lên lịch trong Laravel:**
+ ```bash
+ # Nếu dùng Docker:
+ docker compose -f docker/docker-compose.yml exec -T app php artisan schedule:list
+
+ # Nếu không dùng Docker:
+ php artisan schedule:list
+ ```
+
+3. **Chạy thử scheduler ngay lập tức bằng tay để kiểm thử:**
+ ```bash
+ # Nếu dùng Docker:
+ docker compose -f docker/docker-compose.yml exec -T app php artisan schedule:run
+
+ # Nếu không dùng Docker:
+ php artisan schedule:run
+ ```
diff --git a/resources/views/components/user-avatar-section.blade.php b/resources/views/components/user-avatar-section.blade.php
index 9275ee6..fc7bcd4 100644
--- a/resources/views/components/user-avatar-section.blade.php
+++ b/resources/views/components/user-avatar-section.blade.php
@@ -4,13 +4,16 @@
-
-
-
- @error('avatar'){{ $message }}@enderror
-
+ @if($mode !== 'edit')
+
+
+
+ @error('avatar'){{ $message }}@enderror
+
+ @endif
+@if($mode !== 'edit')
@once
@push('scripts')
@endpush
@endonce
+@endif
diff --git a/resources/views/components/user-form.blade.php b/resources/views/components/user-form.blade.php
index 0f5da09..d6f1469 100644
--- a/resources/views/components/user-form.blade.php
+++ b/resources/views/components/user-form.blade.php
@@ -69,11 +69,6 @@
Bạn có chắc chắn muốn cho nhân viên {{ $user->msnv }} nghỉ việc không? Tài khoản này sẽ không thể đăng nhập hoặc thực hiện các giao dịch thẻ sau khi xác nhận.