diff --git a/app/Http/Controllers/Admin/BasicSettings/MachineSettingController.php b/app/Http/Controllers/Admin/BasicSettings/MachineSettingController.php index 954e064..a000c1c 100644 --- a/app/Http/Controllers/Admin/BasicSettings/MachineSettingController.php +++ b/app/Http/Controllers/Admin/BasicSettings/MachineSettingController.php @@ -25,7 +25,7 @@ class MachineSettingController extends AdminController public function index(Request $request): View { $tab = $request->input('tab', 'machines'); - $per_page = $request->input('per_page', 20); + $per_page = $request->input('per_page', 10); $search = $request->input('search'); // 1. 處理機台清單 (Machines Tab) @@ -36,14 +36,14 @@ class MachineSettingController extends AdminController ->orWhere('serial_no', 'like', "%{$search}%"); }); } - $machines = $machineQuery->latest()->paginate($per_page, ['*'], 'machines_page')->withQueryString(); + $machines = $machineQuery->latest()->paginate($per_page)->withQueryString(); // 2. 處理型號清單 (Models Tab) $modelQuery = MachineModel::query()->withCount('machines'); if ($tab === 'models' && $search) { $modelQuery->where('name', 'like', "%{$search}%"); } - $models_list = $modelQuery->latest()->paginate($per_page, ['*'], 'models_page')->withQueryString(); + $models_list = $modelQuery->latest()->paginate($per_page)->withQueryString(); // 3. 基礎下拉資料 (用於新增/編輯機台的彈窗) $models = MachineModel::select('id', 'name')->get(); diff --git a/app/Http/Controllers/Admin/CompanyController.php b/app/Http/Controllers/Admin/CompanyController.php index b1e3c14..67f213e 100644 --- a/app/Http/Controllers/Admin/CompanyController.php +++ b/app/Http/Controllers/Admin/CompanyController.php @@ -133,10 +133,32 @@ class CompanyController extends Controller ]); $company->update($validated); + + // 分支邏輯:若停用客戶,連帶停用其所有帳號 + if ($validated['status'] == 0) { + $company->users()->update(['status' => 0]); + } return redirect()->back()->with('success', __('Customer updated successfully.')); } + /** + * 切換客戶狀態 + */ + public function toggleStatus(Company $company) + { + $newStatus = $company->status == 1 ? 0 : 1; + $company->update(['status' => $newStatus]); + + // 若切換為停用,同步更新所有旗下帳號 + if ($newStatus == 0) { + $company->users()->update(['status' => 0]); + return redirect()->back()->with('success', __('Customer and associated accounts disabled successfully.')); + } + + return redirect()->back()->with('success', __('Customer enabled successfully.')); + } + /** * Remove the specified resource from storage. */ diff --git a/app/Http/Controllers/Admin/MachineController.php b/app/Http/Controllers/Admin/MachineController.php index fc6ff52..e42fc23 100644 --- a/app/Http/Controllers/Admin/MachineController.php +++ b/app/Http/Controllers/Admin/MachineController.php @@ -14,7 +14,7 @@ class MachineController extends AdminController public function index(Request $request): View { $tab = $request->input('tab', 'list'); - $per_page = $tab === 'list' ? $request->input('per_page', 10) : $request->input('per_page', 12); + $per_page = $request->input('per_page', 10); $query = Machine::query(); @@ -73,7 +73,7 @@ class MachineController extends AdminController */ public function logsAjax(Request $request, Machine $machine) { - $per_page = $request->input('per_page', 20); + $per_page = $request->input('per_page', 10); $startDate = $request->get('start_date', now()->format('Y-m-d')); $endDate = $request->get('end_date', now()->format('Y-m-d')); diff --git a/app/Http/Controllers/Admin/MaintenanceController.php b/app/Http/Controllers/Admin/MaintenanceController.php index 761d726..bcbba15 100644 --- a/app/Http/Controllers/Admin/MaintenanceController.php +++ b/app/Http/Controllers/Admin/MaintenanceController.php @@ -73,6 +73,7 @@ class MaintenanceController extends Controller 'content' => 'nullable|string', 'maintenance_at' => 'required|date', 'photos.*' => 'nullable|image|max:5120', // 每張上限 5MB + 'is_confirmed' => 'required|accepted', ]); $machine = Machine::findOrFail($validated['machine_id']); @@ -97,6 +98,7 @@ class MaintenanceController extends Controller 'content' => $validated['content'], 'photos' => $photoPaths, 'maintenance_at' => $validated['maintenance_at'], + 'is_confirmed' => true, // 既然通過驗證(accepted),則存為 true ]); return redirect()->route('admin.maintenance.index') diff --git a/app/Http/Controllers/Admin/PermissionController.php b/app/Http/Controllers/Admin/PermissionController.php index e99fab8..84c9c2f 100644 --- a/app/Http/Controllers/Admin/PermissionController.php +++ b/app/Http/Controllers/Admin/PermissionController.php @@ -503,4 +503,20 @@ class PermissionController extends Controller return redirect()->back()->with('success', __('Account deleted successfully.')); } + + public function toggleAccountStatus($id) + { + $user = \App\Models\System\User::findOrFail($id); + + // 禁止切換 Super Admin 狀態 + if ($user->hasRole('super-admin')) { + return back()->with('error', __('Cannot change Super Admin status.')); + } + + $user->status = $user->status ? 0 : 1; + $user->save(); + + $statusText = $user->status ? __('Enabled') : __('Disabled'); + return back()->with('success', __('Account :name status has been changed to :status.', ['name' => $user->name, 'status' => $statusText])); + } } diff --git a/app/Models/Machine/MaintenanceRecord.php b/app/Models/Machine/MaintenanceRecord.php index 3373d7a..e659021 100644 --- a/app/Models/Machine/MaintenanceRecord.php +++ b/app/Models/Machine/MaintenanceRecord.php @@ -21,11 +21,13 @@ class MaintenanceRecord extends Model 'content', 'photos', 'maintenance_at', + 'is_confirmed', ]; protected $casts = [ 'photos' => 'array', 'maintenance_at' => 'datetime', + 'is_confirmed' => 'boolean', ]; public function machine() diff --git a/database/migrations/2026_03_25_163935_add_is_confirmed_to_maintenance_records_table.php b/database/migrations/2026_03_25_163935_add_is_confirmed_to_maintenance_records_table.php new file mode 100644 index 0000000..2a4b5fc --- /dev/null +++ b/database/migrations/2026_03_25_163935_add_is_confirmed_to_maintenance_records_table.php @@ -0,0 +1,28 @@ +boolean('is_confirmed')->default(false)->after('photos')->comment('已確認告知客戶並簽名'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('maintenance_records', function (Blueprint $table) { + $table->dropColumn('is_confirmed'); + }); + } +}; diff --git a/lang/en.json b/lang/en.json index 89df739..4bacf5d 100644 --- a/lang/en.json +++ b/lang/en.json @@ -691,5 +691,14 @@ "user": "一般用戶", "vs Yesterday": "vs Yesterday", "warehouses": "Warehouse Management", - "待填寫": "Pending" -} \ No newline at end of file + "待填寫": "Pending", + "Enabled": "Enabled", + "Account :name status has been changed to :status.": "Account :name status has been changed to :status.", + "Cannot change Super Admin status.": "Cannot change Super Admin status.", + "Confirm Status Change": "Confirm Status Change", + "Are you sure you want to change the status? This may affect associated accounts.": "Are you sure you want to change the status? This may affect associated accounts.", + "Confirm Account Status Change": "Confirm Account Status Change", + "Are you sure you want to change the status? After disabling, this account will no longer be able to log in to the system.": "Are you sure you want to change the status? After disabling, this account will no longer be able to log in to the system.", + "Confirm Account Deactivation": "Confirm Deactivation", + "Are you sure you want to deactivate this account? After deactivating, this account will no longer be able to log in to the system.": "Are you sure you want to deactivate this account? After deactivating, this account will no longer be able to log in to the system." +} diff --git a/lang/ja.json b/lang/ja.json index 7e69553..5aee933 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -692,5 +692,14 @@ "user": "一般用戶", "vs Yesterday": "前日比", "warehouses": "倉庫管理", - "待填寫": "待填寫" -} \ No newline at end of file + "待填寫": "待填寫", + "Enabled": "有効中", + "Account :name status has been changed to :status.": "アカウント :name のステータスが :status に変更されました。", + "Cannot change Super Admin status.": "スーパー管理者のステータスは変更できません。", + "Confirm Status Change": "ステータス変更の確認", + "Are you sure you want to change the status? This may affect associated accounts.": "ステータスを変更してもよろしいですか?関連するアカウントに影響する可能性があります。", + "Confirm Account Status Change": "アカウントステータス変更の確認", + "Are you sure you want to change the status? After disabling, this account will no longer be able to log in to the system.": "ステータスを変更してもよろしいですか?無効化後、このアカウントはシステムにログインできなくなります。", + "Confirm Account Deactivation": "アカウント停止の確認", + "Are you sure you want to deactivate this account? After deactivating, this account will no longer be able to log in to the system.": "アカウントを停止してもよろしいですか?一旦停止するとシステムにログインできなくなります。" +} diff --git a/lang/zh_TW.json b/lang/zh_TW.json index dcc95e9..27e4f5e 100644 --- a/lang/zh_TW.json +++ b/lang/zh_TW.json @@ -688,5 +688,14 @@ "user": "一般用戶", "vs Yesterday": "較昨日", "warehouses": "倉庫管理", - "待填寫": "待填寫" -} \ No newline at end of file + "待填寫": "待填寫", + "Enabled": "已啟用", + "Account :name status has been changed to :status.": "帳號 :name 的狀態已變更為 :status。", + "Cannot change Super Admin status.": "無法變更超級管理員的狀態。", + "Confirm Status Change": "確認變更狀態", + "Are you sure you want to change the status? This may affect associated accounts.": "您確定要變更狀態嗎?這可能會影響相關帳號的權限效力。", + "Confirm Account Status Change": "帳號狀態變更確認", + "Are you sure you want to change the status? After disabling, this account will no longer be able to log in to the system.": "您確定要變更狀態嗎?停用之後,該帳號將會立即被登出且無法再登入系統。", + "Confirm Account Deactivation": "停用帳號確認", + "Are you sure you want to deactivate this account? After deactivating, this account will no longer be able to log in to the system.": "確定要停用此帳號嗎?停用後將無法登入系統。" +} diff --git a/lang/zh_TW/validation.php b/lang/zh_TW/validation.php index 8d30243..4dc36c2 100644 --- a/lang/zh_TW/validation.php +++ b/lang/zh_TW/validation.php @@ -179,8 +179,8 @@ return [ */ 'custom' => [ - 'attribute-name' => [ - 'rule-name' => 'custom-message', + 'is_confirmed' => [ + 'accepted' => '您必須勾選確認已告知客戶並取得簽名。', ], ], @@ -202,6 +202,11 @@ return [ 'current_password' => '目前密碼', 'password_confirmation' => '確認密碼', 'phone' => '電話', + 'machine_id' => '機台', + 'category' => '類別', + 'maintenance_at' => '維修日期', + 'content' => '維修內容', + 'is_confirmed' => '確認勾選框', ], ]; diff --git a/resources/views/admin/companies/index.blade.php b/resources/views/admin/companies/index.blade.php index 6a8aad7..f58b19a 100644 --- a/resources/views/admin/companies/index.blade.php +++ b/resources/views/admin/companies/index.blade.php @@ -24,10 +24,22 @@ openEditModal(company) { this.editing = true; this.currentCompany = { ...company }; + this.originalStatus = company.status; this.showModal = true; }, isDeleteConfirmOpen: false, - deleteFormAction: '' + deleteFormAction: '', + isStatusConfirmOpen: false, + originalStatus: 1, + toggleFormAction: '', + statusToggleSource: 'edit', + submitConfirmedForm() { + if (this.statusToggleSource === 'list') { + this.$refs.statusToggleForm.submit(); + } else { + this.$refs.companyForm.submit(); + } + } }">
@@ -148,7 +160,7 @@ @else + class="inline-flex items-center px-3 py-1 rounded-full text-[11px] font-black bg-rose-500/10 text-rose-500 border border-rose-500/20 tracking-widest uppercase"> {{ __('Disabled') }} @endif @@ -174,7 +186,26 @@
- + @else + + @endif +
+ method="POST" class="space-y-6" + @submit.prevent=" + if (editing && currentCompany.status == '0' && originalStatus == '1') { + isStatusConfirmOpen = true; + } else { + $el.submit(); + } + "> @csrf @@ -405,6 +444,12 @@
+ + + + @csrf + @method('PATCH') + @endsection \ No newline at end of file diff --git a/resources/views/admin/data-config/accounts.blade.php b/resources/views/admin/data-config/accounts.blade.php index 574518e..fb2f4c5 100644 --- a/resources/views/admin/data-config/accounts.blade.php +++ b/resources/views/admin/data-config/accounts.blade.php @@ -182,13 +182,12 @@ $roleSelectConfig = [ @if($user->status) - + class="inline-flex items-center px-2.5 py-1 rounded-lg text-xs font-bold bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/20 tracking-widest uppercase"> {{ __('Active') }} @else + class="inline-flex items-center px-2.5 py-1 rounded-lg text-xs font-bold bg-rose-500/10 text-rose-600 dark:text-rose-400 border border-rose-500/20 tracking-widest uppercase"> {{ __('Disabled') }} @endif @@ -196,6 +195,25 @@ $roleSelectConfig = [
@if(!$user->hasRole('super-admin')) + @if($user->status) + + @else + + @endif
-
@csrf @@ -594,6 +612,13 @@ $roleSelectConfig = [ + + + + + @csrf + @method('PATCH') + @endsection @@ -617,6 +642,9 @@ $roleSelectConfig = [ roleSelectConfig: initData.roleSelectConfig, isDeleteConfirmOpen: false, deleteFormAction: '', + isStatusConfirmOpen: false, + toggleFormAction: '', + statusToggleSource: 'list', confirmDelete(action) { this.deleteFormAction = action; this.isDeleteConfirmOpen = true; @@ -701,6 +729,13 @@ $roleSelectConfig = [ this.saving = false; } }, + submitConfirmedForm() { + if (this.statusToggleSource === 'list') { + this.$refs.statusToggleForm.submit(); + } else { + this.$refs.accountForm.submit(); + } + }, get filteredRoles() { const companyId = this.currentUser.company_id; if (!companyId || companyId.toString().trim() === '') { diff --git a/resources/views/admin/maintenance/create.blade.php b/resources/views/admin/maintenance/create.blade.php index e446de4..25d8704 100644 --- a/resources/views/admin/maintenance/create.blade.php +++ b/resources/views/admin/maintenance/create.blade.php @@ -35,7 +35,55 @@ @endif -
+ @csrf
@@ -65,11 +113,14 @@ @foreach($machines as $m) - @endforeach + @error('machine_id') +

{{ $message }}

+ @enderror
@endif @@ -80,45 +131,37 @@
@foreach(['Repair', 'Installation', 'Removal', 'Maintenance'] as $cat) -
+ @error('category') +

{{ $message }}

+ @enderror
- + + @error('maintenance_at') +

{{ $message }}

+ @enderror
- + + @error('content') +

{{ $message }}

+ @enderror
-
+

{{ __('Maintenance Photos') }} ({{ __('Max 3') }})