mirror of
https://github.com/ProxyPanel/ProxyPanel.git
synced 2026-04-02 10:39:56 +00:00
Unify Form Value Persistence on Reload
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -22,3 +22,7 @@ _ide_helper_models.php
|
||||
composer.lock
|
||||
.prettierrc
|
||||
package-lock.json
|
||||
/.junie
|
||||
/public/build
|
||||
/.lingma
|
||||
.tongyiignore
|
||||
|
||||
@@ -79,59 +79,35 @@ class ReportController extends Controller
|
||||
|
||||
// 处理今天的数据
|
||||
if ($hourlyDate->isToday() || $endDate->isToday()) {
|
||||
$todayHoursFlow = $user->hourlyDataFlows()
|
||||
->whereNotNull('node_id')
|
||||
->whereDate('created_at', $currentTime)
|
||||
->with('node:id,name')
|
||||
->selectRaw('node_id, HOUR(created_at) as hour, u + d as total')
|
||||
->get();
|
||||
$todayHoursFlow = $user->hourlyDataFlows()->whereNotNull('node_id')->whereDate('created_at', $currentTime)->with('node:id,name')->selectRaw('node_id, HOUR(created_at) as hour, u + d as total')->get();
|
||||
|
||||
$currentHourFlow = $user->dataFlowLogs()
|
||||
->where('log_time', '>=', $currentTime->startOfHour()->timestamp)
|
||||
->with('node:id,name')
|
||||
->groupBy('node_id')
|
||||
->selectRaw('node_id, ? as hour, sum(u + d) as total', [$currentTime->hour])
|
||||
->get();
|
||||
$currentHourFlow = $user->dataFlowLogs()->where('log_time', '>=', $currentTime->startOfHour()->timestamp)->with('node:id,name')->groupBy('node_id')->selectRaw('node_id, ? as hour, sum(u + d) as total', [$currentTime->hour])->get();
|
||||
|
||||
$todayData = $todayHoursFlow->concat($currentHourFlow)
|
||||
->groupBy('node_id')
|
||||
->map(function ($items) use ($mapFlow) {
|
||||
$hourlyData = $items->mapWithKeys(fn ($item) => [$item->hour => $mapFlow($item)]);
|
||||
$totalFlow = $items->sum('total');
|
||||
$todayData = $todayHoursFlow->concat($currentHourFlow)->groupBy('node_id')->map(function ($items) use ($mapFlow) {
|
||||
$hourlyData = $items->mapWithKeys(fn ($item) => [$item->hour => $mapFlow($item)]);
|
||||
$totalFlow = $items->sum('total');
|
||||
|
||||
return [
|
||||
'hourly' => $hourlyData,
|
||||
'daily' => $mapFlow((object) [
|
||||
'node_id' => $items->first()->node_id,
|
||||
'node' => $items->first()->node,
|
||||
'created_at' => Carbon::today(),
|
||||
'total' => $totalFlow,
|
||||
], 'date'),
|
||||
];
|
||||
});
|
||||
return [
|
||||
'hourly' => $hourlyData,
|
||||
'daily' => $mapFlow((object) [
|
||||
'node_id' => $items->first()->node_id,
|
||||
'node' => $items->first()->node,
|
||||
'created_at' => Carbon::today(),
|
||||
'total' => $totalFlow,
|
||||
], 'date'),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
// 处理小时数据
|
||||
if ($todayData && $hourlyDate->isToday()) {
|
||||
$hourlyFlows = $todayData->flatMap(fn ($item) => $item['hourly'])->values();
|
||||
} else {
|
||||
$hourlyFlows = $user->hourlyDataFlows()
|
||||
->whereNotNull('node_id')
|
||||
->whereDate('created_at', $hourlyDate)
|
||||
->with('node:id,name')
|
||||
->selectRaw('node_id, HOUR(created_at) as hour, u + d as total')
|
||||
->get()
|
||||
->map(fn ($item) => $mapFlow($item));
|
||||
$hourlyFlows = $user->hourlyDataFlows()->whereNotNull('node_id')->whereDate('created_at', $hourlyDate)->with('node:id,name')->selectRaw('node_id, HOUR(created_at) as hour, u + d as total')->get()->map(fn ($item) => $mapFlow($item));
|
||||
}
|
||||
|
||||
// 处理每日数据
|
||||
$dailyFlows = $user->dailyDataFlows()
|
||||
->whereNotNull('node_id')
|
||||
->whereBetween('created_at', [$startDate, $endDate])
|
||||
->with('node:id,name')
|
||||
->selectRaw('node_id, DATE_FORMAT(created_at, "%m-%d") as date, u + d as total')
|
||||
->get()
|
||||
->map(fn ($item) => $mapFlow($item, 'date'));
|
||||
$dailyFlows = $user->dailyDataFlows()->whereNotNull('node_id')->whereBetween('created_at', [$startDate, $endDate])->with('node:id,name')->selectRaw('node_id, DATE_FORMAT(created_at, "%m-%d") as date, u + d as total')->get()->map(fn ($item) => $mapFlow($item, 'date'));
|
||||
|
||||
if ($todayData && $endDate->isToday()) {
|
||||
$dailyFlows = $dailyFlows->concat($todayData->map(fn ($item) => $item['daily']));
|
||||
@@ -143,10 +119,7 @@ class ReportController extends Controller
|
||||
'nodes' => $hourlyFlows->concat($dailyFlows)->pluck('name', 'id')->unique()->toArray(),
|
||||
'hourlyFlows' => $hourlyFlows->toArray(),
|
||||
'dailyFlows' => $dailyFlows->toArray(),
|
||||
'hour_dates' => UserHourlyDataFlow::selectRaw('DISTINCT DATE(created_at) as date')
|
||||
->orderByDesc('date')
|
||||
->pluck('date')
|
||||
->toArray(),
|
||||
'hour_dates' => UserHourlyDataFlow::selectRaw('DISTINCT DATE(created_at) as date')->orderByDesc('date')->pluck('date')->toArray(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -258,7 +231,7 @@ class ReportController extends Controller
|
||||
$nodeId = $request->input('node_id');
|
||||
$nodes = Node::orderBy('name')->pluck('name', 'id');
|
||||
|
||||
// Fetch flows
|
||||
// 获取流量数据
|
||||
$flows = NodeDailyDataFlow::whereNodeId($nodeId)->selectRaw('DATE(created_at) as date, sum(u + d) as total')->groupBy('date')->get()->keyBy('date');
|
||||
|
||||
$dailyFlows = $flows->filter(fn ($flow) => $flow->date >= now()->subMonthNoOverflow()->startOfMonth()->toDateString())->pluck('total', 'date');
|
||||
@@ -276,7 +249,6 @@ class ReportController extends Controller
|
||||
$trafficData = NodeDailyDataFlow::where('node_id', $nodeId)->where('created_at', '>=', $thirtyDaysAgo)->selectRaw('SUM(u + d) as total, COUNT(*) as dataCounts')->first();
|
||||
|
||||
$total30Days = $trafficData->total ?? 0;
|
||||
|
||||
$daysWithData = max($trafficData->dataCounts ?? 0, 1);
|
||||
$months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
||||
|
||||
|
||||
@@ -290,3 +290,28 @@ function collectFormData(formSelector, options = {}) {
|
||||
};
|
||||
})(jQuery);
|
||||
|
||||
/**
|
||||
* 从URL查询参数中提取数据并填充表单
|
||||
* @param {Object} options - 配置选项
|
||||
* @param {string} options.formSelector - 表单选择器,默认为 'form'
|
||||
* @param {Array} options.skipFields - 跳过的字段名
|
||||
*/
|
||||
function populateFormFromQueryParams(options = {}) {
|
||||
// 将URL查询参数转换为对象
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const data = {};
|
||||
|
||||
for (const [key, value] of urlParams.entries()) {
|
||||
if (key.endsWith('[]')) {
|
||||
if (!data.hasOwnProperty(key)) {
|
||||
data[key] = [];
|
||||
}
|
||||
data[key].push(value);
|
||||
} else {
|
||||
data[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用现有的 autoPopulateForm 函数填充表单
|
||||
autoPopulateForm(data, options);
|
||||
}
|
||||
|
||||
@@ -341,13 +341,7 @@
|
||||
window.location.href = `${window.location.pathname}?${urlParams.toString()}`;
|
||||
};
|
||||
|
||||
const resetSearchForm = () => {
|
||||
window.location.href = window.location.href.split("?")[0];
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
initCharts();
|
||||
|
||||
const hourDateSelect = document.getElementById("hour_date");
|
||||
if (hourDateSelect) {
|
||||
hourDateSelect.addEventListener("change", (event) => handleFormSubmit(event, event.target.form));
|
||||
@@ -356,8 +350,14 @@
|
||||
|
||||
$(".input-daterange").datepicker({
|
||||
startDate: nodeData.start_date,
|
||||
endDate: new Date()
|
||||
endDate: new Date(),
|
||||
language: document.documentElement.lang || 'en',
|
||||
autoclose: true,
|
||||
todayHighlight: true
|
||||
});
|
||||
|
||||
populateFormFromQueryParams();
|
||||
initCharts();
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
});
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#node_id').val({{ Request::query('node_id') }});
|
||||
populateFormFromQueryParams();
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="card card-shadow">
|
||||
<div class="card-block p-30">
|
||||
<form class="form-row" onsubmit="handleFormSubmit(event, this);">
|
||||
<x-admin.filter.input class="col-md-1 col-sm-4" name="uid" type="number" :placeholder="trans('model.user.id')" />
|
||||
<x-admin.filter.input class="col-lg-1 col-md-2 col-sm-4" name="uid" type="number" :placeholder="trans('model.user.id')" />
|
||||
<x-admin.filter.input class="col-xxl-2 col-md-3 col-sm-4" name="username" :placeholder="trans('model.user.username')" />
|
||||
<div class="form-group col-xxl-1 col-md-3 col-4 btn-group">
|
||||
<button class="btn btn-primary" type="submit">{{ trans('common.search') }}</button>
|
||||
@@ -220,10 +220,6 @@
|
||||
window.location.href = `${window.location.pathname}?${urlParams.toString()}`;
|
||||
};
|
||||
|
||||
const resetSearchForm = () => {
|
||||
window.location.href = window.location.href.split("?")[0];
|
||||
};
|
||||
|
||||
const initCharts = () => {
|
||||
if (userData && Object.keys(userData).length > 2) {
|
||||
const nodeColorMap = generateNodeColorMap(userData.nodes);
|
||||
@@ -241,13 +237,14 @@
|
||||
|
||||
$(".input-daterange").datepicker({
|
||||
startDate: userData.start_date,
|
||||
endDate: new Date()
|
||||
endDate: new Date(),
|
||||
language: document.documentElement.lang || 'en',
|
||||
autoclose: true,
|
||||
todayHighlight: true
|
||||
});
|
||||
|
||||
populateFormFromQueryParams();
|
||||
initCharts();
|
||||
});
|
||||
|
||||
window.handleFormSubmit = handleFormSubmit;
|
||||
window.resetSearchForm = resetSearchForm;
|
||||
</script>
|
||||
@endsection
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
<script src="/assets/global/vendor/bootstrap-select/bootstrap-select.min.js"></script>
|
||||
<script src="/assets/global/js/Plugin/bootstrap-select.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
populateFormFromQueryParams();
|
||||
});
|
||||
|
||||
$("form:not(.modal-body form)").on("submit", function() {
|
||||
$(this).find("input:not([type=\"submit\"]), select").filter(function() {
|
||||
return this.value === "";
|
||||
@@ -37,29 +41,6 @@
|
||||
$(this).closest("form").trigger("submit");
|
||||
});
|
||||
|
||||
function autoInitSelectpickers() {
|
||||
$('select[data-plugin="selectpicker"]').each(function() {
|
||||
const $select = $(this);
|
||||
const fieldName = $select.attr('name').replace('[]', ''); // 处理多选字段
|
||||
const queryValue = getUrlParameter(fieldName);
|
||||
|
||||
if (queryValue) {
|
||||
$select.selectpicker("val", queryValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取 URL 参数的辅助函数
|
||||
function getUrlParameter(name) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get(name);
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
autoInitSelectpickers();
|
||||
});
|
||||
|
||||
|
||||
// 使用事件委托处理所有删除按钮点击
|
||||
document.addEventListener('click', function(e) {
|
||||
// 检查被点击的元素是否是删除按钮或包含在删除按钮内
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@props(['class' => '', 'type' => 'text', 'name', 'value' => Request::query($name), 'placeholder' => null])
|
||||
@props(['class' => '', 'type' => 'text', 'name', 'value' => null, 'placeholder' => null])
|
||||
|
||||
<div class="form-group {{ $class }}">
|
||||
<input class="form-control" name="{{ $name }}" type="{{ $type }}" value="{{ $value }}" placeholder="{{ $placeholder }}"
|
||||
|
||||
Reference in New Issue
Block a user