|
@@ -0,0 +1,222 @@
|
|
|
|
|
+@extends('base.base')
|
|
|
|
|
+@section('base')
|
|
|
|
|
+<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
|
|
|
+<div class="container-fluid">
|
|
|
|
|
+ <div class="row">
|
|
|
|
|
+ <div class="col-12">
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <div class="card-header d-flex align-items-center justify-content-between">
|
|
|
|
|
+ <h3 class="card-title mb-0">1234 权重配置 & 点击统计</h3>
|
|
|
|
|
+ <small class="text-muted">配置 1/2/3/4 的权重(整数),前端按权重抽取,后台记录用户点击</small>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card-body">
|
|
|
|
|
+ <ul class="nav nav-tabs mb-3" role="tablist">
|
|
|
|
|
+ <li class="nav-item">
|
|
|
|
|
+ <a class="nav-link active" data-toggle="tab" href="#tab-config" role="tab">
|
|
|
|
|
+ <i class="mdi mdi-cog"></i> 权重配置
|
|
|
|
|
+ </a>
|
|
|
|
|
+ </li>
|
|
|
|
|
+ <li class="nav-item">
|
|
|
|
|
+ <a class="nav-link" data-toggle="tab" href="#tab-stats" role="tab">
|
|
|
|
|
+ <i class="mdi mdi-chart-bar"></i> 点击统计
|
|
|
|
|
+ </a>
|
|
|
|
|
+ </li>
|
|
|
|
|
+ </ul>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="tab-content">
|
|
|
|
|
+ <div class="tab-pane fade show active" id="tab-config" role="tabpanel">
|
|
|
|
|
+ @php
|
|
|
|
|
+ $totalWeight = array_sum($config);
|
|
|
|
|
+ @endphp
|
|
|
|
|
+ <div class="alert alert-info">
|
|
|
|
|
+ 当前总权重: <strong id="total-weight">{{ $totalWeight }}</strong>
|
|
|
|
|
+ ,前端按权重比例随机返回 1/2/3/4
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="table-responsive">
|
|
|
|
|
+ <table class="table table-striped table-hover align-middle mb-0" style="max-width: 600px;">
|
|
|
|
|
+ <thead class="thead-light">
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <th style="width:80px;">ID</th>
|
|
|
|
|
+ <th style="width:200px;">权重 (整数)</th>
|
|
|
|
|
+ <th>占比</th>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ </thead>
|
|
|
|
|
+ <tbody class="weight-form">
|
|
|
|
|
+ @foreach([1,2,3,4] as $id)
|
|
|
|
|
+ @php
|
|
|
|
|
+ $w = intval($config[$id] ?? 0);
|
|
|
|
|
+ $percent = $totalWeight > 0 ? round($w / $totalWeight * 100, 2) : 0;
|
|
|
|
|
+ @endphp
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <td><span class="badge badge-primary">{{ $id }}</span></td>
|
|
|
|
|
+ <td>
|
|
|
|
|
+ <input type="number" min="0" class="form-control form-control-sm weight-input"
|
|
|
|
|
+ data-id="{{ $id }}" name="weight[{{ $id }}]" value="{{ $w }}" />
|
|
|
|
|
+ </td>
|
|
|
|
|
+ <td>
|
|
|
|
|
+ <span class="weight-percent" data-id="{{ $id }}">{{ $percent }}%</span>
|
|
|
|
|
+ </td>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ @endforeach
|
|
|
|
|
+ </tbody>
|
|
|
|
|
+ </table>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="d-flex align-items-center mt-4">
|
|
|
|
|
+ <button class="btn btn-gradient-primary btn-sm" id="save-weights">
|
|
|
|
|
+ <i class="mdi mdi-content-save"></i> 保存权重
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <span class="save-status ml-3"></span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="tab-pane fade" id="tab-stats" role="tabpanel">
|
|
|
|
|
+ <div class="d-flex align-items-center justify-content-between mb-3">
|
|
|
|
|
+ <h5 class="mb-0">总点击统计</h5>
|
|
|
|
|
+ <button class="btn btn-sm btn-outline-danger" id="reset-stats">
|
|
|
|
|
+ <i class="mdi mdi-delete"></i> 清除总统计
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ @php
|
|
|
|
|
+ $totalClicksAll = array_sum($totalClicks);
|
|
|
|
|
+ @endphp
|
|
|
|
|
+ <div class="table-responsive mb-4">
|
|
|
|
|
+ <table class="table table-bordered align-middle" style="max-width: 600px;">
|
|
|
|
|
+ <thead class="thead-light">
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <th>ID</th>
|
|
|
|
|
+ <th>点击次数</th>
|
|
|
|
|
+ <th>占比</th>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ </thead>
|
|
|
|
|
+ <tbody>
|
|
|
|
|
+ @foreach([1,2,3,4] as $id)
|
|
|
|
|
+ @php
|
|
|
|
|
+ $c = intval($totalClicks[$id] ?? 0);
|
|
|
|
|
+ $p = $totalClicksAll > 0 ? round($c / $totalClicksAll * 100, 2) : 0;
|
|
|
|
|
+ @endphp
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <td><span class="badge badge-info">{{ $id }}</span></td>
|
|
|
|
|
+ <td>{{ $c }}</td>
|
|
|
|
|
+ <td>{{ $p }}%</td>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ @endforeach
|
|
|
|
|
+ <tr class="table-secondary">
|
|
|
|
|
+ <td><strong>合计</strong></td>
|
|
|
|
|
+ <td colspan="2"><strong>{{ $totalClicksAll }}</strong></td>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ </tbody>
|
|
|
|
|
+ </table>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <h5 class="mb-3">最近 7 天每日点击</h5>
|
|
|
|
|
+ <div class="table-responsive">
|
|
|
|
|
+ <table class="table table-bordered align-middle" style="max-width: 800px;">
|
|
|
|
|
+ <thead class="thead-light">
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <th>日期</th>
|
|
|
|
|
+ <th>1</th>
|
|
|
|
|
+ <th>2</th>
|
|
|
|
|
+ <th>3</th>
|
|
|
|
|
+ <th>4</th>
|
|
|
|
|
+ <th>合计</th>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ </thead>
|
|
|
|
|
+ <tbody>
|
|
|
|
|
+ @foreach($dailyClicks as $row)
|
|
|
|
|
+ @php
|
|
|
|
|
+ $sum = intval($row[1]) + intval($row[2]) + intval($row[3]) + intval($row[4]);
|
|
|
|
|
+ @endphp
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <td>{{ $row['date'] }}</td>
|
|
|
|
|
+ <td>{{ $row[1] }}</td>
|
|
|
|
|
+ <td>{{ $row[2] }}</td>
|
|
|
|
|
+ <td>{{ $row[3] }}</td>
|
|
|
|
|
+ <td>{{ $row[4] }}</td>
|
|
|
|
|
+ <td><strong>{{ $sum }}</strong></td>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ @endforeach
|
|
|
|
|
+ </tbody>
|
|
|
|
|
+ </table>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</div>
|
|
|
|
|
+
|
|
|
|
|
+<script>
|
|
|
|
|
+$(function() {
|
|
|
|
|
+ function refreshPercents() {
|
|
|
|
|
+ let total = 0;
|
|
|
|
|
+ $('.weight-input').each(function(){
|
|
|
|
|
+ total += parseInt($(this).val() || 0);
|
|
|
|
|
+ });
|
|
|
|
|
+ $('#total-weight').text(total);
|
|
|
|
|
+ $('.weight-input').each(function(){
|
|
|
|
|
+ const id = $(this).data('id');
|
|
|
|
|
+ const w = parseInt($(this).val() || 0);
|
|
|
|
|
+ const p = total > 0 ? (w / total * 100).toFixed(2) : 0;
|
|
|
|
|
+ $('.weight-percent[data-id="' + id + '"]').text(p + '%');
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $('.weight-input').on('input change', refreshPercents);
|
|
|
|
|
+
|
|
|
|
|
+ $('#save-weights').click(function() {
|
|
|
|
|
+ const $btn = $(this);
|
|
|
|
|
+ const $status = $btn.siblings('.save-status');
|
|
|
|
|
+ const config = {};
|
|
|
|
|
+ $('.weight-input').each(function(){
|
|
|
|
|
+ const id = $(this).data('id');
|
|
|
|
|
+ let v = parseInt($(this).val() || 0);
|
|
|
|
|
+ if (isNaN(v) || v < 0) v = 0;
|
|
|
|
|
+ config[id] = v;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ $btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> 保存中...');
|
|
|
|
|
+ $status.removeClass('text-success text-danger').text('');
|
|
|
|
|
+
|
|
|
|
|
+ $.post("{{ url('/admin/weight-config/update') }}", {
|
|
|
|
|
+ config: JSON.stringify(config),
|
|
|
|
|
+ _token: "{{ csrf_token() }}"
|
|
|
|
|
+ }).done(function(res){
|
|
|
|
|
+ $btn.prop('disabled', false).html('<i class="mdi mdi-content-save"></i> 保存权重');
|
|
|
|
|
+ if (res.status === 'success') {
|
|
|
|
|
+ $status.text('更新成功').addClass('text-success');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $status.text(res.message || '更新失败').addClass('text-danger');
|
|
|
|
|
+ }
|
|
|
|
|
+ setTimeout(function(){ $status.fadeOut(function(){ $(this).text('').show().removeClass('text-success text-danger'); }); }, 3000);
|
|
|
|
|
+ }).fail(function(){
|
|
|
|
|
+ $btn.prop('disabled', false).html('<i class="mdi mdi-content-save"></i> 保存权重');
|
|
|
|
|
+ $status.text('系统错误').addClass('text-danger');
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ $('#reset-stats').click(function(){
|
|
|
|
|
+ if (!confirm('确认清除总点击统计?(每日明细仍保留)')) return;
|
|
|
|
|
+ $.post("{{ url('/admin/weight-config/reset-stats') }}", {
|
|
|
|
|
+ type: 'total',
|
|
|
|
|
+ _token: "{{ csrf_token() }}"
|
|
|
|
|
+ }).done(function(res){
|
|
|
|
|
+ if (res.status === 'success') {
|
|
|
|
|
+ location.reload();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ alert(res.message || '操作失败');
|
|
|
|
|
+ }
|
|
|
|
|
+ }).fail(function(){
|
|
|
|
|
+ alert('系统错误');
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+});
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style>
|
|
|
|
|
+.table thead th { white-space: nowrap; }
|
|
|
|
|
+.table tbody td { vertical-align: middle; }
|
|
|
|
|
+.badge { font-size: .85rem; padding: .5em .6em; }
|
|
|
|
|
+</style>
|
|
|
|
|
+@endsection
|