[FIX] 實作儀表板真實營收統計與多語系修正

1. 修復儀表板營收統計,將模擬數據替換為從 Order 模型撈取的真實資料。
2. 修正 DashboardController 中的支付狀態篩選邏輯,從字串 'paid' 改為正確的 tinyInteger 狀態碼 1。
3. 在 Order 模型中新增 PAYMENT_STATUS_SUCCESS 與 PAYMENT_STATUS_FAILED 常數。
4. 新增「本月累計營收」的多語系翻譯(中、英、日)。
5. 優化儀表板前端介面,包含動態顯示昨日增長趨勢百分比與顏色標籤。
6. 修正儀表板機台列表中的「今日銷售額」統計邏輯。
This commit is contained in:
sky121113 2026-05-06 17:55:18 +08:00
parent 86449ea36a
commit 938aabc6c1
6 changed files with 46 additions and 10 deletions

View File

@ -3,8 +3,10 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Transaction\Order;
use App\Models\Machine\Machine;
use Illuminate\Http\Request;
use Carbon\Carbon;
class DashboardController extends Controller
{
@ -16,12 +18,37 @@ class DashboardController extends Controller
$perPage = 10;
// 從資料庫獲取真實統計數據
$totalRevenue = \App\Models\Member\MemberWallet::sum('balance');
$activeMachines = Machine::online()->count();
$offlineMachines = Machine::offline()->count();
$alertsPending = Machine::hasError()->count();
$memberCount = \App\Models\Member\Member::count();
// 交易營收統計 (真實數據)
$todayRevenue = Order::where('payment_status', Order::PAYMENT_STATUS_SUCCESS)
->whereDate('payment_at', Carbon::today())
->sum('pay_amount');
$yesterdayRevenue = Order::where('payment_status', Order::PAYMENT_STATUS_SUCCESS)
->whereDate('payment_at', Carbon::yesterday())
->sum('pay_amount');
$dayBeforeRevenue = Order::where('payment_status', Order::PAYMENT_STATUS_SUCCESS)
->whereDate('payment_at', Carbon::yesterday()->subDay())
->sum('pay_amount');
$monthlyRevenue = Order::where('payment_status', Order::PAYMENT_STATUS_SUCCESS)
->whereMonth('payment_at', Carbon::now()->month)
->whereYear('payment_at', Carbon::now()->year)
->sum('pay_amount');
// 計算昨日增長趨勢 (百分比)
$yesterdayTrend = 0;
if ($yesterdayRevenue > 0) {
$yesterdayTrend = (($todayRevenue - $yesterdayRevenue) / $yesterdayRevenue) * 100;
} elseif ($todayRevenue > 0) {
$yesterdayTrend = 100;
}
// 獲取機台列表 (分頁)
$machines = Machine::when($request->search, function ($query, $search) {
$query->where(function ($q) use ($search) {
@ -33,18 +60,22 @@ class DashboardController extends Controller
->withSum('slots', 'max_stock')
->withSum(['orders as today_sales_sum' => function($query) {
$query->whereDate('payment_at', now()->toDateString())
->where('payment_status', 'paid');
->where('payment_status', Order::PAYMENT_STATUS_SUCCESS);
}], 'pay_amount')
->orderByDesc('last_heartbeat_at')
->paginate($perPage)
->withQueryString();
return view('admin.dashboard', compact(
'totalRevenue',
'activeMachines',
'offlineMachines',
'alertsPending',
'memberCount',
'todayRevenue',
'yesterdayRevenue',
'dayBeforeRevenue',
'monthlyRevenue',
'yesterdayTrend',
'machines'
));
}

View File

@ -13,6 +13,10 @@ class Order extends Model
{
use HasFactory, SoftDeletes, TenantScoped;
// 支付狀態
public const PAYMENT_STATUS_FAILED = 0;
public const PAYMENT_STATUS_SUCCESS = 1;
protected $fillable = [
'company_id',
'flow_id',

View File

@ -796,6 +796,7 @@
"Monitor events and system activity across your vending fleet.": "Monitor events and system activity across your vending fleet.",
"Monitor warehouse stock summary": "Monitor warehouse stock summary",
"Monthly Transactions": "Monthly Transactions",
"Monthly Cumulative Revenue": "Monthly Cumulative Revenue",
"Monthly cumulative revenue overview": "Monthly cumulative revenue overview",
"Motor not stopped": "Motor not stopped",
"Movement History": "Movement History",

View File

@ -789,6 +789,7 @@
"Monitor events and system activity across your vending fleet.": "Monitor events and system activity across your vending fleet.",
"Monitor warehouse stock summary": "Monitor warehouse stock summary",
"Monthly Transactions": "Monthly Transactions",
"Monthly Cumulative Revenue": "今月の累計収益",
"Monthly cumulative revenue overview": "Monthly cumulative revenue overview",
"Motor not stopped": "Motor not stopped",
"Movement History": "移動履歴",

View File

@ -895,6 +895,7 @@
"Monitor events and system activity across your vending fleet.": "跨機台連線動態與系統日誌監控。",
"Monitor warehouse stock summary": "監控倉庫庫存摘要",
"Monthly Transactions": "本月交易統計",
"Monthly Cumulative Revenue": "本月累計營收",
"Monthly cumulative revenue overview": "本月累計營收概況",
"Motor not stopped": "電機未停止",
"Movement History": "異動紀錄",

View File

@ -73,7 +73,7 @@
<div>
<h3 class="text-xl font-black text-slate-800 dark:text-white font-display tracking-tight">{{
__('Monthly Transactions') }}</h3>
<p class="text-xs font-bold text-slate-500 dark:text-slate-400 mt-1">{{ __('Monthly cumulative revenue overview') }}</p>
<p class="text-xs font-bold text-slate-500 dark:text-slate-400 mt-1">{{ __('Monthly Cumulative Revenue') }}: <span class="text-cyan-500 font-black">${{ number_format($monthlyRevenue, 0) }}</span></p>
</div>
<div
class="p-2.5 rounded-xl bg-slate-50 dark:bg-slate-800/80 text-slate-400 dark:text-slate-500 border border-transparent dark:border-slate-700/50">
@ -101,12 +101,12 @@
<p class="text-xs font-bold text-slate-500 dark:text-slate-400">{{ __("Today Cumulative Sales") }}</p>
<p
class="text-4xl font-black text-slate-900 dark:text-white mt-1 tracking-tight drop-shadow-sm">
${{ number_format($totalRevenue / 30, 0) }}</p>
${{ number_format($todayRevenue, 0) }}</p>
</div>
</div>
<div class="flex flex-col items-end gap-y-1">
<span
class="text-[10px] font-black text-emerald-500 bg-emerald-500/10 px-2.5 py-0.5 rounded-full">+12.5%</span>
class="text-[10px] font-black {{ $yesterdayTrend >= 0 ? 'text-emerald-500 bg-emerald-500/10' : 'text-rose-500 bg-rose-500/10' }} px-2.5 py-0.5 rounded-full">{{ $yesterdayTrend >= 0 ? '+' : '' }}{{ number_format($yesterdayTrend, 1) }}%</span>
<p class="text-[9px] font-bold text-slate-300 dark:text-slate-500 uppercase tracking-tighter">{{
__('vs Yesterday') }}</p>
</div>
@ -128,8 +128,7 @@
</svg>
</div>
</div>
<p class="text-xl font-black text-slate-800 dark:text-slate-200">${{ number_format($totalRevenue
/ 25, 0) }}</p>
<p class="text-xl font-black text-slate-800 dark:text-slate-200">${{ number_format($yesterdayRevenue, 0) }}</p>
</div>
<!-- Before Yesterday Card -->
@ -146,8 +145,7 @@
</svg>
</div>
</div>
<p class="text-xl font-black text-slate-800 dark:text-slate-200">${{ number_format($totalRevenue
/ 40, 0) }}</p>
<p class="text-xl font-black text-slate-800 dark:text-slate-200">${{ number_format($dayBeforeRevenue, 0) }}</p>
</div>
</div>
</div>