优化导入,格式化代码

分离出充值系统

修复了充值的问题
This commit is contained in:
iVampireSP.com 2022-11-16 13:16:56 +08:00
parent 1be6dea757
commit 4918efa597
No known key found for this signature in database
GPG Key ID: 2F7B001CA27A8132
106 changed files with 1148 additions and 1074 deletions

View File

@ -39,7 +39,7 @@ public function __construct()
*/ */
public function handle() public function handle()
{ {
$moduleController = new ModuleController(); $moduleController = new ModuleController();
$rate = config('drops.module_rate'); $rate = config('drops.module_rate');

View File

@ -58,13 +58,13 @@ public function handle()
$this->info('正在获取主机数量...'); $this->info('正在获取主机数量...');
$hosts = Host::count(); $hosts = Host::count();
$this->info('正在获取部署中的主机数量...'); $this->info('正在获取部署中的主机数量...');
$pending_hosts = Host::where('status', 'pending')->count(); $pending_hosts = Host::where('status', 'pending')->count();
$this->info('正在获取已停止的主机数量...'); $this->info('正在获取已停止的主机数量...');
$stopped_hosts = Host::where('status', 'stopped')->count(); $stopped_hosts = Host::where('status', 'stopped')->count();
$this->info('正在获取部署失败的主机数量...'); $this->info('正在获取部署失败的主机数量...');
$error_hosts = Host::where('status', 'error')->count(); $error_hosts = Host::where('status', 'error')->count();

View File

@ -48,11 +48,11 @@ public function handle()
$user = User::find($user_id); $user = User::find($user_id);
$this->warn('扣除金额: ' . $user->balance . ' 元'); $this->warn('扣除金额: ' . $amount . ' 元');
$this->warn('用户当前余额:' . $user->balance . ' 元'); $this->warn('用户当前余额:' . $user->balance . ' 元');
$this->warn('剩余余额:' . $user->balance -$amount . ' 元'); $this->warn('剩余余额:' . $user->balance - $amount . ' 元');
$confirm = $this->confirm('确认扣除?'); $confirm = $this->confirm('确认扣除?');

View File

@ -109,7 +109,6 @@ public function handle()
$this->info('Redis 总命令数: ' . $redis_total_commands_processed); $this->info('Redis 总命令数: ' . $redis_total_commands_processed);
$this->warn('===== 莱云 统计 ====='); $this->warn('===== 莱云 统计 =====');
$this->warn('要获取 莱云 统计信息,请运行 count 命令。'); $this->warn('要获取 莱云 统计信息,请运行 count 命令。');

View File

@ -17,7 +17,8 @@ class Kernel extends ConsoleKernel
/** /**
* Define the application's command schedule. * Define the application's command schedule.
* *
* @param \Illuminate\Console\Scheduling\Schedule $schedule * @param \Illuminate\Console\Scheduling\Schedule $schedule
*
* @return void * @return void
*/ */
protected function schedule(Schedule $schedule) protected function schedule(Schedule $schedule)

View File

@ -4,7 +4,6 @@
use Illuminate\Auth\AuthenticationException; use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\JsonResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable; use Throwable;
@ -63,8 +62,8 @@ public function register()
/** /**
* Convert an authentication exception into an unauthenticated response. * Convert an authentication exception into an unauthenticated response.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception * @param \Illuminate\Auth\AuthenticationException $exception
* *
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\Http\Response * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\Http\Response
*/ */

View File

@ -5,6 +5,25 @@
trait ApiResponse trait ApiResponse
{ {
// RESTful API response // RESTful API response
public function remoteResponse($response, $status = 200)
{
return response()->json($response, $status)->setEncodingOptions(JSON_UNESCAPED_UNICODE);
}
public function notFound($message = 'Not found')
{
return $this->error($message, 404);
}
// success
public function error($message = '', $code = 400)
{
return $this->apiResponse($message, $code);
}
// error
public function apiResponse($data = [], $status = 200) public function apiResponse($data = [], $status = 200)
{ {
// if data is paginated, return paginated data // if data is paginated, return paginated data
@ -34,55 +53,44 @@ public function apiResponse($data = [], $status = 200)
return response()->json($data, $status)->setEncodingOptions(JSON_UNESCAPED_UNICODE); return response()->json($data, $status)->setEncodingOptions(JSON_UNESCAPED_UNICODE);
} }
public function remoteResponse($response, $status = 200)
{
return response()->json($response, $status)->setEncodingOptions(JSON_UNESCAPED_UNICODE);
}
// success
public function success($data = [])
{
return $this->apiResponse($data, 200);
}
// error
public function error($message = '', $code = 400)
{
return $this->apiResponse($message, $code);
}
// not found // not found
public function notFound($message = 'Not found')
{
return $this->error($message, 404);
}
// forbidden
public function forbidden($message = 'Forbidden') public function forbidden($message = 'Forbidden')
{ {
return $this->error($message, 403); return $this->error($message, 403);
} }
// unauthorized // forbidden
public function unauthorized($message = 'Unauthorized') public function unauthorized($message = 'Unauthorized')
{ {
return $this->error($message, 401); return $this->error($message, 401);
} }
// bad request // unauthorized
public function badRequest($message = 'Bad request') public function badRequest($message = 'Bad request')
{ {
return $this->error($message, 400); return $this->error($message, 400);
} }
// created // bad request
public function created($message = 'Created') public function created($message = 'Created')
{ {
return $this->success($message, 201); return $this->success($message, 201);
} }
// created
public function success($data = [])
{
return $this->apiResponse($data, 200);
}
// accepted // accepted
public function accepted($message = 'Accepted') public function accepted($message = 'Accepted')
{ {
return $this->success($message, 202); return $this->success($message, 202);

View File

@ -4,5 +4,5 @@
trait HttpEvent trait HttpEvent
{ {
} }

View File

@ -6,8 +6,10 @@
use Illuminate\Contracts\Cache\LockTimeoutException; use Illuminate\Contracts\Cache\LockTimeoutException;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
trait Lock { trait Lock
public function await($name, Closure $callback) { {
public function await($name, Closure $callback)
{
// if env is local // if env is local
if (env('APP_ENV') == 'local') { if (env('APP_ENV') == 'local') {
return $callback(); return $callback();

View File

@ -20,7 +20,8 @@ public function index()
} }
} }
public function login(Request $request) { public function login(Request $request)
{
if (auth('admin')->attempt($request->only('email', 'password'))) { if (auth('admin')->attempt($request->only('email', 'password'))) {
return redirect()->route('admin.index'); return redirect()->route('admin.index');
} else { } else {

View File

@ -30,7 +30,8 @@ public function create()
/** /**
* Store a newly created resource in storage. * Store a newly created resource in storage.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function store(Request $request) public function store(Request $request)
@ -41,7 +42,8 @@ public function store(Request $request)
/** /**
* Display the specified resource. * Display the specified resource.
* *
* @param int $id * @param int $id
*
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function show($id) public function show($id)
@ -52,7 +54,8 @@ public function show($id)
/** /**
* Show the form for editing the specified resource. * Show the form for editing the specified resource.
* *
* @param int $id * @param int $id
*
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function edit($id) public function edit($id)
@ -63,8 +66,9 @@ public function edit($id)
/** /**
* Update the specified resource in storage. * Update the specified resource in storage.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* @param int $id * @param int $id
*
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function update(Request $request, $id) public function update(Request $request, $id)
@ -75,7 +79,8 @@ public function update(Request $request, $id)
/** /**
* Remove the specified resource from storage. * Remove the specified resource from storage.
* *
* @param int $id * @param int $id
*
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function destroy($id) public function destroy($id)

View File

@ -2,134 +2,30 @@
namespace App\Http\Controllers\Api; namespace App\Http\Controllers\Api;
use App\Exceptions\ChargeException;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Balance; use App\Models\Balance;
use App\Models\Transaction; use App\Models\Transaction;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Yansongda\LaravelPay\Facades\Pay; use Yansongda\LaravelPay\Facades\Pay;
use Yansongda\Pay\Exception\InvalidResponseException; use Yansongda\Pay\Exception\InvalidResponseException;
use function auth; use function auth;
use function config; use function config;
use function now; use function now;
use function route;
use function view;
class BalanceController extends Controller class BalanceController extends Controller
{ {
// //
public function index(Request $request) public function index(): JsonResponse
{ {
$balances = Balance::thisUser()->simplePaginate(30); $balances = Balance::thisUser()->simplePaginate(30);
return $this->success($balances); return $this->success($balances);
} }
public function store(Request $request) public function checkAndCharge(Balance $balance, $check = false): JsonResponse|bool
{
// 充值
$this->validate($request, [
'amount' => 'required|integer|min:1|max:10000',
]);
$user = $request->user();
$balance = new Balance();
$data = [
'user_id' => $user->id,
'amount' => $request->amount,
'payment' => 'alipay',
];
// if local
// if (env('APP_ENV') == 'local') {
// $data['payment'] = null;
// $data['paid_at'] = now();
// }
$balance = $balance->create($data);
// 生成 18 位订单号
$order_id = date('YmdHis') . $balance->id . rand(1000, 9999);
$balance->order_id = $order_id;
$balance->save();
$balance = $balance->toArray();
$balance['pay_url'] = route('balances.pay.show', ['balance' => $balance['order_id']]);
return $this->success($balance);
}
public function show(Balance $balance)
{
if ($balance->paid_at !== null) {
return $this->error('订单已支付');
}
if (now()->diffInDays($balance->created_at) > 1) {
return $this->error('订单已失效');
}
$pay = Pay::alipay()->web([
'out_trade_no' => $balance->order_id,
'total_amount' => $balance->amount,
'subject' => config('app.display_name') . ' 充值',
]);
return $pay;
}
public function notify(Request $request)
{
$this->validate($request, [
'out_trade_no' => 'required',
]);
// 检测订单是否存在
$balance = Balance::where('order_id', $request->out_trade_no)->with('user')->first();
if (!$balance) {
return $this->notFound('找不到对应的订单');
}
// 检测订单是否已支付
if ($balance->paid_at !== null) {
// return $this->success('订单已支付');
return view('pay_process');
}
// try {
// $data = Pay::alipay()->callback();
// } catch (InvalidResponseException $e) {
// return $this->error('支付失败');
// }
// // 检测 out_trade_no 是否为商户系统中创建的订单号
// if ($data->out_trade_no != $balance->order_id) {
// return $this->error('订单号不一致');
// }
// if ((int) $data->total_amount != (int) $balance->amount) {
// throw new ChargeException('金额不一致');
// }
// // 验证 商户
// if ($data['app_id'] != config('pay.alipay.default.app_id')) {
// throw new ChargeException('商户不匹配');
// }
if ($this->checkAndCharge($balance, true)) {
return view('pay_process');
} else {
return $this->error('支付失败');
}
}
public function checkAndCharge(Balance $balance, $check = false)
{ {
if ($check) { if ($check) {
@ -150,8 +46,13 @@ public function checkAndCharge(Balance $balance, $check = false)
$balance->update([ $balance->update([
'paid_at' => now() 'paid_at' => now()
]); ]);
} catch (InvalidResponseException) { } catch (InvalidResponseException $e) {
Log::error($e->getMessage());
return $this->error('无法验证支付结果。'); return $this->error('无法验证支付结果。');
} catch (ChargeException $e) {
Log::error($e->getMessage());
return $this->error('暂时无法处理充值。');
} }
return true; return true;
@ -160,7 +61,8 @@ public function checkAndCharge(Balance $balance, $check = false)
/** /**
* 获取交易记录 * 获取交易记录
* *
* @param mixed $request * @param mixed $request
*
* @return JsonResponse * @return JsonResponse
*/ */
public function transactions(Request $request): JsonResponse public function transactions(Request $request): JsonResponse

View File

@ -23,13 +23,6 @@ public function __construct()
$this->http = Http::baseUrl($this->baseUrl . '/api')->throw(); $this->http = Http::baseUrl($this->baseUrl . '/api')->throw();
} }
public function get($url)
{
$resp = $this->http->get($url)->json()['data'];
return $resp;
}
public function announcements() public function announcements()
{ {
$resp = $this->cache(function () { $resp = $this->cache(function () {
@ -39,16 +32,6 @@ public function announcements()
return $this->resp($resp); return $this->resp($resp);
} }
public function pinned()
{
$resp = $this->cache(function () {
return $this->get('discussions?filter[tag]=pinned&page[offset]=0&sort=-createdAt');
});
return $this->resp($resp);
}
public function cache(Closure $callback) public function cache(Closure $callback)
{ {
// 获取调用方法名 // 获取调用方法名
@ -59,6 +42,11 @@ public function cache(Closure $callback)
}); });
} }
public function get($url)
{
$resp = $this->http->get($url)->json()['data'];
return $resp;
}
public function resp($data) public function resp($data)
{ {
@ -66,4 +54,13 @@ public function resp($data)
return $this->success($data); return $this->success($data);
} }
public function pinned()
{
$resp = $this->cache(function () {
return $this->get('discussions?filter[tag]=pinned&page[offset]=0&sort=-createdAt');
});
return $this->resp($resp);
}
} }

View File

@ -15,7 +15,7 @@ class HostController extends Controller
{ {
public function index(): JsonResponse public function index(): JsonResponse
{ {
$hosts = Host::where('user_id', auth()->id())->with('module', function ($query) { $hosts = Host::where('user_id', auth()->id())->with('module', function ($query) {
$query->select(['id', 'name']); $query->select(['id', 'name']);
})->get(); })->get();

View File

@ -29,7 +29,7 @@ public function index(WorkOrder $workOrder)
/** /**
* Store a newly created resource in storage. * Store a newly created resource in storage.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* *
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
*/ */

View File

@ -25,6 +25,13 @@ public function broadcast_to_user(Request $request, User $user)
} }
private function rules()
{
return [
'message' => 'required',
];
}
public function broadcast_to_host(Request $request, Host $host) public function broadcast_to_host(Request $request, Host $host)
{ {
$this->validate($request, $this->rules()); $this->validate($request, $this->rules());
@ -37,10 +44,4 @@ public function broadcast_to_host(Request $request, Host $host)
return $this->created($request->message); return $this->created($request->message);
} }
private function rules() {
return [
'message' => 'required',
];
}
} }

View File

@ -72,7 +72,7 @@ public function store(Request $request)
/** /**
* Display the specified resource. * Display the specified resource.
* *
* @param Host $host * @param Host $host
* *
* @return JsonResponse * @return JsonResponse
*/ */
@ -89,7 +89,7 @@ public function show(Host $host)
* Update the specified resource in storage. * Update the specified resource in storage.
* *
* @param Request $request * @param Request $request
* @param Host $host * @param Host $host
* *
* @return JsonResponse * @return JsonResponse
*/ */

View File

@ -19,7 +19,7 @@ public function index()
$data = [ $data = [
'module' => $module, 'module' => $module,
'rate' => (int) config('drops.module_rate'), 'rate' => (int)config('drops.module_rate'),
]; ];
// merge // merge
@ -28,6 +28,22 @@ public function index()
return $this->success($data); return $this->success($data);
} }
public function calcModule(Module|Authenticatable $module): array
{
$default = [
'balance' => 0,
'drops' => 0,
];
return [
'transactions' => [
'this_month' => Cache::get('this_month_balance_and_drops_' . $module->id, $default),
'last_month' => Cache::get('last_month_balance_and_drops_' . $module->id, $default),
]
];
}
public function call(Request $request, Module $module) public function call(Request $request, Module $module)
{ {
$path = request()->path(); $path = request()->path();
@ -58,7 +74,6 @@ public function call(Request $request, Module $module)
return $this->remoteResponse($response['json'], $response['status']); return $this->remoteResponse($response['json'], $response['status']);
} }
public function exportCall(Request $request, Module $module): \Illuminate\Http\Response|\Illuminate\Http\JsonResponse|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory public function exportCall(Request $request, Module $module): \Illuminate\Http\Response|\Illuminate\Http\JsonResponse|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory
{ {
$path = request()->path(); $path = request()->path();
@ -76,21 +91,4 @@ public function exportCall(Request $request, Module $module): \Illuminate\Http\R
return $this->remoteResponse($response['json'], $response['status']); return $this->remoteResponse($response['json'], $response['status']);
} }
public function calcModule(Module|Authenticatable $module): array
{
$default = [
'balance' => 0,
'drops' => 0,
];
return [
'transactions' => [
'this_month' => Cache::get('this_month_balance_and_drops_' . $module->id, $default),
'last_month' => Cache::get('last_month_balance_and_drops_' . $module->id, $default),
]
];
}
} }

View File

@ -25,6 +25,7 @@ public function index(Request $request)
* Store a newly created resource in storage. * Store a newly created resource in storage.
* *
* @param Request $request * @param Request $request
*
* @return JsonResponse * @return JsonResponse
*/ */
public function store(Request $request) public function store(Request $request)

View File

@ -10,7 +10,8 @@
class WorkOrderController extends Controller class WorkOrderController extends Controller
{ {
// //
public function index(Request $request, WorkOrder $workOrder) { public function index(Request $request, WorkOrder $workOrder)
{
// $work_orders = new WorkOrder(); // $work_orders = new WorkOrder();
// // if route has user // // if route has user
// if ($request->route('user')) { // if ($request->route('user')) {
@ -28,7 +29,8 @@ public function index(Request $request, WorkOrder $workOrder) {
// } // }
public function show(WorkOrderRequest $request, WorkOrder $workOrder) { public function show(WorkOrderRequest $request, WorkOrder $workOrder)
{
return $this->success($workOrder); return $this->success($workOrder);
} }

View File

@ -1,15 +1,22 @@
<?php <?php
namespace App\Http\Controllers; namespace App\Http\Controllers\Web;
// use App\Helpers\ApiResponse; // use App\Helpers\ApiResponse;
use App\Http\Controllers\Controller;
use App\Models\User; use App\Models\User;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Exception\ClientException;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use function back;
use function config;
use function now;
use function redirect;
use function session;
use function view;
class AuthController extends Controller class AuthController extends Controller
{ {

View File

@ -0,0 +1,137 @@
<?php
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Models\Balance;
use App\Models\Transaction;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Yansongda\LaravelPay\Facades\Pay;
class BalanceController extends Controller
{
//
public function index(Request $request): View
{
$transaction = new Transaction();
$drops = $transaction->getDrops();
$balance = $request->user()->balance;
return view('balances.index', compact('drops', 'balance'));
}
public function store(Request $request)
{
// 充值
$this->validate($request, [
'amount' => 'required|integer|min:1|max:10000',
]);
$user = $request->user();
$balance = new Balance();
$data = [
'user_id' => $user->id,
'amount' => $request->amount,
'payment' => 'alipay',
];
// if local
// if (env('APP_ENV') == 'local') {
// $data['payment'] = null;
// $data['paid_at'] = now();
// }
$balance = $balance->create($data);
// 生成 18 位订单号
$order_id = date('YmdHis') . $balance->id . rand(1000, 9999);
$balance->order_id = $order_id;
$balance->save();
// $balances['pay_url'] = route('balances.balances.show', ['balances' => $balances['order_id']]);
return redirect()->route('balances.balances.show', ['balances' => $balance->order_id]);
}
/**
* @throws \Laravel\Octane\Exceptions\DdException
*/
public function show(Balance $balance)
{
if ($balance->paid_at !== null) {
return $this->error('订单已支付');
}
if (now()->diffInDays($balance->created_at) > 1) {
return $this->error('订单已失效');
}
$web = Pay::alipay()->web([
'out_trade_no' => $balance->order_id,
'total_amount' => $balance->amount,
'subject' => config('app.display_name') . ' 充值',
]);
return view('balances.pay', ['html' => (string)$web->getBody()]);
}
/**
* @throws ValidationException
*/
public function notify(Request $request): View|JsonResponse
{
$this->validate($request, [
'out_trade_no' => 'required',
]);
// 检测订单是否存在
$balance = Balance::where('order_id', $request->out_trade_no)->with('user')->first();
if (!$balance) {
abort(404, '找不到订单。');
}
// 检测订单是否已支付
if ($balance->paid_at !== null) {
// return $this->success('订单已支付');
return view('pay_process');
}
// try {
// $data = Pay::alipay()->callback();
// } catch (InvalidResponseException $e) {
// return $this->error('支付失败');
// }
// // 检测 out_trade_no 是否为商户系统中创建的订单号
// if ($data->out_trade_no != $balances->order_id) {
// return $this->error('订单号不一致');
// }
// if ((int) $data->total_amount != (int) $balances->amount) {
// throw new ChargeException('金额不一致');
// }
// // 验证 商户
// if ($data['app_id'] != config('balances.alipay.default.app_id')) {
// throw new ChargeException('商户不匹配');
// }
if ((new \App\Http\Controllers\Api\BalanceController())->checkAndCharge($balance, true)) {
return view('pay_process');
} else {
abort(500, '支付失败');
}
}
}

View File

@ -9,12 +9,13 @@ class Authenticate extends Middleware
/** /**
* Get the path the user should be redirected to when they are not authenticated. * Get the path the user should be redirected to when they are not authenticated.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
*
* @return string|null * @return string|null
*/ */
protected function redirectTo($request) protected function redirectTo($request)
{ {
if (! $request->expectsJson()) { if (!$request->expectsJson()) {
return route('index'); return route('index');
} }
} }

View File

@ -12,9 +12,10 @@ class RedirectIfAuthenticated
/** /**
* Handle an incoming request. * Handle an incoming request.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next * @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @param string|null ...$guards * @param string|null ...$guards
*
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/ */
public function handle(Request $request, Closure $next, ...$guards) public function handle(Request $request, Closure $next, ...$guards)

View File

@ -37,8 +37,8 @@ public function handle()
$this_month = Transaction::where('module_id', $module->id)->where('type', 'payout')->whereBetween('created_at', [$beginOfMonth, $endOfMonth]); $this_month = Transaction::where('module_id', $module->id)->where('type', 'payout')->whereBetween('created_at', [$beginOfMonth, $endOfMonth]);
// this month transactions // this month transactions
$this_month = [ $this_month = [
'balance' => $this_month->sum('outcome'), 'balances' => $this_month->sum('outcome'),
'drops' => $this_month->sum('outcome_drops') 'drops' => $this_month->sum('outcome_drops')
]; ];
@ -47,8 +47,8 @@ public function handle()
// last month transactions // last month transactions
$last_moth = Transaction::where('module_id', $module->id)->where('type', 'payout')->whereBetween('created_at', [$beginOfMonth, $endOfMonth]); $last_moth = Transaction::where('module_id', $module->id)->where('type', 'payout')->whereBetween('created_at', [$beginOfMonth, $endOfMonth]);
$last_moth = [ $last_moth = [
'balance' => $last_moth->sum('outcome'), 'balances' => $last_moth->sum('outcome'),
'drops' => $last_moth->sum('outcome_drops') 'drops' => $last_moth->sum('outcome_drops')
]; ];

View File

@ -17,6 +17,7 @@ class Host implements ShouldQueue
public HostModel $host; public HostModel $host;
public string $type; public string $type;
/** /**
* Create a new job instance. * Create a new job instance.
* *

View File

@ -17,6 +17,7 @@ class Reply implements ShouldQueue
use InteractsWithQueue, Queueable, SerializesModels; use InteractsWithQueue, Queueable, SerializesModels;
protected $reply; protected $reply;
/** /**
* Create a new job instance. * Create a new job instance.
* *

View File

@ -23,7 +23,7 @@ class WorkOrder implements ShouldQueue
* *
* @return void * @return void
*/ */
public function __construct(WorkOrderWorkOrder $workOrder, $type = 'post') public function __construct(WorkOrderWorkOrder $workOrder, $type = 'post')
{ {
// //
$this->workOrder = $workOrder; $this->workOrder = $workOrder;

View File

@ -2,8 +2,8 @@
namespace App\Models; namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable class Admin extends Authenticatable
{ {

View File

@ -38,6 +38,55 @@ class Host extends Model
// get user hosts // get user hosts
protected static function boot()
{
parent::boot();
static::created(function ($model) {
broadcast(new UserEvent($model->user_id, 'hosts.created', $model));
});
static::updating(function ($model) {
if ($model->status == 'suspended') {
$model->suspended_at = now();
} else if ($model->status == 'running') {
$model->suspended_at = null;
}
broadcast(new UserEvent($model->user_id, 'hosts.updating', $model));
});
// when Updated
static::updated(function ($model) {
dispatch(new \App\Jobs\Module\Host($model, 'patch'));
Cache::forget('user_hosts_' . $model->user_id);
Cache::forget('user_tasks_' . $model->user_id);
broadcast(new UserEvent($model->user_id, 'hosts.updated', $model));
});
//
// static::deleting(function ($model) {
// broadcast(new UserEvent($model->user_id, 'hosts.deleting', $model));
// });
static::deleting(function ($model) {
Cache::forget('user_tasks_' . $model->user_id);
});
static::deleted(function ($model) {
broadcast(new UserEvent($model->user_id, 'hosts.deleted', $model));
Cache::forget('user_tasks_' . $model->user_id);
Cache::forget('user_hosts_' . $model->user_id);
});
}
// user
public function getUserHosts($user_id = null) public function getUserHosts($user_id = null)
{ {
return $this->where('user_id', $user_id)->with('module', function ($query) { return $this->where('user_id', $user_id)->with('module', function ($query) {
@ -45,31 +94,35 @@ public function getUserHosts($user_id = null)
})->get(); })->get();
} }
// module
// user
public function user(): BelongsToAlias public function user(): BelongsToAlias
{ {
return $this->belongsTo(User::class); return $this->belongsTo(User::class);
} }
// module // workOrders
public function module(): BelongsToAlias public function module(): BelongsToAlias
{ {
return $this->belongsTo(Module::class); return $this->belongsTo(Module::class);
} }
// workOrders // scope
public function workOrders(): HasManyAlias public function workOrders(): HasManyAlias
{ {
return $this->hasMany(WorkOrder::class); return $this->hasMany(WorkOrder::class);
} }
// scope
public function scopeActive($query) public function scopeActive($query)
{ {
return $query->where('status', 'running')->where('price', '!=', 0); return $query->where('status', 'running')->where('price', '!=', 0);
} }
// cost
public function scopeThisUser($query, $module = null) public function scopeThisUser($query, $module = null)
{ {
if ($module) { if ($module) {
@ -79,8 +132,6 @@ public function scopeThisUser($query, $module = null)
} }
} }
// cost
public function cost($price = null, $auto = true): bool public function cost($price = null, $auto = true): bool
{ {
$this->load('user'); $this->load('user');
@ -154,8 +205,7 @@ public function cost($price = null, $auto = true): bool
return true; return true;
} }
public function costBalance($amount = 1): bool
public function costBalance($amount = 1)
{ {
$transaction = new Transaction(); $transaction = new Transaction();
@ -185,49 +235,4 @@ public function costBalance($amount = 1)
return true; return true;
} }
protected static function boot()
{
parent::boot();
static::created(function ($model) {
broadcast(new UserEvent($model->user_id, 'hosts.created', $model));
});
static::updating(function ($model) {
if ($model->status == 'suspended') {
$model->suspended_at = now();
} else if ($model->status == 'running') {
$model->suspended_at = null;
}
broadcast(new UserEvent($model->user_id, 'hosts.updating', $model));
});
// when Updated
static::updated(function ($model) {
dispatch(new \App\Jobs\Module\Host($model, 'patch'));
Cache::forget('user_hosts_' . $model->user_id);
Cache::forget('user_tasks_' . $model->user_id);
broadcast(new UserEvent($model->user_id, 'hosts.updated', $model));
});
//
// static::deleting(function ($model) {
// broadcast(new UserEvent($model->user_id, 'hosts.deleting', $model));
// });
static::deleting(function ($model) {
Cache::forget('user_tasks_' . $model->user_id);
});
static::deleted(function ($model) {
broadcast(new UserEvent($model->user_id, 'hosts.deleted', $model));
Cache::forget('user_tasks_' . $model->user_id);
Cache::forget('user_hosts_' . $model->user_id);
});
}
} }

View File

@ -13,13 +13,12 @@ class Module extends Authenticatable
{ {
use Cachable; use Cachable;
protected $table = 'modules'; public $incrementing = false;
// primary key // primary key
public $incrementing = false;
protected $keyType = 'string';
public $timestamps = false; public $timestamps = false;
protected $table = 'modules';
protected $keyType = 'string';
protected $fillable = [ protected $fillable = [
'id', 'id',
'name', 'name',
@ -32,6 +31,16 @@ class Module extends Authenticatable
'wecom_key' 'wecom_key'
]; ];
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
// if local
if (!app()->environment('local')) {
$model->api_token = Str::random(60);
}
});
}
public function remoteHost($host_id, $func, $requests) public function remoteHost($host_id, $func, $requests)
{ {
@ -44,6 +53,9 @@ public function remoteHost($host_id, $func, $requests)
return [$json, $status]; return [$json, $status];
} }
// post, get, patch, delete 等请求
public function remote($func, $requests) public function remote($func, $requests)
{ {
$http = Http::module($this->api_token, $this->url); $http = Http::module($this->api_token, $this->url);
@ -55,8 +67,6 @@ public function remote($func, $requests)
return [$json, $status]; return [$json, $status];
} }
// post, get, patch, delete 等请求
public function remoteRequest($method, $path, $requests) public function remoteRequest($method, $path, $requests)
{ {
$user = auth()->user(); $user = auth()->user();
@ -115,8 +125,6 @@ public function moduleRequest($method, $path, $requests)
]; ];
} }
public function remotePost($path = '', $data = []) public function remotePost($path = '', $data = [])
{ {
$http = Http::module($this->api_token, $this->url); $http = Http::module($this->api_token, $this->url);
@ -128,6 +136,15 @@ public function remotePost($path = '', $data = [])
return [$json, $status]; return [$json, $status];
} }
// // get cached modules
// public static function cached_modules()
// {
// return Cache::remember('modules', 600, function () {
// return Module::all();
// });
// }
public function check($module_id = null) public function check($module_id = null)
{ {
if ($module_id) { if ($module_id) {
@ -150,24 +167,4 @@ public function check($module_id = null)
return false; return false;
} }
} }
// // get cached modules
// public static function cached_modules()
// {
// return Cache::remember('modules', 600, function () {
// return Module::all();
// });
// }
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
// if local
if (!app()->environment('local')) {
$model->api_token = Str::random(60);
}
});
}
} }

View File

@ -16,7 +16,8 @@ class PersonalAccessToken extends SanctumPersonalAccessToken
* the last_used_at column that has changed. It prevents extra DB writes * the last_used_at column that has changed. It prevents extra DB writes
* since we aren't going to use that column for anything. * since we aren't going to use that column for anything.
* *
* @param array $options * @param array $options
*
* @return bool * @return bool
*/ */
public function save(array $options = []) public function save(array $options = [])

View File

@ -16,43 +16,21 @@ class Task extends Model
{ {
use HasFactory, Cachable; use HasFactory, Cachable;
public $incrementing = false;
protected $fillable = [ protected $fillable = [
'host_id', 'host_id',
'title', 'title',
'progress', 'progress',
'status', 'status',
]; ];
protected $casts = [ protected $casts = [
'id' => 'string', 'id' => 'string',
'progress' => 'integer', 'progress' => 'integer',
]; ];
public $incrementing = false;
// key type string // key type string
protected $keyType = 'string'; protected $keyType = 'string';
public function scopeUser($query)
{
return $query->where('user_id', auth()->id());
}
public function getCurrentUserTasks()
{
return Cache::remember('user_tasks_' . auth()->id(), 3600, function () {
return $this->user()->with('host')->latest()->get();
});
}
public function host()
{
return $this->belongsTo(Host::class);
}
// before create
protected static function boot() protected static function boot()
{ {
parent::boot(); parent::boot();
@ -82,7 +60,6 @@ protected static function boot()
// dd($host); // dd($host);
$model->user_id = $model->host->user_id; $model->user_id = $model->host->user_id;
Cache::forget('user_tasks_' . $model->user_id); Cache::forget('user_tasks_' . $model->user_id);
@ -117,4 +94,23 @@ protected static function boot()
broadcast(new UserEvent($model->user_id, 'tasks.deleted', $model)); broadcast(new UserEvent($model->user_id, 'tasks.deleted', $model));
}); });
} }
public function scopeUser($query)
{
return $query->where('user_id', auth()->id());
}
public function getCurrentUserTasks()
{
return Cache::remember('user_tasks_' . auth()->id(), 3600, function () {
return $this->user()->with('host')->latest()->get();
});
}
// before create
public function host()
{
return $this->belongsTo(Host::class);
}
} }

View File

@ -13,12 +13,11 @@ class Transaction extends Model
{ {
// $t = (new App\Models\Transaction)->create(['name' => 1]) // $t = (new App\Models\Transaction)->create(['name' => 1])
const UPDATED_AT = null;
protected $connection = 'mongodb'; protected $connection = 'mongodb';
protected $collection = 'transactions';
// 停用 updated_at // 停用 updated_at
const UPDATED_AT = null; protected $collection = 'transactions';
protected $dates = [ protected $dates = [
'created_at', 'created_at',
'updated_at', 'updated_at',
@ -70,32 +69,11 @@ public function scopeThisUser($query)
return $query->where('user_id', auth()->id()); return $query->where('user_id', auth()->id());
} }
public function getDrops($user_id = null): float
{
//
if (!$user_id) {
$user_id = auth()->id();
}
$cache_key = 'user_drops_' . $user_id;
$drops = Cache::get($cache_key, [
'drops' => 0,
]);
// 保留 8 位
$drops['drops'] = round($drops['drops'], 8);
return $drops['drops'];
}
public function increaseCurrentUserDrops($amount = 0) public function increaseCurrentUserDrops($amount = 0)
{ {
return $this->increaseDrops(auth()->id(), $amount); return $this->increaseDrops(auth()->id(), $amount);
} }
public function increaseDrops($user_id, $amount = 0) public function increaseDrops($user_id, $amount = 0)
{ {
$cache_key = 'user_drops_' . $user_id; $cache_key = 'user_drops_' . $user_id;
@ -111,7 +89,6 @@ public function increaseDrops($user_id, $amount = 0)
return $current_drops['drops']; return $current_drops['drops'];
} }
public function reduceDrops($user_id, $host_id, $module_id, $auto = 1, $amount = 0) public function reduceDrops($user_id, $host_id, $module_id, $auto = 1, $amount = 0)
{ {
@ -136,7 +113,6 @@ public function reduceDrops($user_id, $host_id, $module_id, $auto = 1, $amount =
$this->addPayoutDrops($user_id, $amount, $description, $host_id, $module_id); $this->addPayoutDrops($user_id, $amount, $description, $host_id, $module_id);
} }
public function addPayoutDrops($user_id, $amount, $description, $host_id, $module_id) public function addPayoutDrops($user_id, $amount, $description, $host_id, $module_id)
{ {
$data = [ $data = [
@ -163,186 +139,6 @@ public function addPayoutDrops($user_id, $amount, $description, $host_id, $modul
return $this->addLog($user_id, $data); return $this->addLog($user_id, $data);
} }
public function addIncomeDrops($user_id, $amount, $description)
{
$data = [
'type' => 'income',
'payment' => 'balances',
'description' => $description,
'income' => 0,
'income_drops' => (float)$amount,
'outcome' => 0,
'outcome_drops' => 0,
];
return $this->addLog($user_id, $data);
}
public function addIncomeBalances($user_id, $payment, $amount, $description)
{
$data = [
'type' => 'income',
'payment' => $payment,
'description' => $description,
'income' => (float)$amount,
'income_drops' => 0,
'outcome' => 0,
'outcome_drops' => 0,
];
return $this->addLog($user_id, $data);
}
public function addPayoutBalances($user_id, $amount, $description, $module_id = null)
{
$data = [
'type' => 'payout',
'payment' => 'balances',
'description' => $description,
'income' => 0,
'income_drops' => 0,
'outcome' => (float)$amount,
'outcome_drops' => 0
];
if ($module_id) {
$data['module_id'] = $module_id;
}
return $this->addLog($user_id, $data);
}
public function addHostPayoutBalances($user_id, $host_id, $module_id, $amount, $description)
{
$data = [
'type' => 'payout',
'payment' => 'balances',
'description' => $description,
'income' => 0,
'income_drops' => 0,
'outcome' => (float)$amount,
'outcome_drops' => 0,
'host_id' => $host_id,
'module_id' => $module_id,
];
return $this->addLog($user_id, $data);
}
public function reduceAmount($user_id, $amount = 0, $description = '扣除费用请求。')
{
$lock = Cache::lock("user_balances_lock_" . $user_id, 10);
try {
$lock->block(5);
$user = User::findOrFail($user_id);
$user->balances -= $amount;
$user->save();
$this->addPayoutBalances($user_id, $amount, $description);
return $user->balances;
} finally {
optional($lock)->release();
}
return false;
}
public function reduceAmountModuleFail($user_id, $module_id, $amount = 0, $description = '扣除费用请求。')
{
$lock = Cache::lock("user_balances_lock_" . $user_id, 10);
try {
$lock->block(5);
$user = User::findOrFail($user_id);
$user->balances -= $amount;
// if balances < 0
if ($user->balances < 0) {
throw new BalanceNotEnoughException('余额不足。');
}
$user->save();
$this->addPayoutBalances($user_id, $amount, $description, $module_id);
return $user->balances;
} finally {
optional($lock)->release();
}
return false;
}
public function reduceHostAmount($user_id, $host_id, $module_id, $amount = 0, $description = '扣除费用请求。')
{
$lock = Cache::lock("user_balances_lock_" . $user_id, 10);
try {
$lock->block(5);
$user = User::findOrFail($user_id);
$user->balances -= $amount;
$user->save();
$this->addHostPayoutBalances($user_id, $host_id, $module_id, $amount, $description);
return $user->balances;
} finally {
optional($lock)->release();
}
return false;
}
/**
* @throws ChargeException
*/
public function addAmount($user_id, $payment = 'console', $amount = 0, $description = null)
{
$lock = Cache::lock("user_balances_lock_" . $user_id, 10);
try {
$lock->block(5);
$user = User::findOrFail($user_id);
$left_balances = $user->balances + $amount;
$user->increment('balances', $amount);
if (!$description) {
$description = '充值金额。';
} else {
$description = '充值 ' . $amount . ' 元';
}
$this->addIncomeBalances($user_id, $payment, $amount, $description);
return $left_balances;
} catch (LockTimeoutException $e) {
Log::error($e);
throw new ChargeException('充值失败,请稍后再试。');
} finally {
optional($lock)->release();
}
return false;
}
private function addLog($user_id, $data) private function addLog($user_id, $data)
{ {
$user = User::find($user_id); $user = User::find($user_id);
@ -362,4 +158,199 @@ private function addLog($user_id, $data)
return $this->create($data); return $this->create($data);
} }
public function getDrops($user_id = null): float
{
//
if (!$user_id) {
$user_id = auth()->id();
}
$cache_key = 'user_drops_' . $user_id;
$drops = Cache::get($cache_key, [
'drops' => 0,
]);
// 保留 8 位
$drops['drops'] = round($drops['drops'], 8);
return $drops['drops'];
}
public function addIncomeDrops($user_id, $amount, $description)
{
$data = [
'type' => 'income',
'payment' => 'balances',
'description' => $description,
'income' => 0,
'income_drops' => (float)$amount,
'outcome' => 0,
'outcome_drops' => 0,
];
return $this->addLog($user_id, $data);
}
public function reduceAmount($user_id, $amount = 0, $description = '扣除费用请求。')
{
$lock = Cache::lock("user_balance_lock_" . $user_id, 10);
try {
$lock->block(5);
$user = User::findOrFail($user_id);
$user->balance -= $amount;
$user->save();
$this->addPayoutBalance($user_id, $amount, $description);
return $user->balance;
} finally {
optional($lock)->release();
}
return false;
}
public function addPayoutBalance($user_id, $amount, $description, $module_id = null)
{
$data = [
'type' => 'payout',
'payment' => 'balances',
'description' => $description,
'income' => 0,
'income_drops' => 0,
'outcome' => (float)$amount,
'outcome_drops' => 0
];
if ($module_id) {
$data['module_id'] = $module_id;
}
return $this->addLog($user_id, $data);
}
public function reduceAmountModuleFail($user_id, $module_id, $amount = 0, $description = '扣除费用请求。')
{
$lock = Cache::lock("user_balance_lock_" . $user_id, 10);
try {
$lock->block(5);
$user = User::findOrFail($user_id);
$user->balance -= $amount;
// if balance < 0
if ($user->balance < 0) {
throw new BalanceNotEnoughException('余额不足。');
}
$user->save();
$this->addPayoutBalance($user_id, $amount, $description, $module_id);
return $user->balance;
} finally {
optional($lock)->release();
}
return false;
}
public function reduceHostAmount($user_id, $host_id, $module_id, $amount = 0, $description = '扣除费用请求。')
{
$lock = Cache::lock("user_balance_lock_" . $user_id, 10);
try {
$lock->block(5);
$user = User::findOrFail($user_id);
$user->balance -= $amount;
$user->save();
$this->addHostPayoutBalance($user_id, $host_id, $module_id, $amount, $description);
return $user->balance;
} finally {
optional($lock)->release();
}
return false;
}
public function addHostPayoutBalance($user_id, $host_id, $module_id, $amount, $description)
{
$data = [
'type' => 'payout',
'payment' => 'balances',
'description' => $description,
'income' => 0,
'income_drops' => 0,
'outcome' => (float)$amount,
'outcome_drops' => 0,
'host_id' => $host_id,
'module_id' => $module_id,
];
return $this->addLog($user_id, $data);
}
/**
* @throws ChargeException
*/
public function addAmount($user_id, $payment = 'console', $amount = 0, $description = null)
{
$lock = Cache::lock("user_balance_lock_" . $user_id, 10);
try {
$lock->block(5);
$user = User::findOrFail($user_id);
$left_balance = $user->balance + $amount;
$user->increment('balance', $amount);
if (!$description) {
$description = '充值金额。';
} else {
$description = '充值 ' . $amount . ' 元';
}
$this->addIncomeBalance($user_id, $payment, $amount, $description);
return $left_balance;
} catch (LockTimeoutException $e) {
Log::error($e);
throw new ChargeException('充值失败,请稍后再试。');
} finally {
optional($lock)->release();
}
return false;
}
public function addIncomeBalance($user_id, $payment, $amount, $description)
{
$data = [
'type' => 'income',
'payment' => $payment,
'description' => $description,
'income' => (float)$amount,
'income_drops' => 0,
'outcome' => 0,
'outcome_drops' => 0,
];
return $this->addLog($user_id, $data);
}
} }

View File

@ -44,7 +44,21 @@ class User extends Authenticatable
'banned_at' => 'datetime', 'banned_at' => 'datetime',
]; ];
protected static function boot()
{
parent::boot();
static::updating(function ($model) {
// balance 四舍五入
$model->balance = round($model->balance, 2);
});
}
/**
* @throws CommonException
* @throws BalanceNotEnoughException
*/
public function toDrops($amount = 1) public function toDrops($amount = 1)
{ {
@ -98,15 +112,4 @@ public function toDrops($amount = 1)
return $this; return $this;
} }
protected static function boot()
{
parent::boot();
static::updating(function ($model) {
// balance 四舍五入
$model->balance = round($model->balance, 2);
});
}
} }

View File

@ -22,23 +22,6 @@ class Reply extends Model
'is_pending', 'is_pending',
]; ];
public function workOrder()
{
return $this->belongsTo(WorkOrder::class, 'work_order_id', 'id');
}
public function user()
{
return $this->belongsTo(User::class);
}
public function scopeWorkOrderId($query, $work_order_id)
{
return $query->where('work_order_id', $work_order_id);
}
// before create
protected static function boot() protected static function boot()
{ {
parent::boot(); parent::boot();
@ -79,4 +62,22 @@ protected static function boot()
dispatch(new \App\Jobs\Module\WorkOrder\WorkOrder($model->workOrder, 'put')); dispatch(new \App\Jobs\Module\WorkOrder\WorkOrder($model->workOrder, 'put'));
}); });
} }
public function workOrder()
{
return $this->belongsTo(WorkOrder::class, 'work_order_id', 'id');
}
public function user()
{
return $this->belongsTo(User::class);
}
// before create
public function scopeWorkOrderId($query, $work_order_id)
{
return $query->where('work_order_id', $work_order_id);
}
} }

