Files
chatroom/resources/views/admin/currency-logs/index.blade.php
T

264 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends('admin.layouts.app')
@section('title', '金币/积分流水查询')
@section('content')
@php
require resource_path('views/admin/partials/list-theme.php');
$selectedSourceCount = count($selectedSources ?? []);
@endphp
<div class="{{ $adminListHeaderCardClass }} mb-6">
<div class="{{ $adminListFilterInnerClass }}">
<form action="{{ route('admin.currency-logs.index') }}" method="GET"
class="flex flex-wrap items-end gap-3 2xl:grid 2xl:grid-cols-[minmax(120px,1fr)_8rem_8rem_minmax(160px,1.1fr)_minmax(160px,1.15fr)_9rem_9rem_auto] 2xl:items-end"
data-admin-auto-filter-form>
<div class="min-w-[120px] flex-1">
<label for="username" class="{{ $adminListFilterLabelClass }}">用户名</label>
<input type="text" name="username" id="username" value="{{ request('username') }}"
class="w-full {{ $adminListFilterInputClass }}" data-auto-submit="input"
placeholder="选填">
</div>
<div class="w-32 shrink-0">
<label for="currency" class="{{ $adminListFilterLabelClass }}">货币类型</label>
<select name="currency" id="currency"
class="w-full {{ $adminListFilterInputClass }}" data-auto-submit="change">
<option value="">全部</option>
<option value="gold" {{ request('currency') == 'gold' ? 'selected' : '' }}>💰 金币</option>
<option value="exp" {{ request('currency') == 'exp' ? 'selected' : '' }}> 经验</option>
<option value="charm" {{ request('currency') == 'charm' ? 'selected' : '' }}>💖 魅力</option>
</select>
</div>
<div class="w-32 shrink-0">
<label for="direction" class="{{ $adminListFilterLabelClass }}">变动方向</label>
<select name="direction" id="direction"
class="w-full {{ $adminListFilterInputClass }}" data-auto-submit="change">
<option value="">全部</option>
<option value="in" {{ request('direction') == 'in' ? 'selected' : '' }}> 增加</option>
<option value="out" {{ request('direction') == 'out' ? 'selected' : '' }}> 扣除</option>
</select>
</div>
<div class="min-w-[160px] flex-[1.15]">
<label class="{{ $adminListFilterLabelClass }}">来源途径</label>
<details class="relative" data-admin-source-filter>
<summary
class="{{ $adminListFilterInputClass }} flex cursor-pointer list-none items-center justify-between bg-white">
<span class="truncate">{{ $selectedSourceCount > 0 ? '已选 '.$selectedSourceCount.' 项' : '全部来源' }}</span>
<svg class="h-4 w-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
</svg>
</summary>
<div class="absolute left-0 z-20 mt-2 flex w-full min-w-[220px] max-w-sm flex-col rounded-xl border border-gray-200 bg-white shadow-lg">
<div class="grid max-h-64 gap-1 overflow-y-auto p-3">
@foreach ($allSources as $src)
<label class="flex items-center gap-2 rounded-md px-2 py-1.5 text-sm text-gray-700 hover:bg-gray-50">
<input type="checkbox" name="sources[]" value="{{ $src->value }}"
class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
@checked(in_array($src->value, $selectedSources ?? [], true))>
<span class="truncate" title="{{ $src->label() }}">{{ $src->label() }}</span>
</label>
@endforeach
</div>
<div class="sticky bottom-0 flex items-center justify-between border-t border-gray-100 bg-white px-3 py-3">
<a href="{{ route('admin.currency-logs.index', request()->except('sources')) }}"
class="{{ $adminListSecondaryTextClass }} hover:text-gray-600">清空来源</a>
<span class="text-xs text-gray-400">勾选后点查询生效</span>
</div>
</div>
</details>
</div>
<div class="min-w-[160px] flex-[1.15]">
<label for="remark" class="{{ $adminListFilterLabelClass }}">备注/房间流水</label>
<input type="text" name="remark" id="remark" value="{{ request('remark') }}"
class="w-full {{ $adminListFilterInputClass }}" data-auto-submit="input"
placeholder="包含(可搜房间名)">
</div>
<div class="w-36 shrink-0">
<label for="date_start" class="{{ $adminListFilterLabelClass }}">开始日期</label>
<input type="date" name="date_start" id="date_start" value="{{ request('date_start') }}"
class="w-full {{ $adminListFilterInputClass }}" data-auto-submit="change">
</div>
<div class="w-36 shrink-0">
<label for="date_end" class="{{ $adminListFilterLabelClass }}">结束日期</label>
<input type="date" name="date_end" id="date_end" value="{{ request('date_end') }}"
class="w-full {{ $adminListFilterInputClass }}" data-auto-submit="change">
</div>
<div class="shrink-0 2xl:ml-0">
<a href="{{ route('admin.currency-logs.index') }}" class="{{ $adminListSecondaryButtonClass }}">
重置
</a>
</div>
</form>
</div>
</div>
<div class="{{ $adminListCardClass }}">
<div class="{{ $adminListTableWrapClass }}">
<table class="{{ $adminListTableClass }} whitespace-nowrap">
<thead>
<tr class="{{ $adminListTableHeadRowClass }}">
<th class="{{ $adminListTableHeadCellClass }}">记录ID</th>
<th class="{{ $adminListTableHeadCellClass }}">用户</th>
<th class="{{ $adminListTableHeadCellClass }}">类型</th>
<th class="{{ $adminListTableHeadCellClass }}">变动数额</th>
<th class="{{ $adminListTableHeadCellClass }}">变后余额</th>
<th class="{{ $adminListTableHeadCellClass }}">来源</th>
<th class="{{ $adminListTableHeadCellClass }} w-1/4">备注信息</th>
<th class="{{ $adminListTableHeadCellClass }} text-right">发生时间</th>
</tr>
</thead>
<tbody class="{{ $adminListTableBodyClass }}">
@forelse ($logs as $log)
<tr class="{{ $adminListTableRowClass }} cursor-default">
<td class="px-6 py-4 {{ $adminListSecondaryTextClass }}">
#{{ $log->id }}
</td>
<td class="px-6 py-4">
<div class="flex flex-col whitespace-nowrap">
<span class="{{ $adminListPrimaryTextClass }}">{{ $log->username }}</span>
</div>
</td>
<td class="px-6 py-4">
@if($log->currency === 'gold')
<span class="inline-flex items-center gap-1 whitespace-nowrap rounded-full bg-yellow-50 px-2 py-0.5 text-xs font-semibold text-yellow-700 ring-1 ring-yellow-200">
<span>💰</span><span>金币</span>
</span>
@elseif($log->currency === 'exp')
<span class="inline-flex items-center gap-1 whitespace-nowrap rounded-full bg-blue-50 px-2 py-0.5 text-xs font-semibold text-blue-700 ring-1 ring-blue-200">
<span></span><span>经验</span>
</span>
@elseif($log->currency === 'charm')
<span class="inline-flex items-center gap-1 whitespace-nowrap rounded-full bg-pink-50 px-2 py-0.5 text-xs font-semibold text-pink-700 ring-1 ring-pink-200">
<span>💖</span><span>魅力</span>
</span>
@else
<span class="{{ $adminListSecondaryTextClass }}">{{ $log->currency }}</span>
@endif
</td>
<td class="px-6 py-4 {{ $adminListNumericTextClass }}">
@if ($log->amount > 0)
<span class="text-emerald-500">+{{ $log->amount }}</span>
@elseif ($log->amount === 0)
<span class="text-gray-500">0</span>
@else
<span class="text-red-500">{{ $log->amount }}</span>
@endif
</td>
<td class="px-6 py-4 {{ $adminListNumericTextClass }} text-gray-700">
{{ $log->balance_after }}
</td>
<td class="px-6 py-4">
@php
$sourceLabel = \App\Enums\CurrencySource::tryFrom($log->source)?->label() ?? $log->source;
@endphp
<span class="inline-flex whitespace-nowrap rounded-full bg-slate-100 px-2 py-0.5 text-xs font-semibold text-slate-700">
{{ $sourceLabel }}
</span>
</td>
<td class="px-6 py-4 {{ $adminListBodyTextClass }}">
{{ $log->remark }}
</td>
<td class="px-6 py-4 {{ $adminListSecondaryTextClass }} text-right whitespace-nowrap">
{{ $log->created_at->format('Y-m-d H:i:s') }}
</td>
</tr>
@empty
<tr>
<td colspan="8" class="{{ $adminListEmptyClass }}">
📭 暂无相关流水记录
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
@if ($logs->hasPages())
<div class="{{ $adminListPaginationClass }}">
{{ $logs->links() }}
</div>
@endif
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
const autoFilterForm = document.querySelector('[data-admin-auto-filter-form]');
const sourceFilter = document.querySelector('[data-admin-source-filter]');
let autoSubmitTimer = null;
const submitAutoFilter = function () {
if (!autoFilterForm) {
return;
}
if (typeof autoFilterForm.requestSubmit === 'function') {
autoFilterForm.requestSubmit();
return;
}
autoFilterForm.submit();
};
if (autoFilterForm) {
autoFilterForm.querySelectorAll('[data-auto-submit="input"]').forEach(function (inputElement) {
inputElement.addEventListener('input', function () {
window.clearTimeout(autoSubmitTimer);
autoSubmitTimer = window.setTimeout(function () {
submitAutoFilter();
}, 450);
});
inputElement.addEventListener('keydown', function (event) {
if (event.key !== 'Enter') {
return;
}
event.preventDefault();
window.clearTimeout(autoSubmitTimer);
submitAutoFilter();
});
});
autoFilterForm.querySelectorAll('[data-auto-submit="change"]').forEach(function (fieldElement) {
fieldElement.addEventListener('change', function () {
window.clearTimeout(autoSubmitTimer);
submitAutoFilter();
});
});
}
if (!sourceFilter) {
return;
}
sourceFilter.querySelectorAll('input[type="checkbox"]').forEach(function (checkboxElement) {
checkboxElement.addEventListener('change', function () {
window.clearTimeout(autoSubmitTimer);
submitAutoFilter();
});
});
document.addEventListener('click', function (event) {
if (!sourceFilter.open) {
return;
}
if (sourceFilter.contains(event.target)) {
return;
}
sourceFilter.removeAttribute('open');
});
});
</script>
@endsection