修复 Bug, 增加流量激活码
This commit is contained in:
parent
6919487fe8
commit
fa8732e548
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,3 +17,4 @@ yarn-error.log
|
||||
/.idea
|
||||
/.vscode
|
||||
.DS_Store
|
||||
/project
|
||||
|
71
app/Http/Controllers/Admin/TrafficActivateCodeController.php
Normal file
71
app/Http/Controllers/Admin/TrafficActivateCodeController.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\TrafficActivateCode;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class TrafficActivateCodeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$codes = TrafficActivateCode::all();
|
||||
$count = $codes->count();
|
||||
return view('admin.codes.index', ['codes' => $codes, 'count' => $count]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create(): View
|
||||
{
|
||||
return view('admin.codes.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$amount = $request->input('amount');
|
||||
$traffic = $request->input('traffic');
|
||||
$codes = $this->generate_key($amount);
|
||||
foreach ($codes as $code) {
|
||||
TrafficActivateCode::create([
|
||||
'code' => $code,
|
||||
'traffic' => $traffic,
|
||||
]);
|
||||
}
|
||||
return view('admin.codes.show', compact('codes'));
|
||||
}
|
||||
|
||||
private function generate_key($count): array
|
||||
{
|
||||
$codes = [];
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$code = Str::random(25);
|
||||
$code = strtoupper($code);
|
||||
$formattedCode = preg_replace('/(\w{5})(\w{5})(\w{5})(\w{5})(\w{5})/', '$1-$2-$3-$4-$5', $code);
|
||||
$codes[] = $formattedCode;
|
||||
}
|
||||
|
||||
return $codes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(TrafficActivateCode $code)
|
||||
{
|
||||
$code->delete();
|
||||
|
||||
return back()->with('success', '删除成功');
|
||||
}
|
||||
}
|
@ -18,7 +18,6 @@ class UserController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$users = new User();
|
||||
$count = User::count();
|
||||
|
||||
foreach ($request->except(['page']) as $key => $value) {
|
||||
if (empty($value)) {
|
||||
|
33
app/Http/Controllers/Api/TrafficActivateCodeController.php
Normal file
33
app/Http/Controllers/Api/TrafficActivateCodeController.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\TrafficActivateCode;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrafficActivateCodeController extends Controller
|
||||
{
|
||||
public function useActivateCode(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'code' => 'required|string'
|
||||
]);
|
||||
$code = $request->post('code');
|
||||
$trafficActivateCode = TrafficActivateCode::where('code', $code)->first();
|
||||
if ($trafficActivateCode == null) {
|
||||
return $this->error('激活码错误');
|
||||
}
|
||||
if ($trafficActivateCode->used_at != null) {
|
||||
return $this->error('激活码已被使用');
|
||||
}
|
||||
$trafficActivateCode->user_id = $request->user()->id;
|
||||
$trafficActivateCode->used_at = now();
|
||||
$trafficActivateCode->update();
|
||||
$user = User::find($request->user()->id);
|
||||
$user->traffic += $trafficActivateCode->traffic;
|
||||
$user->update();
|
||||
return $this->success('激活成功');
|
||||
}
|
||||
}
|
28
app/Models/TrafficActivateCode.php
Normal file
28
app/Models/TrafficActivateCode.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class TrafficActivateCode extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'traffic',
|
||||
|
||||
'user_id',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'used_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('traffic_activate_codes', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('code')->index()->unique();
|
||||
$table->bigInteger('traffic')->index();
|
||||
$table->dateTime('used_at')->nullable();
|
||||
$table->unsignedBigInteger('user_id')->nullable()->index();
|
||||
$table->foreign('user_id')->references('id')->on('users')->nullOnDelete();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('traffic_activate_codes');
|
||||
}
|
||||
};
|
@ -45,7 +45,7 @@ const items = ref([
|
||||
route: "tunnels.create",
|
||||
},
|
||||
{
|
||||
name: "签到",
|
||||
name: "流量补给",
|
||||
route: "sign",
|
||||
},
|
||||
{
|
||||
|
@ -17,27 +17,36 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<h3>兑换流量激活码</h3>
|
||||
<div class="input-group mt-3">
|
||||
<input v-model="activate_code" class="form-control" type="text">
|
||||
<button class="btn btn-primary" @click="exchange">兑换</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
style="display: none"
|
||||
id="signinButton"
|
||||
class="btn btn-primary"
|
||||
data-bs-target="#signinModal"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#signinModal">
|
||||
style="display: none"
|
||||
type="button">
|
||||
</button>
|
||||
|
||||
|
||||
<div class="modal fade" id="signinModal" tabindex="-1" aria-labelledby="signinModalLabel" aria-hidden="true">
|
||||
<div id="signinModal" aria-hidden="true" aria-labelledby="signinModalLabel" class="modal fade" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="signinModalLabel">签到</h1>
|
||||
<h1 id="signinModalLabel" class="modal-title fs-5">签到</h1>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
签到成功!{{ content }}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">确定</button>
|
||||
<button class="btn btn-primary" data-bs-dismiss="modal" type="button">确定</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -61,6 +70,7 @@ const traffic = ref({
|
||||
});
|
||||
|
||||
const theme = ref("")
|
||||
const activate_code = ref("")
|
||||
|
||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
theme.value = "dark"
|
||||
@ -101,6 +111,21 @@ function sign(captcha_token) {
|
||||
});
|
||||
}
|
||||
|
||||
function exchange() {
|
||||
http.post('/codes/use', {
|
||||
'code': activate_code.value
|
||||
}).then(res => {
|
||||
alert(res.data.message)
|
||||
}).catch(res => {
|
||||
alert(res.data.message)
|
||||
}).finally(() => {
|
||||
http.get("user")
|
||||
.then((res) => {
|
||||
traffic.value.traffic = res.data.traffic;
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// function refreshSign() {
|
||||
// const date = new Date(traffic.value.last_sign_at)
|
||||
//
|
||||
|
13
resources/views/admin/codes/create.blade.php
Normal file
13
resources/views/admin/codes/create.blade.php
Normal file
@ -0,0 +1,13 @@
|
||||
<x-app-layout>
|
||||
<h3 class="mb-3">创建流量激活码</h3>
|
||||
<form action="{{ route('admin.codes.store') }}" method="post">
|
||||
@csrf
|
||||
<label for="name" class="form-label">数量</label>
|
||||
<input type="number" name="amount" id="amount" placeholder="数量" class="form-control mb-3" required>
|
||||
|
||||
<label for="name" class="form-label">流量</label>
|
||||
<input type="number" name="traffic" id="traffic" placeholder="流量 (GB)" class="form-control mb-3" required>
|
||||
|
||||
<button class="btn btn-primary" type="submit">创建</button>
|
||||
</form>
|
||||
</x-app-layout>
|
20
resources/views/admin/codes/edit.blade.php
Normal file
20
resources/views/admin/codes/edit.blade.php
Normal file
@ -0,0 +1,20 @@
|
||||
<x-app-layout>
|
||||
<h3 class="mb-3">编辑客户端</h3>
|
||||
<form action="{{ route('admin.clients.update', $client->id) }}" method="post">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<label for="name" class="form-label">名称</label>
|
||||
<input type="text" name="name" id="name" placeholder="名称" class="form-control mb-3" required
|
||||
value="{{ $client->name }}">
|
||||
|
||||
<label for="name" class="form-label">架构</label>
|
||||
<input type="text" name="arch" id="arch" placeholder="架构" class="form-control mb-3" required
|
||||
value="{{ $client->arch }}">
|
||||
|
||||
<label for="name" class="form-label">下载链接</label>
|
||||
<input type="text" name="url" id="url" placeholder="下载链接" class="form-control mb-3" required
|
||||
value="{{ $client->url }}">
|
||||
|
||||
<button class="btn btn-primary" type="submit">保存更改</button>
|
||||
</form>
|
||||
</x-app-layout>
|
45
resources/views/admin/codes/index.blade.php
Normal file
45
resources/views/admin/codes/index.blade.php
Normal file
@ -0,0 +1,45 @@
|
||||
<x-app-layout>
|
||||
<h3>流量激活码</h3>
|
||||
|
||||
<a href="{{ route('admin.codes.create') }}">新建激活码</a>
|
||||
|
||||
<div class="alert alert-primary mt-3" role="alert">
|
||||
总计: {{ $count }}
|
||||
</div>
|
||||
|
||||
<table class="mt-3 table table-hover text-center table-bordered" style="vertical-align: middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>激活码</th>
|
||||
<th>流量</th>
|
||||
<th>使用用户</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
||||
<tbody>
|
||||
@foreach ($codes as $code)
|
||||
<tr>
|
||||
<td>{{ $code->id }}</td>
|
||||
<td>{{ $code->code }}</td>
|
||||
<td>{{ $code->traffic }}</td>
|
||||
<td>
|
||||
@isset($code->user_id)
|
||||
{{ $code->user->name }} # {{ $code->user_id }}
|
||||
@endisset
|
||||
</td>
|
||||
<td>
|
||||
<form action="{{ route('admin.codes.destroy', ['code' => $code]) }}" method="POST"
|
||||
onsubmit="return confirm('真的要删除吗?')">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-danger">删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</x-app-layout>
|
8
resources/views/admin/codes/show.blade.php
Normal file
8
resources/views/admin/codes/show.blade.php
Normal file
@ -0,0 +1,8 @@
|
||||
<x-app-layout>
|
||||
<h3 class="mb-3">流量激活码生成详情</h3>
|
||||
<textarea class="form-control" id="code" rows="10" readonly>
|
||||
@foreach($codes as $code)
|
||||
{{ $code }}
|
||||
@endforeach
|
||||
</textarea>
|
||||
</x-app-layout>
|
@ -86,7 +86,7 @@
|
||||
<td>{{ $host->created_at }}</td>
|
||||
<td>{{ $host->updated_at }}</td>
|
||||
<td>
|
||||
<a href="{{ route('admin.tunnels.show', ['tunnel' => $host]) }}"
|
||||
<a href="{{ route('admin.tunnels.show', ['host' => $host]) }}"
|
||||
class="btn btn-sm btn-primary">编辑</a>
|
||||
|
||||
<form action="{{ route('admin.tunnels.destroy', ['tunnel' => $host]) }}" method="POST"
|
||||
|
@ -42,6 +42,9 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.clients.index') }}">客户端</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.codes.index') }}">流量激活码</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav ml-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
|
@ -5,6 +5,7 @@
|
||||
use App\Http\Controllers\Admin\ServerController;
|
||||
use App\Http\Controllers\Admin\UserController;
|
||||
use App\Http\Controllers\Admin\ClientController;
|
||||
use App\Http\Controllers\Admin\TrafficActivateCodeController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::withoutMiddleware('auth:admin')->group(function() {
|
||||
@ -20,6 +21,9 @@
|
||||
Route::resource('servers', ServerController::class);
|
||||
Route::resource('tunnels', TunnelController::class);
|
||||
Route::resource('clients', ClientController::class);
|
||||
Route::resource('codes', TrafficActivateCodeController::class)->except([
|
||||
'show', 'edit', 'update'
|
||||
]);
|
||||
|
||||
|
||||
Route::get('/logout', [IndexController::class, 'logout'])->name('logout');
|
||||
|
@ -10,6 +10,7 @@
|
||||
use App\Http\Controllers\Application\UserController as ApplicationUserController;
|
||||
use App\Http\Controllers\Api\ClientController;
|
||||
use App\Http\Controllers\Review\ReviewController;
|
||||
use App\Http\Controllers\Api\TrafficActivateCodeController;
|
||||
|
||||
Route::prefix('tunnel')->name('api.tunnel.')->group(function () {
|
||||
Route::post('/handler/{key}', [PortManagerController::class, 'handler'])->name('handler');
|
||||
@ -29,6 +30,7 @@
|
||||
Route::apiResource('servers', ServerController::class);
|
||||
|
||||
Route::apiResource('clients', ClientController::class);
|
||||
Route::post('codes/use', [TrafficActivateCodeController::class, 'useActivateCode'])->name('codes.useActivateCode');
|
||||
|
||||
Route::get('traffic', [TrafficController::class, 'free']);
|
||||
Route::post('traffic', [TrafficController::class, 'sign']);
|
||||
|
Loading…
Reference in New Issue
Block a user