Unify Form Value Persistence on Reload

This commit is contained in:
BrettonYe
2026-01-30 09:41:48 +08:00
parent d1141ac14d
commit bc37f23ea2
8 changed files with 67 additions and 88 deletions

4
.gitignore vendored
View File

@@ -22,3 +22,7 @@ _ide_helper_models.php
composer.lock
.prettierrc
package-lock.json
/.junie
/public/build
/.lingma
.tongyiignore

View File

@@ -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];

View File

@@ -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);
}

View File

@@ -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

View File

@@ -201,7 +201,7 @@
});
$(document).ready(function() {
$('#node_id').val({{ Request::query('node_id') }});
populateFormFromQueryParams();
});
</script>
@endsection

View File

@@ -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

View File

@@ -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) {
// 检查被点击的元素是否是删除按钮或包含在删除按钮内

View File

@@ -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 }}"