View File

@ -26,41 +26,7 @@ class WorkOrder extends Model
]; ];
// user // user
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(User::class);
}
// replies
public function replies(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(Reply::class);
}
// host
public function host(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Host::class);
}
public function module(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Module::class);
}
// scope
public function scopeThisModule($query)
{
return $query->where('module_id', auth('module')->id());
}
public function scopeThisUser($query)
{
return $query->where('user_id', auth()->id());
}
// on create
protected static function boot() protected static function boot()
{ {
parent::boot(); parent::boot();
@ -104,4 +70,43 @@ protected static function boot()
dispatch(new \App\Jobs\Module\WorkOrder\WorkOrder($model, 'put')); dispatch(new \App\Jobs\Module\WorkOrder\WorkOrder($model, 'put'));
}); });
} }
// replies
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(User::class);
}
// host
public function replies(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(Reply::class);
}
public function host(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Host::class);
}
// scope
public function module(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Module::class);
}
public function scopeThisModule($query)
{
return $query->where('module_id', auth('module')->id());
}
// on create
public function scopeThisUser($query)
{
return $query->where('user_id', auth()->id());
}
} }

View File

@ -27,7 +27,8 @@ public function __construct(Module $module)
/** /**
* Get the mail representation of the notification. * Get the mail representation of the notification.
* *
* @param mixed $notifiable * @param mixed $notifiable
*
* @return \Illuminate\Notifications\Messages\MailMessage * @return \Illuminate\Notifications\Messages\MailMessage
*/ */
public function toGroup($notifiable) public function toGroup($notifiable)

