160 lines
5.8 KiB
PHP
160 lines
5.8 KiB
PHP
@extends('admin.content')
|
|
|
|
@section('title', '仪表盘')
|
|
|
|
@section('content')
|
|
@php $portal = $portal ?? 'admin'; @endphp
|
|
<style>
|
|
.dash-metric { font-size: 28px; line-height: 1.2; }
|
|
.dash-metric-hl { color: #009688; font-weight: 600; }
|
|
.dash-metric-sep { color: #bbb; margin: 0 4px; font-weight: 400; }
|
|
.dash-metric-total { color: #333; }
|
|
</style>
|
|
<div class="layui-card">
|
|
<form class="layui-form layui-card-header layuiadmin-card-header-auto" lay-filter="LAY-dash-search">
|
|
<div class="layui-form-item">
|
|
<div class="layui-inline">
|
|
<label class="layui-form-label">时间</label>
|
|
<div class="layui-input-block">
|
|
<select name="range">
|
|
<option value="30d" selected>近30天</option>
|
|
<option value="7d">近7天</option>
|
|
<option value="yesterday">昨日</option>
|
|
<option value="today">今日</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="layui-inline">
|
|
<label class="layui-form-label">渠道 ID</label>
|
|
<div class="layui-input-block">
|
|
<input type="text" name="channel_id" placeholder="渠道 ID" autocomplete="off" class="layui-input">
|
|
</div>
|
|
</div>
|
|
@if ($portal === 'admin')
|
|
<div class="layui-inline">
|
|
<label class="layui-form-label">代理用户</label>
|
|
<div class="layui-input-block">
|
|
<select name="agent_user_id">
|
|
<option value="">全部</option>
|
|
@foreach ($agents as $a)
|
|
<option value="{{ $a->id }}">{{ $a->username }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
<div class="layui-inline">
|
|
<button class="layui-btn" lay-submit lay-filter="LAY-dash-search">查询</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<div class="layui-card-body">
|
|
<div class="layui-row layui-col-space15">
|
|
<div class="layui-col-md2">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">总设备数</div>
|
|
<div class="layui-card-body dash-metric" id="dash-total">—</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-col-md2">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">新增设备</div>
|
|
<div class="layui-card-body dash-metric dash-metric-hl" id="dash-new">—</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-col-md2">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">活跃设备</div>
|
|
<div class="layui-card-body dash-metric" id="dash-active">—</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-col-md3">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">页面 PV</div>
|
|
<div class="layui-card-body dash-metric" id="dash-pv">—</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-col-md3">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">页面 UV</div>
|
|
<div class="layui-card-body dash-metric" id="dash-uv">—</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-word-aux" style="margin-top:4px;">有效口径:iOS < 17 且使用 Safari(左侧高亮 / 右侧为全部)</div>
|
|
|
|
<div class="layui-row layui-col-space15" style="margin-top:12px;">
|
|
<div class="layui-col-md6">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">按系统(PV / UV / 占比)</div>
|
|
<div class="layui-card-body">
|
|
<table class="layui-table" lay-size="sm">
|
|
<thead><tr><th>系统</th><th>PV</th><th>UV</th><th>占比</th></tr></thead>
|
|
<tbody id="dash-by-os"><tr><td colspan="4">—</td></tr></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-col-md6">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">按 iOS 系统版本(PV / UV / 占比)</div>
|
|
<div class="layui-card-body">
|
|
<table class="layui-table" lay-size="sm">
|
|
<thead><tr><th>版本</th><th>PV</th><th>UV</th><th>占比</th></tr></thead>
|
|
<tbody id="dash-by-ios-version"><tr><td colspan="4">—</td></tr></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-word-aux" id="dash-range" style="margin-top:8px;"></div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<script>
|
|
layui.use(['form'], function () {
|
|
var form = layui.form;
|
|
var $ = layui.$;
|
|
var dataUrl = @json(route(($portal ?? 'admin').'.dashboard.data'));
|
|
|
|
function fillRows(sel, rows) {
|
|
var html = '';
|
|
(rows || []).forEach(function (r) {
|
|
var pct = (r.pct === undefined || r.pct === null) ? '—' : (r.pct + '%');
|
|
html += '<tr><td>' + (r.label || '—') + '</td><td>' + r.pv + '</td><td>' + r.uv + '</td><td>' + pct + '</td></tr>';
|
|
});
|
|
$(sel).html(html || '<tr><td colspan="4">暂无</td></tr>');
|
|
}
|
|
|
|
function ratioHtml(effective, total) {
|
|
return '<span class="dash-metric-hl">' + effective + '</span>' +
|
|
'<span class="dash-metric-sep">/</span>' +
|
|
'<span class="dash-metric-total">' + total + '</span>';
|
|
}
|
|
|
|
function load(where) {
|
|
$.getJSON(dataUrl, where || { range: '30d' }, function (res) {
|
|
if (!res || res.code !== 0) return;
|
|
$('#dash-total').text(res.data.total);
|
|
$('#dash-new').text(res.data.new_count);
|
|
$('#dash-active').text(res.data.active_count);
|
|
$('#dash-pv').html(ratioHtml(res.data.effective_pv || 0, res.data.pv || 0));
|
|
$('#dash-uv').html(ratioHtml(res.data.effective_uv || 0, res.data.uv || 0));
|
|
fillRows('#dash-by-os', res.data.by_os);
|
|
fillRows('#dash-by-ios-version', res.data.by_ios_version);
|
|
$('#dash-range').text('统计区间:' + res.data.from + ' ~ ' + res.data.to);
|
|
});
|
|
}
|
|
|
|
form.on('submit(LAY-dash-search)', function (data) {
|
|
load(data.field);
|
|
return false;
|
|
});
|
|
|
|
load({ range: '30d' });
|
|
});
|
|
</script>
|
|
@endpush
|