View File

@ -27,7 +27,8 @@ public function __construct()
/** /**
* Get the notification's delivery channels. * Get the notification's delivery channels.
* *
* @param mixed $notifiable * @param mixed $notifiable
*
* @return array * @return array
*/ */
public function via($notifiable) public function via($notifiable)
@ -49,7 +50,7 @@ public function toGroup($notifiable)
$data = [ $data = [
'balance' => $notifiable, 'balances' => $notifiable,
'user' => $user, 'user' => $user,
]; ];

View File

@ -28,7 +28,8 @@ public function __construct()
/** /**
* Get the notification's delivery channels. * Get the notification's delivery channels.
* *
* @param mixed $notifiable * @param mixed $notifiable
*
* @return array * @return array
*/ */
public function via($notifiable) public function via($notifiable)
@ -49,7 +50,7 @@ public function toGroup($notifiable)
$workOrder->load(['module', 'user']); $workOrder->load(['module', 'user']);
$module = $workOrder->module; $module = $workOrder->module;
} elseif ($notifiable instanceof Reply) { } else if ($notifiable instanceof Reply) {
$view = 'notifications.work_order.reply'; $view = 'notifications.work_order.reply';

View File

@ -10,33 +10,36 @@ class BalanceObserve
/** /**
* Handle the Balance "created" event. * Handle the Balance "created" event.
* *
* @param \App\Models\Balance $balance * @param \App\Models\Balance $balance
*
* @return void * @return void
*/ */
public function created(Balance $balance) public function created(Balance $balance)
{ {
// //
return (new UserBalanceNotification()) return (new UserBalanceNotification())
->toGroup($balance); ->toGroup($balance);
} }
/** /**
* Handle the Balance "updated" event. * Handle the Balance "updated" event.
* *
* @param \App\Models\Balance $balance * @param \App\Models\Balance $balance
*
* @return void * @return void
*/ */
public function updated(Balance $balance) public function updated(Balance $balance)
{ {
// //
return (new UserBalanceNotification()) return (new UserBalanceNotification())
->toGroup($balance); ->toGroup($balance);
} }
/** /**
* Handle the Balance "deleted" event. * Handle the Balance "deleted" event.
* *
* @param \App\Models\Balance $balance * @param \App\Models\Balance $balance
*
* @return void * @return void
*/ */
public function deleted(Balance $balance) public function deleted(Balance $balance)
@ -47,7 +50,8 @@ public function deleted(Balance $balance)
/** /**
* Handle the Balance "restored" event. * Handle the Balance "restored" event.
* *
* @param \App\Models\Balance $balance * @param \App\Models\Balance $balance
*
* @return void * @return void
*/ */
public function restored(Balance $balance) public function restored(Balance $balance)
@ -58,7 +62,8 @@ public function restored(Balance $balance)
/** /**
* Handle the Balance "force deleted" event. * Handle the Balance "force deleted" event.
* *
* @param \App\Models\Balance $balance * @param \App\Models\Balance $balance
*
* @return void * @return void
*/ */
public function forceDeleted(Balance $balance) public function forceDeleted(Balance $balance)

View File

@ -10,7 +10,8 @@ class ReplyObserver
/** /**
* Handle the Reply "created" event. * Handle the Reply "created" event.
* *
* @param \App\Models\WorkOrder\Reply $reply * @param \App\Models\WorkOrder\Reply $reply
*
* @return void * @return void
*/ */
public function created(Reply $reply) public function created(Reply $reply)
@ -23,7 +24,8 @@ public function created(Reply $reply)
/** /**
* Handle the Reply "updated" event. * Handle the Reply "updated" event.
* *
* @param \App\Models\WorkOrder\Reply $reply * @param \App\Models\WorkOrder\Reply $reply
*
* @return void * @return void
*/ */
public function updated(Reply $reply) public function updated(Reply $reply)
@ -34,7 +36,8 @@ public function updated(Reply $reply)
/** /**
* Handle the Reply "deleted" event. * Handle the Reply "deleted" event.
* *
* @param \App\Models\WorkOrder\Reply $reply * @param \App\Models\WorkOrder\Reply $reply
*
* @return void * @return void
*/ */
public function deleted(Reply $reply) public function deleted(Reply $reply)
@ -45,7 +48,8 @@ public function deleted(Reply $reply)
/** /**
* Handle the Reply "restored" event. * Handle the Reply "restored" event.
* *
* @param \App\Models\WorkOrder\Reply $reply * @param \App\Models\WorkOrder\Reply $reply
*
* @return void * @return void
*/ */
public function restored(Reply $reply) public function restored(Reply $reply)
@ -56,7 +60,8 @@ public function restored(Reply $reply)
/** /**
* Handle the Reply "force deleted" event. * Handle the Reply "force deleted" event.
* *
* @param \App\Models\WorkOrder\Reply $reply * @param \App\Models\WorkOrder\Reply $reply
*
* @return void * @return void
*/ */
public function forceDeleted(Reply $reply) public function forceDeleted(Reply $reply)

View File

@ -11,7 +11,8 @@ class WorkOrderObserver
/** /**
* Handle the WorkOrder "created" event. * Handle the WorkOrder "created" event.
* *
* @param \App\Models\WorkOrder\WorkOrder $workOrder * @param \App\Models\WorkOrder\WorkOrder $workOrder
*
* @return void * @return void
*/ */
public function created(WorkOrder $workOrder) public function created(WorkOrder $workOrder)
@ -24,7 +25,8 @@ public function created(WorkOrder $workOrder)
/** /**
* Handle the WorkOrder "updated" event. * Handle the WorkOrder "updated" event.
* *
* @param \App\Models\WorkOrder\WorkOrder $workOrder * @param \App\Models\WorkOrder\WorkOrder $workOrder
*
* @return void * @return void
*/ */
public function updated(WorkOrder $workOrder) public function updated(WorkOrder $workOrder)
@ -39,7 +41,8 @@ public function updated(WorkOrder $workOrder)
/** /**
* Handle the WorkOrder "deleted" event. * Handle the WorkOrder "deleted" event.
* *
* @param \App\Models\WorkOrder\WorkOrder $workOrder * @param \App\Models\WorkOrder\WorkOrder $workOrder
*
* @return void * @return void
*/ */
public function deleted(WorkOrder $workOrder) public function deleted(WorkOrder $workOrder)
@ -50,7 +53,8 @@ public function deleted(WorkOrder $workOrder)
/** /**
* Handle the WorkOrder "restored" event. * Handle the WorkOrder "restored" event.
* *
* @param \App\Models\WorkOrder\WorkOrder $workOrder * @param \App\Models\WorkOrder\WorkOrder $workOrder
*
* @return void * @return void
*/ */
public function restored(WorkOrder $workOrder) public function restored(WorkOrder $workOrder)
@ -61,7 +65,8 @@ public function restored(WorkOrder $workOrder)
/** /**
* Handle the WorkOrder "force deleted" event. * Handle the WorkOrder "force deleted" event.
* *
* @param \App\Models\WorkOrder\WorkOrder $workOrder * @param \App\Models\WorkOrder\WorkOrder $workOrder
*
* @return void * @return void
*/ */
public function forceDeleted(WorkOrder $workOrder) public function forceDeleted(WorkOrder $workOrder)

View File

@ -15,9 +15,9 @@ define('LARAVEL_START', microtime(true));
| |
*/ */
require __DIR__.'/vendor/autoload.php'; require __DIR__ . '/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php'; $app = require_once __DIR__ . '/bootstrap/app.php';
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View File

@ -42,7 +42,7 @@
| |
*/ */
'debug' => (bool) env('APP_DEBUG', false), 'debug' => (bool)env('APP_DEBUG', false),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -141,7 +141,7 @@
'maintenance' => [ 'maintenance' => [
'driver' => 'cache', 'driver' => 'cache',
'store' => 'redis', 'store' => 'redis',
], ],
/* /*

View File

@ -36,7 +36,7 @@
'secret' => env('PUSHER_APP_SECRET'), 'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'), 'app_id' => env('PUSHER_APP_ID'),
'options' => [ 'options' => [
'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com', 'host' => env('PUSHER_HOST') ?: 'api-' . env('PUSHER_APP_CLUSTER', 'mt1') . '.pusher.com',
'port' => env('PUSHER_PORT', 443), 'port' => env('PUSHER_PORT', 443),
'scheme' => env('PUSHER_SCHEME', 'https'), 'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true, 'encrypted' => true,

View File

@ -39,7 +39,7 @@
'public' => [ 'public' => [
'driver' => 'local', 'driver' => 'local',
'root' => storage_path('app/public'), 'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage', 'url' => env('APP_URL') . '/storage',
'visibility' => 'public', 'visibility' => 'public',
'throw' => false, 'throw' => false,
], ],

View File

@ -85,7 +85,7 @@
'handler_with' => [ 'handler_with' => [
'host' => env('PAPERTRAIL_URL'), 'host' => env('PAPERTRAIL_URL'),
'port' => env('PAPERTRAIL_PORT'), 'port' => env('PAPERTRAIL_PORT'),
'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), 'connectionString' => 'tls://' . env('PAPERTRAIL_URL') . ':' . env('PAPERTRAIL_PORT'),
], ],
], ],

View File

@ -85,7 +85,7 @@
'connect_timeout' => 5.0, 'connect_timeout' => 5.0,
// 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html) // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
], ],
// optional默认 warning日志路径为sys_get_temp_dir().'/logs/yansongda.pay.log' // optional默认 warning日志路径为sys_get_temp_dir().'/logs/yansongda.balances.log'
'logger' => [ 'logger' => [
'enable' => false, 'enable' => false,
'file' => null, 'file' => null,

View File

@ -128,7 +128,7 @@
'cookie' => env( 'cookie' => env(
'SESSION_COOKIE', 'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session' Str::slug(env('APP_NAME', 'laravel'), '_') . '_session'
), ),
/* /*

View File

@ -33,7 +33,7 @@ public function definition()
*/ */
public function unverified() public function unverified()
{ {
return $this->state(fn (array $attributes) => [ return $this->state(fn(array $attributes) => [
'email_verified_at' => null, 'email_verified_at' => null,
]); ]);
} }

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -5,8 +5,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *
@ -17,7 +16,7 @@ public function up()
Schema::create('drops', function (Blueprint $table) { Schema::create('drops', function (Blueprint $table) {
$table->id(); $table->id();
// payment // payment
$table->string('payment')->index(); $table->string('payment')->index();
// amount // amount

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -5,8 +5,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -5,8 +5,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *
@ -15,7 +14,7 @@ public function up()
{ {
Schema::table('users', function (Blueprint $table) { Schema::table('users', function (Blueprint $table) {
// //
$table->decimal('balance', 10, 2)->default(0)->after('password'); $table->decimal('balances', 10, 2)->default(0)->after('password');
// drop column if exists // drop column if exists
if (Schema::hasColumn('users', 'drops')) { if (Schema::hasColumn('users', 'drops')) {
@ -33,7 +32,7 @@ public function down()
{ {
Schema::table('users', function (Blueprint $table) { Schema::table('users', function (Blueprint $table) {
// //
$table->dropColumn('balance'); $table->dropColumn('balances');
}); });
} }
}; };

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *
@ -15,7 +14,7 @@ public function up()
{ {
Schema::table('users', function (Blueprint $table) { Schema::table('users', function (Blueprint $table) {
// //
$table->dateTime('banned_at')->nullable()->comment('封禁时间')->after('balance'); $table->dateTime('banned_at')->nullable()->comment('封禁时间')->after('balances');
// reason // reason
$table->string('banned_reason')->nullable()->after('banned_at'); $table->string('banned_reason')->nullable()->after('banned_at');
}); });

View File

@ -3,8 +3,7 @@
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -3,8 +3,7 @@
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -4,8 +4,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -3,8 +3,7 @@
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
* *

View File

@ -1,7 +1,7 @@
<?php <?php
return [ return [
'failed' => '用户名或密码错误。', 'failed' => '用户名或密码错误。',
'password' => '密码错误', 'password' => '密码错误',
'throttle' => '您尝试的登录次数过多,请 :seconds 秒后再试。', 'throttle' => '您尝试的登录次数过多,请 :seconds 秒后再试。',
]; ];

View File

@ -1,6 +1,6 @@
<?php <?php
return [ return [
'next' => '下一页 &raquo;', 'next' => '下一页 &raquo;',
'previous' => '&laquo; 上一页', 'previous' => '&laquo; 上一页',
]; ];

View File

@ -1,9 +1,9 @@
<?php <?php
return [ return [
'reset' => '密码重置成功!', 'reset' => '密码重置成功!',
'sent' => '密码重置邮件已发送!', 'sent' => '密码重置邮件已发送!',
'throttled' => '请稍候再试。', 'throttled' => '请稍候再试。',
'token' => '密码重置令牌无效。', 'token' => '密码重置令牌无效。',
'user' => '找不到该邮箱对应的用户。', 'user' => '找不到该邮箱对应的用户。',
]; ];

View File

@ -1,204 +1,204 @@
<?php <?php
return [ return [
'accepted' => '您必须接受 :attribute。', 'accepted' => '您必须接受 :attribute。',
'accepted_if' => '当 :other 为 :value 时,必须接受 :attribute。', 'accepted_if' => '当 :other 为 :value 时,必须接受 :attribute。',
'active_url' => ':Attribute 不是一个有效的网址。', 'active_url' => ':Attribute 不是一个有效的网址。',
'after' => ':Attribute 必须要晚于 :date。', 'after' => ':Attribute 必须要晚于 :date。',
'after_or_equal' => ':Attribute 必须要等于 :date 或更晚。', 'after_or_equal' => ':Attribute 必须要等于 :date 或更晚。',
'alpha' => ':Attribute 只能由字母组成。', 'alpha' => ':Attribute 只能由字母组成。',
'alpha_dash' => ':Attribute 只能由字母、数字、短划线(-)和下划线(_)组成。', 'alpha_dash' => ':Attribute 只能由字母、数字、短划线(-)和下划线(_)组成。',
'alpha_num' => ':Attribute 只能由字母和数字组成。', 'alpha_num' => ':Attribute 只能由字母和数字组成。',
'array' => ':Attribute 必须是一个数组。', 'array' => ':Attribute 必须是一个数组。',
'before' => ':Attribute 必须要早于 :date。', 'before' => ':Attribute 必须要早于 :date。',
'before_or_equal' => ':Attribute 必须要等于 :date 或更早。', 'before_or_equal' => ':Attribute 必须要等于 :date 或更早。',
'between' => [ 'between' => [
'array' => ':Attribute 必须只有 :min - :max 个单元。', 'array' => ':Attribute 必须只有 :min - :max 个单元。',
'file' => ':Attribute 必须介于 :min - :max KB 之间。', 'file' => ':Attribute 必须介于 :min - :max KB 之间。',
'numeric' => ':Attribute 必须介于 :min - :max 之间。', 'numeric' => ':Attribute 必须介于 :min - :max 之间。',
'string' => ':Attribute 必须介于 :min - :max 个字符之间。', 'string' => ':Attribute 必须介于 :min - :max 个字符之间。',
], ],
'boolean' => ':Attribute 必须为布尔值。', 'boolean' => ':Attribute 必须为布尔值。',
'confirmed' => ':Attribute 两次输入不一致。', 'confirmed' => ':Attribute 两次输入不一致。',
'current_password' => '密码错误。', 'current_password' => '密码错误。',
'date' => ':Attribute 不是一个有效的日期。', 'date' => ':Attribute 不是一个有效的日期。',
'date_equals' => ':Attribute 必须要等于 :date。', 'date_equals' => ':Attribute 必须要等于 :date。',
'date_format' => ':Attribute 的格式必须为 :format。', 'date_format' => ':Attribute 的格式必须为 :format。',
'declined' => ':Attribute 必须是拒绝的。', 'declined' => ':Attribute 必须是拒绝的。',
'declined_if' => '当 :other 为 :value 时字段 :attribute 必须是拒绝的。', 'declined_if' => '当 :other 为 :value 时字段 :attribute 必须是拒绝的。',
'different' => ':Attribute 和 :other 必须不同。', 'different' => ':Attribute 和 :other 必须不同。',
'digits' => ':Attribute 必须是 :digits 位数字。', 'digits' => ':Attribute 必须是 :digits 位数字。',
'digits_between' => ':Attribute 必须是介于 :min 和 :max 位的数字。', 'digits_between' => ':Attribute 必须是介于 :min 和 :max 位的数字。',
'dimensions' => ':Attribute 图片尺寸不正确。', 'dimensions' => ':Attribute 图片尺寸不正确。',
'distinct' => ':Attribute 已经存在。', 'distinct' => ':Attribute 已经存在。',
'doesnt_end_with' => ':Attribute 不能以以下之一结尾: :values。', 'doesnt_end_with' => ':Attribute 不能以以下之一结尾: :values。',
'doesnt_start_with' => ':Attribute 不能以下列之一开头: :values。', 'doesnt_start_with' => ':Attribute 不能以下列之一开头: :values。',
'email' => ':Attribute 不是一个合法的邮箱。', 'email' => ':Attribute 不是一个合法的邮箱。',
'ends_with' => ':Attribute 必须以 :values 为结尾。', 'ends_with' => ':Attribute 必须以 :values 为结尾。',
'enum' => ':Attribute 值不正确。', 'enum' => ':Attribute 值不正确。',
'exists' => ':Attribute 不存在。', 'exists' => ':Attribute 不存在。',
'file' => ':Attribute 必须是文件。', 'file' => ':Attribute 必须是文件。',
'filled' => ':Attribute 不能为空。', 'filled' => ':Attribute 不能为空。',
'gt' => [ 'gt' => [
'array' => ':Attribute 必须多于 :value 个元素。', 'array' => ':Attribute 必须多于 :value 个元素。',
'file' => ':Attribute 必须大于 :value KB。', 'file' => ':Attribute 必须大于 :value KB。',
'numeric' => ':Attribute 必须大于 :value。', 'numeric' => ':Attribute 必须大于 :value。',
'string' => ':Attribute 必须多于 :value 个字符。', 'string' => ':Attribute 必须多于 :value 个字符。',
], ],
'gte' => [ 'gte' => [
'array' => ':Attribute 必须多于或等于 :value 个元素。', 'array' => ':Attribute 必须多于或等于 :value 个元素。',
'file' => ':Attribute 必须大于或等于 :value KB。', 'file' => ':Attribute 必须大于或等于 :value KB。',
'numeric' => ':Attribute 必须大于或等于 :value。', 'numeric' => ':Attribute 必须大于或等于 :value。',
'string' => ':Attribute 必须多于或等于 :value 个字符。', 'string' => ':Attribute 必须多于或等于 :value 个字符。',
], ],
'image' => ':Attribute 必须是图片。', 'image' => ':Attribute 必须是图片。',
'in' => '已选的属性 :attribute 无效。', 'in' => '已选的属性 :attribute 无效。',
'in_array' => ':Attribute 必须在 :other 中。', 'in_array' => ':Attribute 必须在 :other 中。',
'integer' => ':Attribute 必须是整数。', 'integer' => ':Attribute 必须是整数。',
'ip' => ':Attribute 必须是有效的 IP 地址。', 'ip' => ':Attribute 必须是有效的 IP 地址。',
'ipv4' => ':Attribute 必须是有效的 IPv4 地址。', 'ipv4' => ':Attribute 必须是有效的 IPv4 地址。',
'ipv6' => ':Attribute 必须是有效的 IPv6 地址。', 'ipv6' => ':Attribute 必须是有效的 IPv6 地址。',
'json' => ':Attribute 必须是正确的 JSON 格式。', 'json' => ':Attribute 必须是正确的 JSON 格式。',
'lt' => [ 'lt' => [
'array' => ':Attribute 必须少于 :value 个元素。', 'array' => ':Attribute 必须少于 :value 个元素。',
'file' => ':Attribute 必须小于 :value KB。', 'file' => ':Attribute 必须小于 :value KB。',
'numeric' => ':Attribute 必须小于 :value。', 'numeric' => ':Attribute 必须小于 :value。',
'string' => ':Attribute 必须少于 :value 个字符。', 'string' => ':Attribute 必须少于 :value 个字符。',
], ],
'lte' => [ 'lte' => [
'array' => ':Attribute 必须少于或等于 :value 个元素。', 'array' => ':Attribute 必须少于或等于 :value 个元素。',
'file' => ':Attribute 必须小于或等于 :value KB。', 'file' => ':Attribute 必须小于或等于 :value KB。',
'numeric' => ':Attribute 必须小于或等于 :value。', 'numeric' => ':Attribute 必须小于或等于 :value。',
'string' => ':Attribute 必须少于或等于 :value 个字符。', 'string' => ':Attribute 必须少于或等于 :value 个字符。',
], ],
'mac_address' => ':Attribute 必须是一个有效的 MAC 地址。', 'mac_address' => ':Attribute 必须是一个有效的 MAC 地址。',
'max' => [ 'max' => [
'array' => ':Attribute 最多只有 :max 个单元。', 'array' => ':Attribute 最多只有 :max 个单元。',
'file' => ':Attribute 不能大于 :max KB。', 'file' => ':Attribute 不能大于 :max KB。',
'numeric' => ':Attribute 不能大于 :max。', 'numeric' => ':Attribute 不能大于 :max。',
'string' => ':Attribute 不能大于 :max 个字符。', 'string' => ':Attribute 不能大于 :max 个字符。',
], ],
'max_digits' => ':Attribute 不能超过 :max 位数。', 'max_digits' => ':Attribute 不能超过 :max 位数。',
'mimes' => ':Attribute 必须是一个 :values 类型的文件。', 'mimes' => ':Attribute 必须是一个 :values 类型的文件。',
'mimetypes' => ':Attribute 必须是一个 :values 类型的文件。', 'mimetypes' => ':Attribute 必须是一个 :values 类型的文件。',
'min' => [ 'min' => [
'array' => ':Attribute 至少有 :min 个单元。', 'array' => ':Attribute 至少有 :min 个单元。',
'file' => ':Attribute 大小不能小于 :min KB。', 'file' => ':Attribute 大小不能小于 :min KB。',
'numeric' => ':Attribute 必须大于等于 :min。', 'numeric' => ':Attribute 必须大于等于 :min。',
'string' => ':Attribute 至少为 :min 个字符。', 'string' => ':Attribute 至少为 :min 个字符。',
], ],
'min_digits' => ':Attribute 必须至少有 :min 位数。', 'min_digits' => ':Attribute 必须至少有 :min 位数。',
'multiple_of' => ':Attribute 必须是 :value 中的多个值。', 'multiple_of' => ':Attribute 必须是 :value 中的多个值。',
'not_in' => '已选的属性 :attribute 非法。', 'not_in' => '已选的属性 :attribute 非法。',
'not_regex' => ':Attribute 的格式错误。', 'not_regex' => ':Attribute 的格式错误。',
'numeric' => ':Attribute 必须是一个数字。', 'numeric' => ':Attribute 必须是一个数字。',
'password' => [ 'password' => [
'letters' => ':Attribute 必须至少包含一个字母。', 'letters' => ':Attribute 必须至少包含一个字母。',
'mixed' => ':Attribute 必须至少包含一个大写字母和一个小写字母。', 'mixed' => ':Attribute 必须至少包含一个大写字母和一个小写字母。',
'numbers' => ':Attribute 必须至少包含一个数字。', 'numbers' => ':Attribute 必须至少包含一个数字。',
'symbols' => ':Attribute 必须至少包含一个符号。', 'symbols' => ':Attribute 必须至少包含一个符号。',
'uncompromised' => '给定的 :attribute 出现在数据泄漏中。请选择不同的 :attribute。', 'uncompromised' => '给定的 :attribute 出现在数据泄漏中。请选择不同的 :attribute。',
], ],
'present' => ':Attribute 必须存在。', 'present' => ':Attribute 必须存在。',
'prohibited' => ':Attribute 字段被禁止。', 'prohibited' => ':Attribute 字段被禁止。',
'prohibited_if' => '当 :other 为 :value 时,禁止 :attribute 字段。', 'prohibited_if' => '当 :other 为 :value 时,禁止 :attribute 字段。',
'prohibited_unless' => ':Attribute 字段被禁止,除非 :other 位于 :values 中。', 'prohibited_unless' => ':Attribute 字段被禁止,除非 :other 位于 :values 中。',
'prohibits' => ':Attribute 字段禁止出现 :other。', 'prohibits' => ':Attribute 字段禁止出现 :other。',
'regex' => ':Attribute 格式不正确。', 'regex' => ':Attribute 格式不正确。',
'required' => ':Attribute 不能为空。', 'required' => ':Attribute 不能为空。',
'required_array_keys' => ':Attribute 至少包含指定的键::values.', 'required_array_keys' => ':Attribute 至少包含指定的键::values.',
'required_if' => '当 :other 为 :value 时 :attribute 不能为空。', 'required_if' => '当 :other 为 :value 时 :attribute 不能为空。',
'required_if_accepted' => '当 :other 存在时,:attribute 不能为空。', 'required_if_accepted' => '当 :other 存在时,:attribute 不能为空。',
'required_unless' => '当 :other 不为 :values 时 :attribute 不能为空。', 'required_unless' => '当 :other 不为 :values 时 :attribute 不能为空。',
'required_with' => '当 :values 存在时 :attribute 不能为空。', 'required_with' => '当 :values 存在时 :attribute 不能为空。',
'required_with_all' => '当 :values 存在时 :attribute 不能为空。', 'required_with_all' => '当 :values 存在时 :attribute 不能为空。',
'required_without' => '当 :values 不存在时 :attribute 不能为空。', 'required_without' => '当 :values 不存在时 :attribute 不能为空。',
'required_without_all' => '当 :values 都不存在时 :attribute 不能为空。', 'required_without_all' => '当 :values 都不存在时 :attribute 不能为空。',
'same' => ':Attribute 和 :other 必须相同。', 'same' => ':Attribute 和 :other 必须相同。',
'size' => [ 'size' => [
'array' => ':Attribute 必须为 :size 个单元。', 'array' => ':Attribute 必须为 :size 个单元。',
'file' => ':Attribute 大小必须为 :size KB。', 'file' => ':Attribute 大小必须为 :size KB。',
'numeric' => ':Attribute 大小必须为 :size。', 'numeric' => ':Attribute 大小必须为 :size。',
'string' => ':Attribute 必须是 :size 个字符。', 'string' => ':Attribute 必须是 :size 个字符。',
], ],
'starts_with' => ':Attribute 必须以 :values 为开头。', 'starts_with' => ':Attribute 必须以 :values 为开头。',
'string' => ':Attribute 必须是一个字符串。', 'string' => ':Attribute 必须是一个字符串。',
'timezone' => ':Attribute 必须是一个合法的时区值。', 'timezone' => ':Attribute 必须是一个合法的时区值。',
'unique' => ':Attribute 已经存在。', 'unique' => ':Attribute 已经存在。',
'uploaded' => ':Attribute 上传失败。', 'uploaded' => ':Attribute 上传失败。',
'url' => ':Attribute 格式不正确。', 'url' => ':Attribute 格式不正确。',
'uuid' => ':Attribute 必须是有效的 UUID。', 'uuid' => ':Attribute 必须是有效的 UUID。',
'attributes' => [ 'attributes' => [
'address' => '地址', 'address' => '地址',
'age' => '年龄', 'age' => '年龄',
'amount' => '数额', 'amount' => '数额',
'area' => '区域', 'area' => '区域',
'available' => '可用的', 'available' => '可用的',
'birthday' => '生日', 'birthday' => '生日',
'body' => '身体', 'body' => '身体',
'city' => '城市', 'city' => '城市',
'content' => '内容', 'content' => '内容',
'country' => '国家', 'country' => '国家',
'created_at' => '创建于', 'created_at' => '创建于',
'creator' => '创建者', 'creator' => '创建者',
'current_password' => '当前密码', 'current_password' => '当前密码',
'date' => '日期', 'date' => '日期',
'date_of_birth' => '出生日期', 'date_of_birth' => '出生日期',
'day' => '天', 'day' => '天',
'deleted_at' => '删除于', 'deleted_at' => '删除于',
'description' => '描述', 'description' => '描述',
'district' => '地区', 'district' => '地区',
'duration' => '期间', 'duration' => '期间',
'email' => '邮箱', 'email' => '邮箱',
'excerpt' => '摘要', 'excerpt' => '摘要',
'filter' => '过滤', 'filter' => '过滤',
'first_name' => '名', 'first_name' => '名',
'gender' => '性别', 'gender' => '性别',
'group' => '组', 'group' => '组',
'hour' => '时', 'hour' => '时',
'image' => '图像', 'image' => '图像',
'last_name' => '姓', 'last_name' => '姓',
'lesson' => '课程', 'lesson' => '课程',
'line_address_1' => '线路地址 1', 'line_address_1' => '线路地址 1',
'line_address_2' => '线路地址 2', 'line_address_2' => '线路地址 2',
'message' => '信息', 'message' => '信息',
'middle_name' => '中间名字', 'middle_name' => '中间名字',
'minute' => '分', 'minute' => '分',
'mobile' => '手机', 'mobile' => '手机',
'month' => '月', 'month' => '月',
'name' => '名称', 'name' => '名称',
'national_code' => '国家代码', 'national_code' => '国家代码',
'number' => '数字', 'number' => '数字',
'password' => '密码', 'password' => '密码',
'password_confirmation' => '确认密码', 'password_confirmation' => '确认密码',
'phone' => '电话', 'phone' => '电话',
'photo' => '照片', 'photo' => '照片',
'postal_code' => '邮政编码', 'postal_code' => '邮政编码',
'price' => '价格', 'price' => '价格',
'province' => '省', 'province' => '省',
'recaptcha_response_field' => '重复验证码响应字段', 'recaptcha_response_field' => '重复验证码响应字段',
'remember' => '记住', 'remember' => '记住',
'restored_at' => '恢复于', 'restored_at' => '恢复于',
'result_text_under_image' => '图像下的结果文本', 'result_text_under_image' => '图像下的结果文本',
'role' => '角色', 'role' => '角色',
'second' => '秒', 'second' => '秒',
'sex' => '性别', 'sex' => '性别',
'short_text' => '短文本', 'short_text' => '短文本',
'size' => '大小', 'size' => '大小',
'state' => '状态', 'state' => '状态',
'street' => '街道', 'street' => '街道',
'student' => '学生', 'student' => '学生',
'subject' => '主题', 'subject' => '主题',
'teacher' => '教师', 'teacher' => '教师',
'terms' => '条款', 'terms' => '条款',
'test_description' => '测试说明', 'test_description' => '测试说明',
'test_locale' => '测试语言环境', 'test_locale' => '测试语言环境',
'test_name' => '测试名称', 'test_name' => '测试名称',
'text' => '文本', 'text' => '文本',
'time' => '时间', 'time' => '时间',
'title' => '标题', 'title' => '标题',
'updated_at' => '更新于', 'updated_at' => '更新于',
'username' => '用户名', 'username' => '用户名',
'year' => '年', 'year' => '年',
], ],
]; ];

View File

@ -1,7 +1,7 @@
<?php <?php
use Illuminate\Http\Request;
use Illuminate\Contracts\Http\Kernel; use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;
define('LARAVEL_START', microtime(true)); define('LARAVEL_START', microtime(true));
@ -16,7 +16,7 @@
| |
*/ */
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) { if (file_exists($maintenance = __DIR__ . '/../storage/framework/maintenance.php')) {
require $maintenance; require $maintenance;
} }
@ -31,7 +31,7 @@
| |
*/ */
require __DIR__.'/../vendor/autoload.php'; require __DIR__ . '/../vendor/autoload.php';
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -44,7 +44,7 @@
| |
*/ */
$app = require_once __DIR__.'/../bootstrap/app.php'; $app = require_once __DIR__ . '/../bootstrap/app.php';
$kernel = $app->make(Kernel::class); $kernel = $app->make(Kernel::class);

View File

@ -1,6 +1,4 @@
import _ from 'lodash'; import _ from 'lodash';
window._ = _;
import 'bootstrap'; import 'bootstrap';
/** /**
@ -8,8 +6,10 @@ import 'bootstrap';
* to our Laravel back-end. This library automatically handles sending the * to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie. * CSRF token as a header based on the value of the "XSRF" token cookie.
*/ */
import axios from 'axios'; import axios from 'axios';
window._ = _;
window.axios = axios; window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

View File

@ -4,6 +4,6 @@
@section('content') @section('content')
欢迎来到后台管理系统 欢迎来到后台管理系统
@endsection @endsection

View File

@ -16,11 +16,11 @@
<div class="col-md-6"> <div class="col-md-6">
<input id="email" type="email" <input id="email" type="email"
class="form-control @error('email') is-invalid @enderror" name="email" class="form-control @error('email') is-invalid @enderror" name="email"
value="{{ old('email') }}" required autocomplete="email" autofocus> value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email') @error('email')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong> <strong>{{ $message }}</strong>
</span> </span>
@enderror @enderror
@ -32,11 +32,12 @@ class="form-control @error('email') is-invalid @enderror" name="email"
<div class="col-md-6"> <div class="col-md-6">
<input id="password" type="password" <input id="password" type="password"
class="form-control @error('password') is-invalid @enderror" name="password" required class="form-control @error('password') is-invalid @enderror" name="password"
autocomplete="current-password"> required
autocomplete="current-password">
@error('password') @error('password')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong> <strong>{{ $message }}</strong>
</span> </span>
@enderror @enderror

View File

@ -4,6 +4,6 @@
@section('content') @section('content')
欢迎来到后台管理系统 欢迎来到后台管理系统
@endsection @endsection

View File

@ -0,0 +1,19 @@
@extends('layouts.app')
@section('title', '余额')
@section('content')
<h2>余额</h2>
<p>您的余额: {{ $balance }} </p>
<p>Drops: {{ $drops }} </p>
<form name="charge" method="POST" target="_blank" action="{{ route('balances.store') }}">
@csrf
<input type="number" name="amount" value="1" min="1" max="1000"/>
<button type="submit" class="btn btn-primary">充值</button>
</form>
@endsection

View File

@ -2,12 +2,12 @@
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8"/>
<title>支付订单</title> <title>支付订单</title>
</head> </head>
<body> <body>
{!! $html !!} {!! $html !!}
</body> </body>
</html> </html>

View File

@ -10,10 +10,10 @@
</head> </head>
<body> <body>
<h1>很抱歉,您可能违反了我们的规定。</h1> <h1>很抱歉,您可能违反了我们的规定。</h1>
<p>{{ auth()->user()->banned_reason }}</p> <p>{{ auth()->user()->banned_reason }}</p>
<a href="{{ route('logout') }}">更换账号</a> <a href="{{ route('logout') }}">更换账号</a>
</body> </body>
</html> </html>

View File

@ -2,22 +2,22 @@
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16"> <symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16">
<path <path
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z" /> d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</symbol> </symbol>
<symbol id="info-fill" fill="currentColor" viewBox="0 0 16 16"> <symbol id="info-fill" fill="currentColor" viewBox="0 0 16 16">
<path <path
d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z" /> d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</symbol> </symbol>
<symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16"> <symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16">
<path <path
d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z" /> d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
</symbol> </symbol>
</svg> </svg>
@if (session('error')) @if (session('error'))
<div> <div>
<div class="alert alert-danger d-flex align-items-center alert-dismissible fade show" role="alert"> <div class="alert alert-danger d-flex align-items-center alert-dismissible fade show" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Danger:"> <svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Danger:">
<use xlink:href="#exclamation-triangle-fill" /> <use xlink:href="#exclamation-triangle-fill"/>
</svg> </svg>
<div> <div>
{{ session('error') }} {{ session('error') }}
@ -30,7 +30,7 @@
<div> <div>
<div class="alert alert-primary d-flex align-items-center alert-dismissible fade show" role="alert"> <div class="alert alert-primary d-flex align-items-center alert-dismissible fade show" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Info:"> <svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Info:">
<use xlink:href="#info-fill" /> <use xlink:href="#info-fill"/>
</svg> </svg>
<div> <div>
{{ session('status') }} {{ session('status') }}
@ -44,7 +44,7 @@
<div> <div>
<div class="alert alert-success d-flex align-items-center alert-dismissible fade show" role="alert"> <div class="alert alert-success d-flex align-items-center alert-dismissible fade show" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Success:"> <svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Success:">
<use xlink:href="#check-circle-fill" /> <use xlink:href="#check-circle-fill"/>
</svg> </svg>
<div> <div>
{{ session('success') }} {{ session('success') }}
@ -58,7 +58,7 @@
<div> <div>
<div class="alert alert-danger d-flex align-items-center alert-dismissible fade show" role="alert"> <div class="alert alert-danger d-flex align-items-center alert-dismissible fade show" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Danger:"> <svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Danger:">
<use xlink:href="#exclamation-triangle-fill" /> <use xlink:href="#exclamation-triangle-fill"/>
</svg> </svg>
<div> <div>
<ul class="mb-0"> <ul class="mb-0">

View File

@ -25,11 +25,11 @@
<form action="{{ route('newToken') }}" name="newToken" method="POST"> <form action="{{ route('newToken') }}" name="newToken" method="POST">
@csrf @csrf
<input type="text" name="token_name" placeholder="Token 名字" /> <input type="text" name="token_name" placeholder="Token 名字"/>
<button class="btn btn-primary" type="submit">获取新的 Token</button> <button class="btn btn-primary" type="submit">获取新的 Token</button>
</form> </form>
<hr /> <hr/>
<p>如果你需要撤销对所有应用程序的授权,你可以在这里吊销所有 Token</p> <p>如果你需要撤销对所有应用程序的授权,你可以在这里吊销所有 Token</p>
<form action="{{ route('deleteAll') }}" method="post"> <form action="{{ route('deleteAll') }}" method="post">
@csrf @csrf
@ -38,7 +38,7 @@
</form> </form>
<p class="text-danger">*如果您的 Token 被泄漏,您应该立即吊销所有 Token</p> <p class="text-danger">*如果您的 Token 被泄漏,您应该立即吊销所有 Token</p>
<hr /> <hr/>
<form action="{{ route('logout') }}" method="post"> <form action="{{ route('logout') }}" method="post">
@csrf @csrf
<button class="btn btn-danger" type="submit">退出登录</button> <button class="btn btn-danger" type="submit">退出登录</button>

View File

@ -19,71 +19,71 @@
</head> </head>
<body> <body>
<div id="app"> <div id="app">
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm"> <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
<div class="container"> <div class="container">
<a class="navbar-brand" href="{{ route('admin.index') }}"> <a class="navbar-brand" href="{{ route('admin.index') }}">
{{ config('app.display_name') }} {{ config('app.display_name') }}
</a> </a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="{{ __('Toggle navigation') }}"> aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="collapse navbar-collapse" id="navbarSupportedContent"> <div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- Left Side Of Navbar --> <!-- Left Side Of Navbar -->
<ul class="navbar-nav me-auto"> <ul class="navbar-nav me-auto">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{{ route('admin.users.index') }}">用户</a> <a class="nav-link" href="{{ route('admin.users.index') }}">用户</a>
</li> </li>
</ul> </ul>
<!-- Right Side Of Navbar --> <!-- Right Side Of Navbar -->
<ul class="navbar-nav ms-auto"> <ul class="navbar-nav ms-auto">
<!-- Authentication Links --> <!-- Authentication Links -->
@if (!Auth::guard('admin')->check()) @if (!Auth::guard('admin')->check())
@if (Route::has('admin.login')) @if (Route::has('admin.login'))
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{{ route('admin.login') }}">{{ __('Login') }}</a> <a class="nav-link" href="{{ route('admin.login') }}">{{ __('Login') }}</a>
</li> </li>
@endif @endif
@else @else
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button"
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ Auth::guard('admin')->user()->email ?? '' }} {{ Auth::guard('admin')->user()->email ?? '' }}
</a>
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ route('admin.logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a> </a>
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown"> <form id="logout-form" action="{{ route('admin.logout') }}" method="POST"
<a class="dropdown-item" href="{{ route('admin.logout') }}" class="d-none">
onclick="event.preventDefault(); @csrf
document.getElementById('logout-form').submit();"> </form>
{{ __('Logout') }} </div>
</a> </li>
@endguest
<form id="logout-form" action="{{ route('admin.logout') }}" method="POST" </ul>
class="d-none">
@csrf
</form>
</div>
</li>
@endguest
</ul>
</div>
</div> </div>
</nav> </div>
</nav>
<main class="py-4"> <main class="py-4">
<div class="container"> <div class="container">
<x-alert /> <x-alert/>
</div> </div>
<div class="container"> <div class="container">
@yield('content') @yield('content')
</div> </div>
</main> </main>
</div> </div>
</body> </body>
</html> </html>

View File

@ -19,74 +19,74 @@
</head> </head>
<body> <body>
<div id="app"> <div id="app">
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm"> <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
<div class="container"> <div class="container">
<a class="navbar-brand" href="{{ route('admin.index') }}"> <a class="navbar-brand" href="{{ route('index') }}">
{{ config('app.display_name') }} {{ config('app.display_name') }}
</a> </a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="{{ __('Toggle navigation') }}"> aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="collapse navbar-collapse" id="navbarSupportedContent"> <div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- Left Side Of Navbar --> <!-- Left Side Of Navbar -->
<ul class="navbar-nav me-auto"> <ul class="navbar-nav me-auto">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{{ route('index') }}">首页</a> <a class="nav-link" href="{{ route('index') }}">首页</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{{ route('index') }}">首页</a> <a class="nav-link" href="{{ route('balances.index') }}">余额</a>
</li> </li>
</ul> </ul>
<!-- Right Side Of Navbar --> <!-- Right Side Of Navbar -->
<ul class="navbar-nav ms-auto"> <ul class="navbar-nav ms-auto">
<!-- Authentication Links --> <!-- Authentication Links -->
@guest @guest
@if (Route::has('admin.login')) @if (Route::has('admin.login'))
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{{ route('admin.login') }}">{{ __('Login') }}</a> <a class="nav-link" href="{{ route('admin.login') }}">{{ __('Login') }}</a>
</li> </li>
@endif @endif
@else @else
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button"
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ Auth::user()->name }} {{ Auth::user()->name }}
</a>
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a> </a>
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown"> <form id="logout-form" action="{{ route('logout') }}" method="POST"
<a class="dropdown-item" href="{{ route('logout') }}" class="d-none">
onclick="event.preventDefault(); @csrf
document.getElementById('logout-form').submit();"> </form>
{{ __('Logout') }} </div>
</a> </li>
@endguest
<form id="logout-form" action="{{ route('logout') }}" method="POST" </ul>
class="d-none">
@csrf
</form>
</div>
</li>
@endguest
</ul>
</div>
</div> </div>
</nav> </div>
</nav>
<main class="py-4"> <main class="py-4">
<div class="container"> <div class="container">
<x-alert /> <x-alert/>
</div> </div>
<div class="container"> <div class="container">
@yield('content') @yield('content')
</div> </div>
</main> </main>
</div> </div>
</body> </body>
</html> </html>

View File

@ -10,11 +10,11 @@
</head> </head>
<body> <body>
<h1>我们无法让您继续</h1> <h1>我们无法让您继续</h1>
<p>您的账户尚未通过实名验证,因此无法使用此功能。</p> <p>您的账户尚未通过实名验证,因此无法使用此功能。</p>
<p>请到<a href="https://www.lae.email/zh-CN/real-name-authentication">这里</a>实名验证,然后再重新登录。</p> <p>请到<a href="https://www.lae.email/zh-CN/real-name-authentication">这里</a>实名验证,然后再重新登录。</p>
<a href="{{ route('login') }}">重新登录</a> <a href="{{ route('login') }}">重新登录</a>
</body> </body>
</html> </html>

View File

@ -2,26 +2,25 @@
# {{ $module->name }} # {{ $module->name }}
================================== ==================================
## 本月 ## 本月
#### 现金 {{ round($data['transactions']['this_month']['balance'], 2) }} 元 #### 现金 {{ round($data['transactions']['this_month']['balances'], 2) }} 元
#### Drops {{ round($data['transactions']['this_month']['drops'], 4) }} #### Drops {{ round($data['transactions']['this_month']['drops'], 4) }}
#### 合计 {{ round($data['transactions']['this_month']['balance'] + $data['transactions']['this_month']['drops'] / $data['rate'], 2) }} 元 #### 合计 {{ round($data['transactions']['this_month']['balances'] + $data['transactions']['this_month']['drops'] / $data['rate'], 2) }} 元
================================== ==================================
## 上个月 ## 上个月
#### 现金 {{ round($data['transactions']['last_month']['balance'], 2) }} 元 #### 现金 {{ round($data['transactions']['last_month']['balances'], 2) }} 元
#### Drops {{ round($data['transactions']['last_month']['drops'], 4) }} #### Drops {{ round($data['transactions']['last_month']['drops'], 4) }}
#### 合计 {{ round($data['transactions']['last_month']['balance'] + $data['transactions']['last_month']['drops'] / $data['rate'], 2) }} 元 #### 合计 {{ round($data['transactions']['last_month']['balances'] + $data['transactions']['last_month']['drops'] / $data['rate'], 2) }} 元
{{-- {{--
$module = $this->http->get('modules')->json()['data']; $module = $this->http->get('modules')->json()['data'];
$total = $module['transactions']['this_month']['balance']; $total = $module['transactions']['this_month']['balances'];
$drops = $module['transactions']['this_month']['drops'] / $module['rate']; $drops = $module['transactions']['this_month']['drops'] / $module['rate'];
if ($drops < 0) { $drops=0; } $total +=$drops; $total=round($total, 2); $module=[ 'balance'=> if ($drops < 0) { $drops=0; } $total +=$drops; $total=round($total, 2); $module=[ 'balances'=>
$module['transactions']['this_month']['balance'], $module['transactions']['this_month']['balances'],
'drops' => $module['transactions']['this_month']['drops'], 'drops' => $module['transactions']['this_month']['drops'],
'total' => $total, 'total' => $total,
]; ];
@ -32,7 +31,7 @@
本月收益 本月收益
</h3> </h3>
<p> <p>
直接扣费金额: {{ $module['balance'] }} 直接扣费金额: {{ $module['balances'] }}
</p> </p>
<p> <p>
Drops: {{ $module['drops'] }} Drops: {{ $module['drops'] }}

Some files were not shown because too many files have changed in this diff Show More