diff --git a/app/Console/Commands/AutoClearLog.php b/app/Console/Commands/AutoClearLog.php
index 24b1cfc0..c0d6a160 100644
--- a/app/Console/Commands/AutoClearLog.php
+++ b/app/Console/Commands/AutoClearLog.php
@@ -5,8 +5,11 @@ namespace App\Console\Commands;
use App\Models\NodeDailyDataFlow;
use App\Models\NodeHeartBeat;
use App\Models\NodeHourlyDataFlow;
+use App\Models\NodeOnlineIp;
use App\Models\NodeOnlineLog;
-use App\Models\NodeOnlineUserIp;
+use App\Models\NotificationLog;
+use App\Models\Payment;
+use App\Models\RuleLog;
use App\Models\UserBanedLog;
use App\Models\UserDailyDataFlow;
use App\Models\UserDataFlowLog;
@@ -41,17 +44,32 @@ class AutoClearLog extends Command
private function clearLog(): void
{
try {
+ // 清除节点每天流量数据日志
+ NodeDailyDataFlow::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-2 month')))->delete();
+
+ // 清除节点每小时流量数据日志
+ NodeHourlyDataFlow::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 days')))->delete();
+
+ // 清理通知日志
+ NotificationLog::where('updated_at', '<=', date('Y-m-d H:i:s', strtotime('-1 month')))->delete();
+
// 清除节点负载信息日志
NodeHeartBeat::where('log_time', '<=', strtotime('-30 minutes'))->delete();
// 清除节点在线用户数日志
NodeOnlineLog::where('log_time', '<=', strtotime('-1 hour'))->delete();
- // 清除用户流量日志
- UserDataFlowLog::where('log_time', '<=', strtotime('-3 days'))->delete();
+ // 清理在线支付日志
+ Payment::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-1 year')))->delete();
- // 清除用户每时各流量数据日志
- UserHourlyDataFlow::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 days')))->delete();
+ // 清理审计触发日志
+ RuleLog::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 month')))->delete();
+
+ // 清除用户连接IP
+ NodeOnlineIp::where('created_at', '<=', strtotime('-1 week'))->delete();
+
+ // 清除用户封禁日志
+ UserBanedLog::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 month')))->delete();
// 清除用户各节点 / 节点总计的每天流量数据日志
UserDailyDataFlow::where('node_id', '<>', null)
@@ -59,23 +77,17 @@ class AutoClearLog extends Command
->orWhere('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 month')))
->delete();
- // 清除节点每小时流量数据日志
- NodeHourlyDataFlow::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 days')))->delete();
-
- // 清除节点每天流量数据日志
- NodeDailyDataFlow::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-2 month')))->delete();
-
- // 清除用户封禁日志
- UserBanedLog::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 month')))->delete();
-
- // 清除用户连接IP
- NodeOnlineUserIp::where('created_at', '<=', strtotime('-1 month'))->delete();
+ // 清除用户每时各流量数据日志
+ UserHourlyDataFlow::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 days')))->delete();
// 清除用户登陆日志
- UserLoginLog::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 month')))->delete();
+ UserLoginLog::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 month')))->delete(); // 清除用户订阅记录
- // 清除用户订阅记录
+ // 清理用户订阅请求日志
UserSubscribeLog::where('request_time', '<=', date('Y-m-d H:i:s', strtotime('-1 month')))->delete();
+
+ // 清除用户流量日志
+ UserDataFlowLog::where('log_time', '<=', strtotime('-3 days'))->delete();
} catch (Exception $e) {
Log::error('【清理日志】错误: '.$e->getMessage());
}
diff --git a/app/Console/Commands/AutoJob.php b/app/Console/Commands/AutoJob.php
index ef6e76c9..480418d9 100644
--- a/app/Console/Commands/AutoJob.php
+++ b/app/Console/Commands/AutoJob.php
@@ -80,11 +80,7 @@ class AutoJob extends Command
VerifyCode::recentUnused()->update(['status' => 2]);
// 优惠券到期 / 用尽的 自动置无效
- Coupon::whereStatus(0)
- ->where('end_time', '<=', time())
- ->orWhereIn('type', [1, 2])
- ->whereUsableTimes(0)
- ->update(['status' => 2]);
+ Coupon::withTrashed()->whereStatus(0)->where('end_time', '<=', time())->orWhereIn('type', [1, 2])->whereUsableTimes(0)->update(['status' => 2]);
// 邀请码到期自动置无效
Invite::whereStatus(0)->where('dateline', '<=', date('Y-m-d H:i:s'))->update(['status' => 2]);
diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php
index 480f0acf..1997a3c6 100644
--- a/app/Exceptions/Handler.php
+++ b/app/Exceptions/Handler.php
@@ -9,6 +9,7 @@ use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Request;
use Illuminate\Session\TokenMismatchException;
+use Illuminate\Validation\ValidationException;
use Log;
use ReflectionException;
use Response;
@@ -25,6 +26,7 @@ class Handler extends ExceptionHandler
*/
protected $dontReport = [
HttpException::class,
+ ValidationException::class,
];
/**
diff --git a/app/Http/Controllers/Admin/AffiliateController.php b/app/Http/Controllers/Admin/AffiliateController.php
index a3767123..c14633bf 100644
--- a/app/Http/Controllers/Admin/AffiliateController.php
+++ b/app/Http/Controllers/Admin/AffiliateController.php
@@ -5,15 +5,8 @@ namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\ReferralApply;
use App\Models\ReferralLog;
-use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
-use Response;
-/**
- * 推广控制器.
- *
- * Class AffiliateController
- */
class AffiliateController extends Controller
{
// 提现申请列表
@@ -33,44 +26,38 @@ class AffiliateController extends Controller
$query->whereStatus($status);
}
- $view['applyList'] = $query->latest()->paginate(15)->appends($request->except('page'));
-
- return view('admin.aff.index', $view);
+ return view('admin.aff.index', ['applyList' => $query->latest()->paginate(15)->appends($request->except('page'))]);
}
// 提现申请详情
- public function detail(Request $request, $id)
+ public function detail(Request $request, ReferralApply $aff)
{
- $view['basic'] = ReferralApply::with('user:id,email')->find($id);
- $view['commissions'] = [];
- if ($view['basic'] && $view['basic']->link_logs) {
- $view['commissions'] = ReferralLog::with(['invitee:id,email', 'order.goods:id,name'])
- ->whereIn('id', $view['basic']->link_logs)
+ if ($aff->link_logs) {
+ $commissions = ReferralLog::with(['invitee:id,email', 'order.goods:id,name'])
+ ->whereIn('id', $aff->link_logs)
->paginate(15)
->appends($request->except('page'));
}
- return view('admin.aff.detail', $view);
+ return view('admin.aff.detail', [
+ 'referral' => $aff->load('user:id,email'),
+ 'commissions' => $commissions ?? null,
+ ]);
}
// 设置提现申请状态
- public function setStatus(Request $request): JsonResponse
+ public function setStatus(Request $request, ReferralApply $aff)
{
- $id = $request->input('id');
- $status = (int) $request->input('status');
+ $status = (int) $request->validate(['status' => 'required|numeric|between:-1,2']);
- $ret = ReferralApply::whereId($id)->update(['status' => $status]);
- if ($ret) {
+ if ($aff->update(['status' => $status])) {
// 审核申请的时候将关联的
- $referralApply = ReferralApply::findOrFail($id);
- if ($referralApply && $status === 1) {
- ReferralLog::whereIn('id', $referralApply->link_logs)->update(['status' => 1]);
- } elseif ($referralApply && $status === 2) {
- ReferralLog::whereIn('id', $referralApply->link_logs)->update(['status' => 2]);
+ if ($status === 1 || $status === 2) {
+ $aff->referral_logs()->update(['status' => $status]);
}
}
- return Response::json(['status' => 'success', 'message' => '操作成功']);
+ return response()->json(['status' => 'success', 'message' => '操作成功']);
}
// 用户返利流水记录
@@ -98,8 +85,6 @@ class AffiliateController extends Controller
$query->whereStatus($status);
}
- $view['list'] = $query->paginate(15)->appends($request->except('page'));
-
- return view('admin.aff.rebate', $view);
+ return view('admin.aff.rebate', ['referralLogs' => $query->paginate(15)->appends($request->except('page'))]);
}
}
diff --git a/app/Http/Controllers/Admin/ArticleController.php b/app/Http/Controllers/Admin/ArticleController.php
index c1849e31..daacfffd 100644
--- a/app/Http/Controllers/Admin/ArticleController.php
+++ b/app/Http/Controllers/Admin/ArticleController.php
@@ -6,22 +6,15 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\ArticleRequest;
use App\Models\Article;
use Exception;
-use Illuminate\Http\JsonResponse;
-use Illuminate\Http\RedirectResponse;
-use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Log;
-use Redirect;
-use Response;
class ArticleController extends Controller
{
// 文章列表
- public function index(Request $request)
+ public function index()
{
- $view['articles'] = Article::orderByDesc('sort')->paginate(15)->appends($request->except('page'));
-
- return view('admin.article.index', $view);
+ return view('admin.article.index', ['articles' => Article::orderByDesc('sort')->paginate(15)->appends(request('page'))]);
}
// 添加文章页面
@@ -33,9 +26,9 @@ class ArticleController extends Controller
// 添加文章
public function store(ArticleRequest $request)
{
- $data = $request->except('_method', '_token');
+ $data = $request->validated();
// LOGO
- if ($request->input('type') !== '4' && $request->hasFile('logo')) {
+ if ($data['type'] !== '4' && $request->hasFile('logo')) {
$path = $this->fileUpload($request->file('logo'));
if (is_string($path)) {
$data['logo'] = $path;
@@ -44,50 +37,44 @@ class ArticleController extends Controller
}
}
- $article = Article::create($data);
- if ($article->id) {
- return Redirect::route('admin.article.edit', $article->id)->with('successMsg', '添加成功');
+ if ($article = Article::create($data)) {
+ return redirect(route('admin.article.edit', $article))->with('successMsg', '添加成功');
}
- return Redirect::back()->withInput()->withErrors('添加失败');
+ return redirect()->back()->withInput()->withErrors('添加失败');
}
// 图片上传
public function fileUpload(UploadedFile $file)
{
$fileName = Str::random(8).time().'.'.$file->getClientOriginalExtension();
- $path = $file->storeAs('public', $fileName);
- if (! $path) {
- return Redirect::back()->withInput()->withErrors('Logo存储失败');
+ if (! $file->storeAs('public', $fileName)) {
+ return redirect()->back()->withInput()->withErrors('Logo存储失败');
}
return 'upload/'.$fileName;
}
// 文章页面
- public function show($id)
+ public function show(Article $article)
{
- $view['article'] = Article::find($id);
-
- return view('admin.article.show', $view);
+ return view('admin.article.show', compact('article'));
}
// 编辑文章页面
- public function edit($id)
+ public function edit(Article $article)
{
- $view['article'] = Article::find($id);
-
- return view('admin.article.edit', $view);
+ return view('admin.article.edit', compact('article'));
}
// 编辑文章
- public function update(ArticleRequest $request, $id): RedirectResponse
+ public function update(ArticleRequest $request, Article $article)
{
- $data = $request->except('_method', '_token');
+ $data = $request->validated();
$data['logo'] = $data['logo'] ?? null;
// LOGO
- if ($request->input('type') != 4 && $request->hasFile('logo')) {
+ if ($data['type'] !== '4' && $request->hasFile('logo')) {
$path = $this->fileUpload($request->file('logo'));
if (is_string($path)) {
$data['logo'] = $path;
@@ -96,26 +83,24 @@ class ArticleController extends Controller
}
}
- if (Article::find($id)->update($data)) {
- return Redirect::back()->with('successMsg', '编辑成功');
+ if ($article->update($data)) {
+ return redirect()->back()->with('successMsg', '编辑成功');
}
- return Redirect::back()->withErrors('编辑失败');
+ return redirect()->back()->withInput()->withErrors('编辑失败');
}
// 删除文章
- public function destroy($id): JsonResponse
+ public function destroy(Article $article)
{
try {
- Article::find($id)->delete();
+ $article->delete();
} catch (Exception $e) {
Log::error('删除文章失败:'.$e->getMessage());
- return Response::json(
- ['status' => 'fail', 'message' => '删除失败:'.$e->getMessage()]
- );
+ return response()->json(['status' => 'fail', 'message' => '删除失败:'.$e->getMessage()]);
}
- return Response::json(['status' => 'success', 'message' => '删除成功']);
+ return response()->json(['status' => 'success', 'message' => '删除成功']);
}
}
diff --git a/app/Http/Controllers/Admin/CertController.php b/app/Http/Controllers/Admin/CertController.php
index f4123d05..69589af2 100644
--- a/app/Http/Controllers/Admin/CertController.php
+++ b/app/Http/Controllers/Admin/CertController.php
@@ -3,32 +3,29 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
+use App\Http\Requests\Admin\CertRequest;
use App\Models\NodeCertificate;
use Exception;
-use Illuminate\Http\JsonResponse;
-use Illuminate\Http\Request;
use Log;
-use Response;
class CertController extends Controller
{
// 域名证书列表
- public function index(Request $request)
+ public function index()
{
- $DvList = NodeCertificate::orderBy('id')->paginate(15)->appends($request->except('page'));
- foreach ($DvList as $Dv) {
- if ($Dv->pem) {
- $DvInfo = openssl_x509_parse($Dv->pem);
- if ($DvInfo) {
- $Dv->issuer = $DvInfo['issuer']['O'] ?? null;
- $Dv->from = date('Y-m-d', $DvInfo['validFrom_time_t']) ?: null;
- $Dv->to = date('Y-m-d', $DvInfo['validTo_time_t']) ?: null;
+ $certs = NodeCertificate::orderBy('id')->paginate(15)->appends(request('page'));
+ foreach ($certs as $cert) {
+ if ($cert->pem) {
+ $certInfo = openssl_x509_parse($cert->pem);
+ if ($certInfo) {
+ $cert->issuer = $certInfo['issuer']['O'] ?? null;
+ $cert->from = date('Y-m-d', $certInfo['validFrom_time_t']) ?: null;
+ $cert->to = date('Y-m-d', $certInfo['validTo_time_t']) ?: null;
}
}
}
- $view['list'] = $DvList;
- return view('admin.node.cert.index', $view);
+ return view('admin.node.cert.index', ['certs' => $certs]);
}
public function create()
@@ -37,52 +34,43 @@ class CertController extends Controller
}
// 添加域名证书
- public function store(Request $request): JsonResponse
+ public function store(CertRequest $request)
{
- $cert = new NodeCertificate();
- $cert->domain = $request->input('domain');
- $cert->key = str_replace(["\r", "\n"], '', $request->input('key'));
- $cert->pem = str_replace(["\r", "\n"], '', $request->input('pem'));
- $cert->save();
-
- if ($cert->id) {
- return Response::json(['status' => 'success', 'message' => '生成成功']);
+ if ($cert = NodeCertificate::create($request->validated())) {
+ return redirect(route('admin.node.cert.update', $cert))->with('successMsg', '生成成功');
}
- return Response::json(['status' => 'fail', 'message' => '生成失败']);
+ return redirect()->back()->withInput()->withErrors('生成失败');
}
// 编辑域名证书
- public function edit($id)
+ public function edit(NodeCertificate $cert)
{
- $view['Dv'] = NodeCertificate::find($id);
-
- return view('admin.node.cert.info', $view);
+ return view('admin.node.cert.info', compact('cert'));
}
- public function update(Request $request, $id): JsonResponse
+ public function update(CertRequest $request, NodeCertificate $cert)
{
- $Dv = NodeCertificate::findOrFail($id);
- if ($Dv->update(['domain' => $request->input('domain'), 'key' => $request->input('key'), 'pem' => $request->input('pem')])) {
- return Response::json(['status' => 'success', 'message' => '修改成功']);
+ if ($cert->update($request->validated())) {
+ return redirect()->back()->with('successMsg', '修改成功');
}
- return Response::json(['status' => 'fail', 'message' => '修改失败']);
+ return redirect()->back()->withInput()->withErrors('修改失败');
}
// 删除域名证书
- public function destroy($id): JsonResponse
+ public function destroy(NodeCertificate $cert)
{
try {
- if (NodeCertificate::whereId($id)->delete()) {
- return Response::json(['status' => 'success', 'message' => '操作成功']);
+ if ($cert->delete()) {
+ return response()->json(['status' => 'success', 'message' => '操作成功']);
}
} catch (Exception $e) {
Log::error('删除域名证书失败:'.$e->getMessage());
- return Response::json(['status' => 'fail', 'message' => '删除域名证书失败:'.$e->getMessage()]);
+ return response()->json(['status' => 'fail', 'message' => '删除域名证书错误:'.$e->getMessage()]);
}
- return Response::json(['status' => 'fail', 'message' => '删除域名证书失败']);
+ return response()->json(['status' => 'fail', 'message' => '删除域名证书失败']);
}
}
diff --git a/app/Http/Controllers/Admin/Config/EmailFilterController.php b/app/Http/Controllers/Admin/Config/EmailFilterController.php
index 9a662057..63c42fb0 100644
--- a/app/Http/Controllers/Admin/Config/EmailFilterController.php
+++ b/app/Http/Controllers/Admin/Config/EmailFilterController.php
@@ -16,9 +16,7 @@ class EmailFilterController extends Controller
// 邮箱过滤列表
public function index()
{
- $view['list'] = EmailFilter::orderByDesc('id')->paginate(15);
-
- return view('admin.config.emailFilter', $view);
+ return view('admin.config.emailFilter', ['list' => EmailFilter::orderByDesc('id')->paginate()]);
}
// 添加邮箱后缀
diff --git a/app/Http/Controllers/Admin/Config/LabelController.php b/app/Http/Controllers/Admin/Config/LabelController.php
index c5f000de..6590088b 100644
--- a/app/Http/Controllers/Admin/Config/LabelController.php
+++ b/app/Http/Controllers/Admin/Config/LabelController.php
@@ -4,7 +4,6 @@ namespace App\Http\Controllers\Admin\Config;
use App\Http\Controllers\Controller;
use App\Models\Label;
-use App\Models\NodeLabel;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -28,9 +27,9 @@ class LabelController extends Controller
}
// 编辑标签
- public function update(Request $request, $id): JsonResponse
+ public function update(Request $request, Label $label): JsonResponse
{
- if (Label::whereId($id)->update(['name' => $request->input('name'), 'sort' => $request->input('sort')])) {
+ if ($label->update(['name' => $request->input('name'), 'sort' => $request->input('sort')])) {
return Response::json(['status' => 'success', 'message' => '编辑成功']);
}
@@ -38,10 +37,10 @@ class LabelController extends Controller
}
// 删除标签
- public function destroy($id): ?JsonResponse
+ public function destroy(Label $label): ?JsonResponse
{
try {
- Label::whereId($id)->delete();
+ $label->delete();
return Response::json(['status' => 'success', 'message' => '删除成功']);
} catch (Exception $e) {
diff --git a/app/Http/Controllers/Admin/CouponController.php b/app/Http/Controllers/Admin/CouponController.php
index 764b76d4..d63dc22b 100644
--- a/app/Http/Controllers/Admin/CouponController.php
+++ b/app/Http/Controllers/Admin/CouponController.php
@@ -43,9 +43,7 @@ class CouponController extends Controller
$query->whereStatus($status);
}
- $view['couponList'] = $query->latest()->paginate(15)->appends($request->except('page'));
-
- return view('admin.coupon.index', $view);
+ return view('admin.coupon.index', ['couponList' => $query->latest()->paginate(15)->appends($request->except('page'))]);
}
// 添加优惠券页面
@@ -71,19 +69,12 @@ class CouponController extends Controller
}
try {
$num = (int) $request->input('num');
+ $data = $request->only(['name', 'type', 'usable_times', 'value', 'rule', 'start_time', 'end_time']);
+ $data['logo'] = $logo;
for ($i = 0; $i < $num; $i++) {
- $obj = new Coupon();
- $obj->name = $request->input('name');
- $obj->logo = $logo;
- $obj->sn = $num === 1 && $request->input('sn') ? $request->input('sn') : Str::random(8);
- $obj->type = $request->input('type');
- $obj->usable_times = $request->input('usable_times');
- $obj->value = $request->input('value');
- $obj->rule = $request->input('rule');
- $obj->start_time = strtotime($request->input('start_time'));
- $obj->end_time = strtotime($request->input('end_time'));
- $obj->save();
+ $data['sn'] = $num === 1 && $request->input('sn') ? $request->input('sn') : Str::random(8);
+ Coupon::create($data);
}
return Redirect::route('admin.coupon.index')->with('successMsg', '生成成功');
@@ -95,10 +86,10 @@ class CouponController extends Controller
}
// 删除优惠券
- public function destroy($id): JsonResponse
+ public function destroy(Coupon $coupon): JsonResponse
{
try {
- if (Coupon::find($id)->delete()) {
+ if ($coupon->delete()) {
return Response::json(['status' => 'success', 'message' => '删除成功']);
}
} catch (Exception $e) {
@@ -132,7 +123,7 @@ class CouponController extends Controller
$sheet->setTitle('抵用券');
$sheet->fromArray(['名称', '使用次数', '有效期', '券码', '金额(元)', '使用限制(元)'], null);
foreach ($voucherList as $k => $vo) {
- $dateRange = date('Y-m-d', $vo->start_time).' ~ '.date('Y-m-d', $vo->end_time);
+ $dateRange = $vo->start_time.' ~ '.$vo->end_time;
$sheet->fromArray([$vo->name, $vo->usable_times ?? '无限制', $dateRange, $vo->sn, $vo->value, $vo->rule], null, 'A'.($k + 2));
}
@@ -143,7 +134,7 @@ class CouponController extends Controller
$sheet->setTitle('折扣券');
$sheet->fromArray(['名称', '使用次数', '有效期', '券码', '折扣(折)', '使用限制(元)'], null);
foreach ($discountCouponList as $k => $vo) {
- $dateRange = date('Y-m-d', $vo->start_time).' ~ '.date('Y-m-d', $vo->end_time);
+ $dateRange = $vo->start_time.' ~ '.$vo->end_time;
$sheet->fromArray([$vo->name, $vo->usable_times ?? '无限制', $dateRange, $vo->sn, $vo->value, $vo->rule], null, 'A'.($k + 2));
}
@@ -154,7 +145,7 @@ class CouponController extends Controller
$sheet->setTitle('充值券');
$sheet->fromArray(['名称', '有效期', '券码', '金额(元)'], null);
foreach ($refillList as $k => $vo) {
- $dateRange = date('Y-m-d', $vo->start_time).' ~ '.date('Y-m-d', $vo->end_time);
+ $dateRange = $vo->start_time.' ~ '.$vo->end_time;
$sheet->fromArray([$vo->name, $dateRange, $vo->sn, $vo->value], null, 'A'.($k + 2));
}
diff --git a/app/Http/Controllers/Admin/LogsController.php b/app/Http/Controllers/Admin/LogsController.php
index b5d2047e..c58fa991 100644
--- a/app/Http/Controllers/Admin/LogsController.php
+++ b/app/Http/Controllers/Admin/LogsController.php
@@ -5,7 +5,7 @@ namespace App\Http\Controllers\Admin;
use App\Components\IP;
use App\Http\Controllers\Controller;
use App\Models\Node;
-use App\Models\NodeOnlineUserIp;
+use App\Models\NodeOnlineIp;
use App\Models\NotificationLog;
use App\Models\Order;
use App\Models\PaymentCallback;
@@ -15,7 +15,6 @@ use App\Models\UserCreditLog;
use App\Models\UserDataFlowLog;
use App\Models\UserDataModifyLog;
use Illuminate\Http\Request;
-use Redirect;
class LogsController extends Controller
{
@@ -78,9 +77,7 @@ class LogsController extends Controller
$query->orderByDesc('id');
}
- $view['orderList'] = $query->paginate(15)->appends($request->except('page'));
-
- return view('admin.logs.order', $view);
+ return view('admin.logs.order', ['orders' => $query->paginate(15)->appends($request->except('page'))]);
}
// 流量日志
@@ -123,20 +120,18 @@ class LogsController extends Controller
$query->where('log_time', '<=', strtotime($endTime));
}
- // 已使用流量
- $view['totalTraffic'] = flowAutoShow($query->sum('u') + $query->sum('d'));
-
- $list = $query->latest('log_time')->paginate(20)->appends($request->except('page'));
- foreach ($list as $vo) {
- $vo->u = flowAutoShow($vo->u);
- $vo->d = flowAutoShow($vo->d);
- $vo->log_time = date('Y-m-d H:i:s', $vo->log_time);
+ $dataFlowLogs = $query->latest('log_time')->paginate(20)->appends($request->except('page'));
+ foreach ($dataFlowLogs as $log) {
+ $log->u = flowAutoShow($log->u);
+ $log->d = flowAutoShow($log->d);
+ $log->log_time = date('Y-m-d H:i:s', $log->log_time);
}
- $view['list'] = $list;
- $view['nodeList'] = Node::whereStatus(1)->orderByDesc('sort')->latest()->get();
-
- return view('admin.logs.traffic', $view);
+ return view('admin.logs.traffic', [
+ 'totalTraffic' => flowAutoShow($query->sum('u') + $query->sum('d')), // 已使用流量
+ 'dataFlowLogs' => $dataFlowLogs,
+ 'nodes' => Node::whereStatus(1)->orderByDesc('sort')->latest()->get(),
+ ]);
}
// 邮件发送日志列表
@@ -155,9 +150,7 @@ class LogsController extends Controller
$query->whereType($type);
}
- $view['list'] = $query->latest()->paginate(15)->appends($request->except('page'));
-
- return view('admin.logs.notification', $view);
+ return view('admin.logs.notification', ['notificationLogs' => $query->latest()->paginate(15)->appends($request->except('page'))]);
}
// 在线IP监控(实时)
@@ -168,7 +161,7 @@ class LogsController extends Controller
$port = $request->input('port');
$nodeId = $request->input('nodeId');
- $query = NodeOnlineUserIp::with(['node:id,name', 'user:id,email'])->where('created_at', '>=', strtotime('-2 minutes'));
+ $query = NodeOnlineIp::with(['node:id,name', 'user:id,email'])->where('created_at', '>=', strtotime('-2 minutes'));
if (isset($ip)) {
$query->whereIp($ip);
@@ -209,10 +202,10 @@ class LogsController extends Controller
$log->ipInfo = implode(' ', $ipInfo);
}
- $view['list'] = $onlineIPLogs;
- $view['nodeList'] = Node::whereStatus(1)->orderByDesc('sort')->latest()->get();
-
- return view('admin.logs.onlineIPMonitor', $view);
+ return view('admin.logs.onlineIPMonitor', [
+ 'onlineIPLogs' => $onlineIPLogs,
+ 'nodes' => Node::whereStatus(1)->orderByDesc('sort')->latest()->get(),
+ ]);
}
// 用户余额变动记录
@@ -228,9 +221,7 @@ class LogsController extends Controller
});
}
- $view['list'] = $query->paginate(15)->appends($request->except('page'));
-
- return view('admin.logs.userCreditHistory', $view);
+ return view('admin.logs.userCreditHistory', ['userCreditLogs' => $query->paginate(15)->appends($request->except('page'))]);
}
// 用户封禁记录
@@ -246,9 +237,7 @@ class LogsController extends Controller
});
}
- $view['list'] = $query->paginate(15)->appends($request->except('page'));
-
- return view('admin.logs.userBanHistory', $view);
+ return view('admin.logs.userBanHistory', ['userBanLogs' => $query->paginate(15)->appends($request->except('page'))]);
}
// 用户流量变动记录
@@ -264,9 +253,7 @@ class LogsController extends Controller
});
}
- $view['list'] = $query->latest()->paginate(15)->appends($request->except('page'));
-
- return view('admin.logs.userTraffic', $view);
+ return view('admin.logs.userTraffic', ['userTrafficLogs' => $query->latest()->paginate(15)->appends($request->except('page'))]);
}
// 用户在线IP记录
@@ -297,34 +284,19 @@ class LogsController extends Controller
$userList = $query->paginate(15)->appends($request->except('page'));
- $nodeOnlineIPs = NodeOnlineUserIp::with('node:id,name')->where('created_at', '>=', strtotime('-10 minutes'))->latest()->distinct();
- // Todo 优化查询
+ $nodeOnlineIPs = NodeOnlineIp::with('node:id,name')->where('created_at', '>=', strtotime('-10 minutes'))->latest()->distinct()->get();
foreach ($userList as $user) {
// 最近5条在线IP记录,如果后端设置为60秒上报一次,则为10分钟内的在线IP
- $user->onlineIPList = $nodeOnlineIPs->wherePort($user->port)->limit(5)->get();
+ $user->onlineIPList = $nodeOnlineIPs->where('port', '==', $user->port)->chunk(5);
}
- $view['userList'] = $userList;
-
- return view('admin.logs.userOnlineIP', $view);
+ return view('admin.logs.userOnlineIP', ['userList' => $userList]);
}
// 用户流量监控
- public function userTrafficMonitor($id)
+ public function userTrafficMonitor(User $user)
{
- if (empty($id)) {
- return Redirect::back();
- }
-
- $user = User::find($id);
- if (empty($user)) {
- return Redirect::back();
- }
-
- $view['email'] = $user->email;
- $view = array_merge($view, $this->dataFlowChart($user->id));
-
- return view('admin.logs.userMonitor', $view);
+ return view('admin.logs.userMonitor', array_merge(['email' => $user->email], $this->dataFlowChart($user->id)));
}
// 回调日志
@@ -338,8 +310,6 @@ class LogsController extends Controller
$query->whereStatus($status);
}
- $view['list'] = $query->latest()->paginate(10)->appends($request->except('page'));
-
- return view('admin.logs.callback', $view);
+ return view('admin.logs.callback', ['callbackLogs' => $query->latest()->paginate(10)->appends($request->except('page'))]);
}
}
diff --git a/app/Http/Controllers/Admin/MarketingController.php b/app/Http/Controllers/Admin/MarketingController.php
index 6a7557fb..e6eeb091 100644
--- a/app/Http/Controllers/Admin/MarketingController.php
+++ b/app/Http/Controllers/Admin/MarketingController.php
@@ -31,9 +31,7 @@ class MarketingController extends Controller
$query->whereStatus($status);
}
- $view['list'] = $query->paginate(15)->appends($request->except('page'));
-
- return view('admin.marketing.emailList', $view);
+ return view('admin.marketing.emailList', ['emails' => $query->paginate(15)->appends($request->except('page'))]);
}
// 消息通道群发列表
@@ -47,9 +45,7 @@ class MarketingController extends Controller
$query->whereStatus($status);
}
- $view['list'] = $query->paginate(15)->appends($request->except('page'));
-
- return view('admin.marketing.pushList', $view);
+ return view('admin.marketing.pushList', ['pushes' => $query->paginate(15)->appends($request->except('page'))]);
}
// 添加推送消息
diff --git a/app/Http/Controllers/Admin/NodeAuthController.php b/app/Http/Controllers/Admin/NodeAuthController.php
new file mode 100644
index 00000000..60ec4590
--- /dev/null
+++ b/app/Http/Controllers/Admin/NodeAuthController.php
@@ -0,0 +1,62 @@
+ NodeAuth::orderBy('node_id')->paginate()->appends(request('page'))]);
+ }
+
+ // 添加节点授权
+ public function store(Request $request)
+ {
+ $nodeArray = Node::whereStatus(1)->orderBy('id')->pluck('id')->toArray();
+ $authArray = NodeAuth::orderBy('node_id')->pluck('node_id')->toArray();
+
+ $arrayDifferent = array_diff($nodeArray, $authArray);
+
+ if (empty($arrayDifferent)) {
+ return Response::json(['status' => 'success', 'message' => '没有需要生成授权的节点']);
+ }
+
+ foreach ($arrayDifferent as $nodeId) {
+ $obj = new NodeAuth();
+ $obj->node_id = $nodeId;
+ $obj->key = Str::random();
+ $obj->secret = Str::random(8);
+ $obj->save();
+ }
+
+ return Response::json(['status' => 'success', 'message' => '生成成功']);
+ }
+
+ // 重置节点授权
+ public function update(NodeAuth $auth)
+ {
+ if ($auth->update(['key' => Str::random(), 'secret' => Str::random(8)])) {
+ return Response::json(['status' => 'success', 'message' => '操作成功']);
+ }
+
+ return Response::json(['status' => 'fail', 'message' => '操作失败']);
+ }
+
+ // 删除节点授权
+ public function destroy(NodeAuth $auth)
+ {
+ try {
+ $auth->delete();
+ } catch (Exception $e) {
+ return Response::json(['status' => 'fail', 'message' => '错误:'.var_export($e, true)]);
+ }
+
+ return Response::json(['status' => 'success', 'message' => '操作成功']);
+ }
+}
diff --git a/app/Http/Controllers/Admin/NodeController.php b/app/Http/Controllers/Admin/NodeController.php
index b2d4e5b8..b49daf8d 100644
--- a/app/Http/Controllers/Admin/NodeController.php
+++ b/app/Http/Controllers/Admin/NodeController.php
@@ -10,18 +10,15 @@ use App\Models\Country;
use App\Models\Label;
use App\Models\Level;
use App\Models\Node;
-use App\Models\NodeAuth;
use App\Models\NodeCertificate;
use App\Models\NodePing;
+use App\Models\RuleGroup;
use App\Services\NodeService;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Log;
-use Redirect;
use Response;
-use Session;
-use Str;
class NodeController extends Controller
{
@@ -52,19 +49,18 @@ class NodeController extends Controller
$node->uptime = empty($node_info) ? 0 : seconds2time($node_info->uptime);
}
- $view['nodeList'] = $nodeList;
-
- return view('admin.node.index', $view);
+ return view('admin.node.index', ['nodeList' => $nodeList]);
}
// 添加节点页面
public function create()
{
return view('admin.node.info', [
- 'countryList' => Country::orderBy('code')->get(),
- 'levelList' => Level::orderBy('level')->get(),
- 'labelList' => Label::orderByDesc('sort')->orderBy('id')->get(),
- 'dvList' => NodeCertificate::orderBy('id')->get(),
+ 'countries' => Country::orderBy('code')->get(),
+ 'levels' => Level::orderBy('level')->get(),
+ 'ruleGroups' => RuleGroup::orderBy('id')->get(),
+ 'labels' => Label::orderByDesc('sort')->orderBy('id')->get(),
+ 'certs' => NodeCertificate::orderBy('id')->get(),
]);
}
@@ -76,8 +72,8 @@ class NodeController extends Controller
if ($node) {
// 生成节点标签
- if ($request->exists('labels')) {
- (new NodeService())->makeLabels($node->id, $request->input('labels'));
+ if ($request->has('labels')) {
+ $node->labels()->attach($request->input('labels'));
}
return Response::json(['status' => 'success', 'message' => '添加成功']);
@@ -92,27 +88,24 @@ class NodeController extends Controller
}
// 编辑节点页面
- public function edit($id)
+ public function edit(Node $node)
{
return view('admin.node.info', [
- 'node' => Node::with('labels')->find($id),
- 'countryList' => Country::orderBy('code')->get(),
- 'levelList' => Level::orderBy('level')->get(),
- 'labelList' => Label::orderByDesc('sort')->orderBy('id')->get(),
- 'dvList' => NodeCertificate::orderBy('id')->get(),
+ 'node' => $node,
+ 'countries' => Country::orderBy('code')->get(),
+ 'levels' => Level::orderBy('level')->get(),
+ 'ruleGroups' => RuleGroup::orderBy('id')->get(),
+ 'labels' => Label::orderByDesc('sort')->orderBy('id')->get(),
+ 'certs' => NodeCertificate::orderBy('id')->get(),
]);
}
// 编辑节点
- public function update(NodeRequest $request, $id): JsonResponse
+ public function update(NodeRequest $request, Node $node): JsonResponse
{
- $node = Node::find($id);
-
try {
- // 生成节点标签
- if ($request->exists('labels')) {
- (new NodeService())->makeLabels($node->id, $request->input('labels'));
- }
+ // 更新节点标签
+ $node->labels()->sync($request->input('labels'));
if ($node->update($request->except('_token', 'labels'))) {
return Response::json(['status' => 'success', 'message' => '编辑成功']);
@@ -127,10 +120,8 @@ class NodeController extends Controller
}
// 删除节点
- public function destroy($id): JsonResponse
+ public function destroy(Node $node): JsonResponse
{
- $node = Node::findOrFail($id);
-
try {
if ($node->delete()) {
return Response::json(['status' => 'success', 'message' => '删除成功']);
@@ -145,9 +136,8 @@ class NodeController extends Controller
}
// 节点信息验证
- public function checkNode($id): JsonResponse
+ public function checkNode(Node $node): JsonResponse
{
- $node = Node::find($id);
// 使用DDNS的node先获取ipv4地址
if ($node->is_ddns) {
$ip = gethostbyname($node->server);
@@ -174,9 +164,9 @@ class NodeController extends Controller
}
// 重载节点
- public function reload($id): JsonResponse
+ public function reload(Node $node): JsonResponse
{
- if (reloadNode::dispatchNow(Node::whereId($id)->get())) {
+ if (reloadNode::dispatchNow($node)) {
return Response::json(['status' => 'success', 'message' => '重载成功!']);
}
@@ -184,27 +174,14 @@ class NodeController extends Controller
}
// 节点流量监控
- public function nodeMonitor($id)
+ public function nodeMonitor(Node $node)
{
- $node = Node::find($id);
- if (! $node) {
- Session::flash('errorMsg', '节点不存在,请重试');
-
- return Redirect::back();
- }
-
- $view['nodeName'] = $node->name;
- $view['nodeServer'] = $node->server;
- $view = array_merge($view, $this->DataFlowChart($node->id, true));
-
- return view('admin.node.monitor', $view);
+ return view('admin.node.monitor', array_merge(['nodeName' => $node->name, 'nodeServer' => $node->server], $this->DataFlowChart($node->id, true)));
}
// Ping节点延迟
- public function pingNode($id): JsonResponse
+ public function pingNode(Node $node): JsonResponse
{
- $node = Node::findOrFail($id);
-
$result = NetworkDetection::ping($node->is_ddns ? $node->server : $node->ip);
if ($result) {
@@ -225,69 +202,15 @@ class NodeController extends Controller
// Ping节点延迟日志
public function pingLog(Request $request)
{
- $node_id = $request->input('nodeId');
+ $node_id = $request->input('id');
$query = NodePing::query();
if (isset($node_id)) {
$query->whereNodeId($node_id);
}
- $view['nodeList'] = Node::orderBy('id')->get();
- $view['pingLogs'] = $query->latest()->paginate(15)->appends($request->except('page'));
-
- return view('admin.node.ping', $view);
- }
-
- // 节点授权列表
- public function authList(Request $request)
- {
- $view['list'] = NodeAuth::orderBy('node_id')->paginate(15)->appends($request->except('page'));
-
- return view('admin.node.auth', $view);
- }
-
- // 添加节点授权
- public function addAuth(): JsonResponse
- {
- $nodeArray = Node::whereStatus(1)->orderBy('id')->pluck('id')->toArray();
- $authArray = NodeAuth::orderBy('node_id')->pluck('node_id')->toArray();
-
- $arrayDifferent = array_diff($nodeArray, $authArray);
-
- if (empty($arrayDifferent)) {
- return Response::json(['status' => 'success', 'message' => '没有需要生成授权的节点']);
- }
-
- foreach ($arrayDifferent as $nodeId) {
- $obj = new NodeAuth();
- $obj->node_id = $nodeId;
- $obj->key = Str::random();
- $obj->secret = Str::random(8);
- $obj->save();
- }
-
- return Response::json(['status' => 'success', 'message' => '生成成功']);
- }
-
- // 删除节点授权
- public function delAuth($id): JsonResponse
- {
- try {
- NodeAuth::whereId($id)->delete();
- } catch (Exception $e) {
- return Response::json(['status' => 'fail', 'message' => '错误:'.var_export($e, true)]);
- }
-
- return Response::json(['status' => 'success', 'message' => '操作成功']);
- }
-
- // 重置节点授权
- public function refreshAuth($id): JsonResponse
- {
- $ret = NodeAuth::find($id)->update(['key' => Str::random(), 'secret' => Str::random(8)]);
- if ($ret) {
- return Response::json(['status' => 'success', 'message' => '操作成功']);
- }
-
- return Response::json(['status' => 'fail', 'message' => '操作失败']);
+ return view('admin.node.ping', [
+ 'nodeList' => Node::orderBy('id')->get(),
+ 'pingLogs' => $query->latest()->paginate(15)->appends($request->except('page')),
+ ]);
}
}
diff --git a/app/Http/Controllers/Admin/PermissionController.php b/app/Http/Controllers/Admin/PermissionController.php
index 09356e57..516e6d79 100644
--- a/app/Http/Controllers/Admin/PermissionController.php
+++ b/app/Http/Controllers/Admin/PermissionController.php
@@ -3,17 +3,15 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
-use Illuminate\Http\Request;
-use Illuminate\Http\Response;
+use App\Http\Requests\Admin\PermissionRequest;
+use Exception;
use Spatie\Permission\Models\Permission;
class PermissionController extends Controller
{
public function index()
{
- $permissions = Permission::query()->paginate(15);
-
- return view('admin.permission.index', compact('permissions'));
+ return view('admin.permission.index', ['permissions' => Permission::query()->paginate(15)]);
}
public function create()
@@ -21,17 +19,9 @@ class PermissionController extends Controller
return view('admin.permission.info');
}
- public function store(Request $request)
+ public function store(PermissionRequest $request)
{
- $validator = validator()->make($request->all(), ['name' => 'required', 'description' => 'required']);
-
- if ($validator->fails()) {
- return redirect()->back()->withInput()->withErrors($validator->errors());
- }
-
- $permission = Permission::create($request->all());
-
- if ($permission) {
+ if ($permission = Permission::create($request->validated())) {
return redirect()->route('admin.permission.edit', $permission)->with('successMsg', '操作成功');
}
@@ -43,15 +33,9 @@ class PermissionController extends Controller
return view('admin.permission.info', compact('permission'));
}
- public function update(Request $request, Permission $permission)
+ public function update(PermissionRequest $request, Permission $permission)
{
- $validator = validator()->make($request->all(), ['name' => 'required', 'description' => 'required']);
-
- if ($validator->fails()) {
- return redirect()->back()->withInput()->withErrors($validator->errors());
- }
-
- if ($permission->update($request->all())) {
+ if ($permission->update($request->validated())) {
return redirect()->back()->with('successMsg', '操作成功');
}
@@ -63,9 +47,9 @@ class PermissionController extends Controller
try {
$permission->delete();
} catch (Exception $e) {
- return Response::json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
+ return response()->json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
}
- return Response::json(['status' => 'success', 'message' => '清理成功']);
+ return response()->json(['status' => 'success', 'message' => '清理成功']);
}
}
diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php
index 74ec310f..48a634bc 100644
--- a/app/Http/Controllers/Admin/RoleController.php
+++ b/app/Http/Controllers/Admin/RoleController.php
@@ -3,8 +3,8 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
-use Illuminate\Http\Request;
-use Illuminate\Http\Response;
+use App\Http\Requests\Admin\RoleRequest;
+use Exception;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
@@ -12,29 +12,19 @@ class RoleController extends Controller
{
public function index()
{
- $roles = Role::with('permissions')->paginate(15);
-
- return view('admin.role.index', compact('roles'));
+ return view('admin.role.index', ['roles' => Role::with('permissions')->paginate(15)]);
}
public function create()
{
- $permissions = Permission::all()->pluck('description', 'name');
-
- return view('admin.role.info', compact('permissions'));
+ return view('admin.role.info', ['permissions' => Permission::all()->pluck('description', 'name')]);
}
- public function store(Request $request)
+ public function store(RoleRequest $request)
{
- $validator = validator()->make($request->all(), ['name' => 'required', 'description' => 'required']);
+ if ($role = Role::create($request->only(['name', 'description']))) {
+ $role->givePermissionTo($request->input('permissions') ?: []);
- if ($validator->fails()) {
- return redirect()->back()->withInput()->withErrors($validator->errors());
- }
-
- $role = Role::create($request->except('permissions'));
- $permissions = $request->input('permissions') ?: [];
- if ($role->givePermissionTo($permissions)) {
return redirect()->route('admin.role.edit', $role)->with('successMsg', '操作成功');
}
@@ -43,27 +33,21 @@ class RoleController extends Controller
public function edit(Role $role)
{
- $role->load('permissions');
- $permissions = Permission::all()->pluck('description', 'name');
-
- return view('admin.role.info', compact('role', 'permissions'));
+ return view('admin.role.info', [
+ 'role' => $role->load('permissions'),
+ 'permissions' => Permission::all()->pluck('description', 'name'),
+ ]);
}
- public function update(Request $request, Role $role)
+ public function update(RoleRequest $request, Role $role)
{
- $validator = validator()->make($request->all(), ['name' => 'required', 'description' => 'required']);
-
- if ($validator->fails()) {
- return redirect()->back()->withInput()->withErrors($validator->errors());
- }
-
if ($role->name === 'Super Admin') {
return redirect()->back()->withInput()->withErrors('请勿修改超级管理员');
}
- $role->update($request->except('permissions'));
- $permissions = $request->input('permissions') ?: [];
- if ($role->syncPermissions($permissions)) {
+ if ($role->update($request->only(['name', 'description']))) {
+ $role->syncPermissions($request->input('permissions') ?: []);
+
return redirect()->back()->with('successMsg', '操作成功');
}
@@ -74,13 +58,13 @@ class RoleController extends Controller
{
try {
if ($role->name === 'Super Admin') {
- return Response::json(['status' => 'fail', 'message' => '请勿删除超级管理员']);
+ return response()->json(['status' => 'fail', 'message' => '请勿删除超级管理员']);
}
$role->delete();
} catch (Exception $e) {
- return Response::json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
+ return response()->json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
}
- return Response::json(['status' => 'success', 'message' => '清理成功']);
+ return response()->json(['status' => 'success', 'message' => '清理成功']);
}
}
diff --git a/app/Http/Controllers/Admin/RuleController.php b/app/Http/Controllers/Admin/RuleController.php
index 930b3f1d..3b4c327a 100644
--- a/app/Http/Controllers/Admin/RuleController.php
+++ b/app/Http/Controllers/Admin/RuleController.php
@@ -3,15 +3,14 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
+use App\Http\Requests\Admin\RuleRequest;
use App\Models\Node;
use App\Models\Rule;
-use App\Models\RuleGroup;
use App\Models\RuleLog;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Response;
-use Validator;
class RuleController extends Controller
{
@@ -25,31 +24,13 @@ class RuleController extends Controller
$query->whereType($type);
}
- $view['rules'] = $query->paginate(15)->appends($request->except('page'));
-
- return view('admin.rule.index', $view);
+ return view('admin.rule.index', ['rules' => $query->paginate(15)->appends($request->except('page'))]);
}
// 添加审计规则
- public function store(Request $request): JsonResponse
+ public function store(RuleRequest $request): JsonResponse
{
- $validator = Validator::make($request->all(), [
- 'type' => 'required|between:1,4',
- 'name' => 'required',
- 'pattern' => 'required',
- ]);
-
- if ($validator->fails()) {
- return Response::json(['status' => 'fail', 'message' => $validator->errors()->all()]);
- }
-
- $rule = new Rule();
- $rule->type = $request->input('type');
- $rule->name = $request->input('name');
- $rule->pattern = $request->input('pattern');
- $rule->save();
-
- if ($rule->id) {
+ if (Rule::create($request->validated())) {
return Response::json(['status' => 'success', 'message' => '提交成功']);
}
@@ -57,9 +38,9 @@ class RuleController extends Controller
}
// 编辑审计规则
- public function update(Request $request, $id): JsonResponse
+ public function update(RuleRequest $request, Rule $rule): JsonResponse
{
- if (Rule::find($id)->update(['name' => $request->input('rule_name'), 'pattern' => $request->input('rule_pattern')])) {
+ if ($rule->update($request->validated())) {
return Response::json(['status' => 'success', 'message' => '操作成功']);
}
@@ -67,18 +48,10 @@ class RuleController extends Controller
}
// 删除审计规则
- public function destroy($id): JsonResponse
+ public function destroy(Rule $rule): JsonResponse
{
try {
- Rule::whereId($id)->delete();
-
- foreach (RuleGroup::all() as $ruleGroup) {
- $rules = $ruleGroup->rules;
- if ($rules && in_array($id, $rules, true)) {
- $ruleGroup->rules = array_merge(array_diff($rules, [$id]));
- $ruleGroup->save();
- }
- }
+ $rule->delete();
} catch (Exception $e) {
return Response::json(['status' => 'fail', 'message' => '操作失败, '.$e->getMessage()]);
}
@@ -110,11 +83,11 @@ class RuleController extends Controller
$query->whereRuleId($ruleId);
}
- $view['nodeList'] = Node::all();
- $view['ruleList'] = Rule::all();
- $view['ruleLogs'] = $query->latest()->paginate(15)->appends($request->except('page'));
-
- return view('admin.rule.log', $view);
+ return view('admin.rule.log', [
+ 'nodes' => Node::all(),
+ 'rules' => Rule::all(),
+ 'ruleLogs' => $query->latest()->paginate(15)->appends($request->except('page')),
+ ]);
}
// 清除所有审计触发日志
@@ -125,8 +98,8 @@ class RuleController extends Controller
} catch (Exception $e) {
return Response::json(['status' => 'fail', 'message' => '清理失败, '.$e->getMessage()]);
}
- $result = RuleLog::doesntExist();
- if ($ret || $result) {
+
+ if ($ret || RuleLog::doesntExist()) {
return Response::json(['status' => 'success', 'message' => '清理成功']);
}
diff --git a/app/Http/Controllers/Admin/RuleGroupController.php b/app/Http/Controllers/Admin/RuleGroupController.php
index c9f0ef7c..1555969d 100644
--- a/app/Http/Controllers/Admin/RuleGroupController.php
+++ b/app/Http/Controllers/Admin/RuleGroupController.php
@@ -3,146 +3,67 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
-use App\Models\Node;
+use App\Http\Requests\Admin\RuleGroupRequest;
use App\Models\Rule;
use App\Models\RuleGroup;
-use App\Models\RuleGroupNode;
use Exception;
-use Illuminate\Http\JsonResponse;
-use Illuminate\Http\RedirectResponse;
-use Illuminate\Http\Request;
-use Redirect;
-use Response;
-use Validator;
class RuleGroupController extends Controller
{
// 审计规则分组列表
- public function index(Request $request)
+ public function index()
{
- $view['ruleGroupList'] = RuleGroup::paginate(15)->appends($request->except('page'));
-
- return view('admin.rule.group.index', $view);
+ return view('admin.rule.group.index', ['ruleGroups' => RuleGroup::paginate(15)->appends(request('page'))]);
}
// 添加审计规则分组页面
public function create()
{
- $view['ruleList'] = Rule::all();
-
- return view('admin.rule.group.info', $view);
+ return view('admin.rule.group.info', ['rules' => Rule::all()]);
}
// 添加审计规则分组
- public function store(Request $request): RedirectResponse
+ public function store(RuleGroupRequest $request)
{
- $validator = Validator::make($request->all(), [
- 'name' => 'required',
- 'type' => 'required|boolean',
- 'rules' => 'required',
- ]);
+ if ($group = RuleGroup::create($request->only('name', 'type'))) {
+ $group->rules()->attach($request->input('rules'));
- if ($validator->fails()) {
- return Redirect::back()->withInput()->withErrors($validator->errors());
+ return redirect(route('admin.rule.group.edit', $group))->with('successMsg', '操作成功');
}
- $obj = new RuleGroup();
- $obj->name = $request->input('name');
- $obj->type = (int) $request->input('type');
- $obj->rules = $request->input('rules');
- $obj->save();
-
- if ($obj->id) {
- return Redirect::back()->with('successMsg', '操作成功');
- }
-
- return Redirect::back()->withInput()->withErrors('操作失败');
+ return redirect()->back()->withInput()->withErrors('操作失败');
}
// 编辑审计规则分组页面
- public function edit($id)
+ public function edit(RuleGroup $group)
{
- $view['ruleGroup'] = RuleGroup::find($id);
- $view['ruleList'] = Rule::all();
-
- return view('admin.rule.group.info', $view);
+ return view('admin.rule.group.info', [
+ 'ruleGroup' => $group,
+ 'rules' => Rule::all(),
+ ]);
}
// 编辑审计规则分组
- public function update(Request $request, $id): RedirectResponse
+ public function update(RuleGroupRequest $request, RuleGroup $group)
{
- $validator = Validator::make($request->all(), [
- 'name' => 'required',
- 'type' => 'required|boolean',
- ]);
- if ($validator->fails()) {
- return Redirect::back()->withInput()->withErrors($validator->errors());
+ if ($group->update($request->only(['name', 'type']))) {
+ $group->rules()->sync($request->input('rules'));
+
+ return redirect()->back()->with('successMsg', '操作成功');
}
- $ret = RuleGroup::find($id)->update([
- 'name' => $request->input('name'),
- 'type' => $request->input('type'),
- 'rules' => $request->input('rules'),
- ]);
-
- if ($ret) {
- return Redirect::back()->with('successMsg', '操作成功');
- }
-
- return Redirect::back()->withInput()->withErrors('操作失败');
+ return redirect()->back()->withInput()->withErrors('操作失败');
}
// 删除审计规则分组
- public function destroy($id): JsonResponse
+ public function destroy(RuleGroup $group)
{
try {
- RuleGroup::whereId($id)->delete();
+ $group->delete();
} catch (Exception $e) {
- return Response::json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
+ return response()->json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
}
- return Response::json(['status' => 'success', 'message' => '清理成功']);
- }
-
- // 规则分组关联节点
- public function assignNode($id)
- {
- $view['ruleGroup'] = RuleGroup::find($id);
- $view['nodeList'] = Node::all();
-
- return view('admin.rule.group.assign', $view);
- }
-
- // 规则分组关联节点
- public function assign(Request $request, $id)
- {
- $nodes = $request->input('nodes');
- $ruleGroup = RuleGroup::findOrFail($id);
-
- try {
- if ($ruleGroup->nodes === $nodes) {
- return Redirect::back()->with('successMsg', '检测为未修改,无变动!');
- }
- RuleGroupNode::whereRuleGroupId($id)->delete();
- if ($nodes) {
- $ruleGroup->nodes = $nodes;
- if (! $ruleGroup->save()) {
- return Redirect::back()->withErrors('更新错误!');
- }
-
- foreach ($nodes as $nodeId) {
- $obj = new RuleGroupNode();
- $obj->rule_group_id = $id;
- $obj->node_id = $nodeId;
- $obj->save();
- }
- } else {
- RuleGroup::find($id)->update(['nodes' => null]);
- }
- } catch (Exception $e) {
- return Redirect::back()->withInput()->withErrors($e->getMessage());
- }
-
- return Redirect::back()->with('successMsg', '操作成功');
+ return response()->json(['status' => 'success', 'message' => '清理成功']);
}
}
diff --git a/app/Http/Controllers/Admin/ShopController.php b/app/Http/Controllers/Admin/ShopController.php
index d6d6d914..ca16001f 100644
--- a/app/Http/Controllers/Admin/ShopController.php
+++ b/app/Http/Controllers/Admin/ShopController.php
@@ -17,11 +17,6 @@ use Redirect;
use Response;
use Str;
-/**
- * 商店控制器.
- *
- * Class ShopController
- */
class ShopController extends Controller
{
// 商品列表
@@ -40,17 +35,13 @@ class ShopController extends Controller
$query->whereStatus($status);
}
- $view['goodsList'] = $query->orderByDesc('status')->paginate(10)->appends($request->except('page'));
-
- return view('admin.shop.index', $view);
+ return view('admin.shop.index', ['goodsList' => $query->orderByDesc('status')->paginate(10)->appends($request->except('page'))]);
}
// 添加商品页面
public function create()
{
- $view['levelList'] = Level::orderBy('level')->get();
-
- return view('admin.shop.info', $view);
+ return view('admin.shop.info', ['levels' => Level::orderBy('level')->get()]);
}
// 添加商品
@@ -71,10 +62,9 @@ class ShopController extends Controller
return $path;
}
}
- $good = Goods::create($data);
- if ($good) {
- return Redirect::route('admin.goods.edit', $good->id)->with('successMsg', '添加成功');
+ if ($good = Goods::create($data)) {
+ return Redirect::route('admin.goods.edit', $good)->with('successMsg', '添加成功');
}
} catch (Exception $e) {
Log::error('添加商品信息异常:'.$e->getMessage());
@@ -99,18 +89,17 @@ class ShopController extends Controller
}
// 编辑商品页面
- public function edit($id)
+ public function edit(Goods $good)
{
- $view['goods'] = Goods::find($id);
- $view['levelList'] = Level::orderBy('level')->get();
-
- return view('admin.shop.info', $view);
+ return view('admin.shop.info', [
+ 'good' => $good,
+ 'levels' => Level::orderBy('level')->get(),
+ ]);
}
// 编辑商品
- public function update(ShopUpdateRequest $request, $id)
+ public function update(ShopUpdateRequest $request, Goods $good)
{
- $goods = Goods::findOrFail($id);
$data = $request->except('_token', '_method', 'logo');
// 商品LOGO
if ($request->hasFile('logo')) {
@@ -126,7 +115,7 @@ class ShopController extends Controller
$data['is_hot'] = $request->input('is_hot') ? 1 : 0;
$data['status'] = $request->input('status') ? 1 : 0;
- if ($goods->update($data)) {
+ if ($good->update($data)) {
return Redirect::back()->with('successMsg', '编辑成功');
}
} catch (Exception $e) {
@@ -139,10 +128,10 @@ class ShopController extends Controller
}
// 删除商品
- public function destroy($id): JsonResponse
+ public function destroy(Goods $good): JsonResponse
{
try {
- if (Goods::find($id)->delete()) {
+ if ($good->delete()) {
return Response::json(['status' => 'success', 'message' => '删除成功']);
}
} catch (Exception $e) {
diff --git a/app/Http/Controllers/Admin/SubscribeController.php b/app/Http/Controllers/Admin/SubscribeController.php
index 93ba0d6d..122b6d08 100644
--- a/app/Http/Controllers/Admin/SubscribeController.php
+++ b/app/Http/Controllers/Admin/SubscribeController.php
@@ -5,7 +5,6 @@ namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\UserSubscribe;
use App\Models\UserSubscribeLog;
-use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Response;
@@ -39,13 +38,11 @@ class SubscribeController extends Controller
$query->whereStatus($status);
}
- $view['subscribeList'] = $query->latest()->paginate(20)->appends($request->except('page'));
-
- return view('admin.subscribe.index', $view);
+ return view('admin.subscribe.index', ['subscribeList' => $query->latest()->paginate(20)->appends($request->except('page'))]);
}
//订阅记录
- public function subscribeLog(Request $request, $id)
+ public function subscribeLog($id)
{
$query = UserSubscribeLog::with('user:email');
@@ -53,19 +50,12 @@ class SubscribeController extends Controller
$query->whereUserSubscribeId($id);
}
- $view['subscribeLog'] = $query->latest()->paginate(20)->appends($request->except('page'));
-
- return view('admin.subscribe.log', $view);
+ return view('admin.subscribe.log', ['subscribeLog' => $query->latest()->paginate(20)->appends(\request('page'))]);
}
// 设置用户的订阅的状态
- public function setSubscribeStatus(Request $request, $id): JsonResponse
+ public function setSubscribeStatus(UserSubscribe $subscribe)
{
- if (empty($id)) {
- return Response::json(['status' => 'fail', 'message' => '操作异常']);
- }
- $subscribe = UserSubscribe::find($id);
-
if ($subscribe->status) {
$subscribe->update(['status' => 0, 'ban_time' => time(), 'ban_desc' => '后台手动封禁']);
} else {
diff --git a/app/Http/Controllers/Admin/SystemController.php b/app/Http/Controllers/Admin/SystemController.php
index 1ad373b9..9a85e73b 100644
--- a/app/Http/Controllers/Admin/SystemController.php
+++ b/app/Http/Controllers/Admin/SystemController.php
@@ -16,10 +16,7 @@ class SystemController extends Controller
// 系统设置
public function index()
{
- $view = Config::pluck('value', 'name')->toArray();
- $view['labelList'] = Label::orderByDesc('sort')->orderBy('id')->get();
-
- return view('admin.config.system', $view);
+ return view('admin.config.system', array_merge(['labelList' => Label::orderByDesc('sort')->orderBy('id')->get()], Config::pluck('value', 'name')->toArray()));
}
// 设置系统扩展信息,例如客服、统计代码
diff --git a/app/Http/Controllers/Admin/TicketController.php b/app/Http/Controllers/Admin/TicketController.php
index d3ba249f..a7387b6e 100644
--- a/app/Http/Controllers/Admin/TicketController.php
+++ b/app/Http/Controllers/Admin/TicketController.php
@@ -3,12 +3,10 @@
namespace App\Http\Controllers\Admin;
use App\Components\Helpers;
-use App\Components\PushNotification;
use App\Http\Controllers\Controller;
use App\Mail\closeTicket;
use App\Mail\replyTicket;
use App\Models\Ticket;
-use App\Models\TicketReply;
use App\Models\User;
use Auth;
use Illuminate\Http\Request;
@@ -27,7 +25,7 @@ class TicketController extends Controller
{
$email = $request->input('email');
- $query = Ticket::whereAdminId(Auth::id())->orwhere('admin_id', null);
+ $query = Ticket::whereAdminId(Auth::id())->orwhere('admin_id');
if (isset($email)) {
$query->whereHas('user', static function ($q) use ($email) {
@@ -35,9 +33,7 @@ class TicketController extends Controller
});
}
- $view['ticketList'] = $query->latest()->paginate(10)->appends($request->except('page'));
-
- return view('admin.ticket.index', $view);
+ return view('admin.ticket.index', ['ticketList' => $query->latest()->paginate(10)->appends($request->except('page'))]);
}
// 创建工单
@@ -76,28 +72,22 @@ class TicketController extends Controller
}
// 回复
- public function edit($id)
+ public function edit(Ticket $ticket)
{
- $view['ticket'] = Ticket::find($id);
- $view['replyList'] = TicketReply::whereTicketId($id)->oldest()->get();
-
- return view('admin.ticket.reply', $view);
+ return view('admin.ticket.reply', [
+ 'ticket' => $ticket,
+ 'replyList' => $ticket->reply()->oldest()->get(),
+ ]);
}
// 回复工单
- public function update(Request $request, $id)
+ public function update(Request $request, Ticket $ticket)
{
$content = substr(str_replace(['atob', 'eval'], '', clean($request->input('content'))), 0, 300);
- $obj = new TicketReply();
- $obj->ticket_id = $id;
- $obj->admin_id = Auth::id();
- $obj->content = $content;
-
- if ($obj->save()) {
+ if ($ticket->reply()->create(['admin_id' => Auth::id(), 'content' => $content])) {
// 将工单置为已回复
- $ticket = Ticket::with('user')->find($id);
- Ticket::whereId($id)->update(['status' => 1]);
+ $ticket->update(['status' => 1]);
$title = '工单回复提醒';
$content = '标题:'.$ticket->title.'
管理员回复:'.$content;
@@ -113,10 +103,8 @@ class TicketController extends Controller
}
// 关闭工单
- public function destroy($id)
+ public function destroy(Ticket $ticket)
{
- $ticket = Ticket::with('user')->find($id);
-
if (! $ticket->close()) {
return Response::json(['status' => 'fail', 'message' => '关闭失败']);
}
diff --git a/app/Http/Controllers/Admin/ToolsController.php b/app/Http/Controllers/Admin/ToolsController.php
index 46a09631..8c97a47c 100644
--- a/app/Http/Controllers/Admin/ToolsController.php
+++ b/app/Http/Controllers/Admin/ToolsController.php
@@ -197,10 +197,7 @@ class ToolsController extends Controller
}
$logs = $this->tail($file, 10000);
- if (false === $logs) {
- $view['urlList'] = [];
- } else {
- $url = [];
+ if (false !== $logs) {
foreach ($logs as $log) {
if (str_contains($log, 'TCP connecting')) {
continue;
@@ -220,10 +217,8 @@ class ToolsController extends Controller
}
}
}
-
- $view['urlList'] = array_unique($url);
}
- return view('admin.tools.analysis', $view);
+ return view('admin.tools.analysis', ['urlList' => array_unique($url ?? [])]);
}
}
diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 8290e58b..b00f6c3f 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -9,16 +9,15 @@ use App\Http\Requests\Admin\UserStoreRequest;
use App\Http\Requests\Admin\UserUpdateRequest;
use App\Models\Level;
use App\Models\Node;
+use App\Models\Order;
use App\Models\User;
use App\Models\UserGroup;
use App\Models\UserHourlyDataFlow;
use Auth;
-use DB;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Log;
-use Redirect;
use Response;
use Session;
use Spatie\Permission\Models\Role;
@@ -96,10 +95,16 @@ class UserController extends Controller
}
// 不活跃用户
- if ($request->input('unActive')) {
+ if ($request->has('unActive')) {
$query->whereBetween('t', [1, strtotime('-'.sysConfig('expire_days').' days')])->whereEnable(1);
}
+ // 不活跃用户
+ if ($request->has('paying')) {
+ $payingUser = Order::whereStatus(2)->where('goods_id', '<>', 0)->whereIsExpire(0)->where('amount', '>', 0)->pluck('user_id')->unique();
+ $query->whereIn('id', $payingUser);
+ }
+
// 1小时内流量异常用户
if ($flowAbnormal) {
$query->whereIn('id', (new UserHourlyDataFlow)->trafficAbnormal());
@@ -119,14 +124,12 @@ class UserController extends Controller
$roles = Role::all()->pluck('description', 'name');
} elseif (Auth::getUser()->hasPermissionTo('give roles')) {
$roles = Auth::getUser()->roles();
- } else {
- $roles = [];
}
return view('admin.user.info', [
'levels' => Level::orderBy('level')->get(),
'userGroups' => UserGroup::orderBy('id')->get(),
- 'roles' => $roles,
+ 'roles' => $roles ?? [],
]);
}
@@ -173,15 +176,13 @@ class UserController extends Controller
$roles = Role::all()->pluck('description', 'name');
} elseif (Auth::getUser()->hasPermissionTo('give roles')) {
$roles = Auth::getUser()->roles();
- } else {
- $roles = [];
}
return view('admin.user.info', [
'user' => $user->load('inviter:id,email'),
'levels' => Level::orderBy('level')->get(),
'userGroups' => UserGroup::orderBy('id')->get(),
- 'roles' => $roles,
+ 'roles' => $roles ?? [],
]);
}
@@ -256,38 +257,26 @@ class UserController extends Controller
}
// 批量生成账号
- public function batchAddUsers(Request $request)
+ public function batchAddUsers()
{
+ $preset = ['transfer_enable' => 1024 * GB, 'expired_at' => date('Y-m-d', strtotime('+365 days'))];
+
try {
- DB::beginTransaction();
-
- for ($i = 0; $i < $request->input('amount', 1); $i++) {
- $uid = Helpers::addUser(Str::random(8).'@auto.generate', Str::random(), 1024 * GB, 365);
-
- if ($uid) {
- // 写入用户流量变动记录
- Helpers::addUserTrafficModifyLog($uid, null, 0, 1024 * GB, '后台批量生成用户');
- }
+ for ($i = 0; $i < (int) request('amount', 1); $i++) {
+ $user = factory(User::class)->create($preset);
+ // 写入用户流量变动记录
+ Helpers::addUserTrafficModifyLog($user->id, null, 0, 1024 * GB, '后台批量生成用户');
}
- DB::commit();
-
return Response::json(['status' => 'success', 'message' => '批量生成账号成功']);
} catch (Exception $e) {
- DB::rollBack();
-
return Response::json(['status' => 'fail', 'message' => '批量生成账号失败:'.$e->getMessage()]);
}
}
// 转换成某个用户的身份
- public function switchToUser(Request $request): JsonResponse
+ public function switchToUser(User $user): JsonResponse
{
- $user = User::find($request->input('user_id'));
- if (! $user) {
- return Response::json(['status' => 'fail', 'message' => '用户不存在']);
- }
-
// 存储当前管理员ID,并将当前登录信息改成要切换的用户的身份信息
Session::put('admin', Auth::id());
Session::put('user', $user->id);
@@ -296,10 +285,10 @@ class UserController extends Controller
}
// 重置用户流量
- public function resetTraffic(Request $request): JsonResponse
+ public function resetTraffic(User $user): JsonResponse
{
try {
- User::find($request->input('id'))->update(['u' => 0, 'd' => 0]);
+ $user->update(['u' => 0, 'd' => 0]);
} catch (Exception $e) {
Log::error('流量重置失败:'.$e->getMessage());
@@ -310,19 +299,17 @@ class UserController extends Controller
}
// 操作用户余额
- public function handleUserCredit(Request $request): JsonResponse
+ public function handleUserCredit(Request $request, User $user): JsonResponse
{
- $userId = $request->input('user_id');
- $amount = $request->input('amount');
+ $amount = (int) $request->input('amount');
- if (empty($userId) || empty($amount)) {
+ if (empty($amount)) {
return Response::json(['status' => 'fail', 'message' => '充值异常']);
}
- $user = User::find($userId);
// 加减余额
if ($user->updateCredit($amount)) {
- Helpers::addUserCreditLog($userId, null, $user->credit, $user->credit + $amount, $amount, '后台手动充值'); // 写入余额变动日志
+ Helpers::addUserCreditLog($user->id, null, $user->credit, $user->credit + $amount, $amount, '后台手动充值'); // 写入余额变动日志
return Response::json(['status' => 'success', 'message' => '充值成功']);
}
@@ -331,19 +318,15 @@ class UserController extends Controller
}
// 导出配置信息
- public function export(Request $request, User $user)
+ public function export(User $user)
{
- if ($user === null) {
- return Redirect::back();
- }
-
- $view['nodeList'] = Node::whereStatus(1)->orderByDesc('sort')->orderBy('id')->paginate(15)->appends($request->except('page'));
- $view['user'] = $user;
-
- return view('admin.user.export', $view);
+ return view('admin.user.export', [
+ 'user' => $user,
+ 'nodeList' => Node::whereStatus(1)->orderByDesc('sort')->orderBy('id')->paginate(15)->appends(\request('page')),
+ ]);
}
- public function exportProxyConfig(Request $request, $uid): JsonResponse
+ public function exportProxyConfig(Request $request, User $user): JsonResponse
{
$node = Node::find($request->input('id'));
if ($node->type === 1) {
@@ -356,7 +339,7 @@ class UserController extends Controller
$proxyType = 'V2Ray';
}
- $data = $this->getUserNodeInfo($uid, $node->id, $request->input('type') !== 'text' ? 0 : 1);
+ $data = $this->getUserNodeInfo($user->id, $node->id, $request->input('type') !== 'text' ? 0 : 1);
return Response::json(['status' => 'success', 'data' => $data, 'title' => $proxyType]);
}
diff --git a/app/Http/Controllers/Admin/UserGroupController.php b/app/Http/Controllers/Admin/UserGroupController.php
index 5202acca..c883cc3d 100644
--- a/app/Http/Controllers/Admin/UserGroupController.php
+++ b/app/Http/Controllers/Admin/UserGroupController.php
@@ -3,92 +3,71 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
+use App\Http\Requests\Admin\UserGroupRequest;
use App\Models\Node;
-use App\Models\User;
use App\Models\UserGroup;
use Exception;
-use Illuminate\Http\JsonResponse;
-use Illuminate\Http\RedirectResponse;
-use Illuminate\Http\Request;
-use Redirect;
-use Response;
-use Validator;
class UserGroupController extends Controller
{
- public function index(Request $request)
+ public function index()
{
- $view['list'] = UserGroup::paginate(15)->appends($request->except('page'));
-
- return view('admin.user.group.index', $view);
+ return view('admin.user.group.index', ['groups' => UserGroup::paginate(15)->appends(request('page'))]);
}
// 添加用户分组页面
public function create()
{
- $nodes = Node::whereStatus(1)->pluck('name', 'id');
-
- return view('admin.user.group.info', compact('nodes'));
+ return view('admin.user.group.info', ['nodes' => Node::whereStatus(1)->pluck('name', 'id')]);
}
// 添加用户分组
- public function store(Request $request): RedirectResponse
+ public function store(UserGroupRequest $request)
{
- $validator = Validator::make($request->all(), ['name' => 'required']);
+ if ($userGroup = UserGroup::create($request->only(['name']))) {
+ $userGroup->nodes()->attach($request->input('nodes'));
- if ($validator->fails()) {
- return Redirect::back()->withInput()->withErrors($validator->errors());
+ return redirect(route('admin.user.group.edit', $userGroup))->with('successMsg', '操作成功');
}
- $userGroup = UserGroup::create(['name' => $request->input('name'), 'nodes' => $request->input('nodes')]);
-
- if ($userGroup) {
- return Redirect::route('admin.user.group.edit', $userGroup)->with('successMsg', '操作成功');
- }
-
- return Redirect::back()->withInput()->withErrors('操作失败');
+ return redirect()->back()->withInput()->withErrors('操作失败');
}
// 编辑用户分组页面
public function edit(UserGroup $group)
{
- $nodes = Node::whereStatus(1)->pluck('name', 'id');
-
- return view('admin.user.group.info', compact('group', 'nodes'));
+ return view('admin.user.group.info', [
+ 'group' => $group,
+ 'nodes' => Node::whereStatus(1)->pluck('name', 'id'),
+ ]);
}
// 编辑用户分组
- public function update(Request $request, UserGroup $group)
+ public function update(UserGroupRequest $request, UserGroup $group)
{
- $validator = Validator::make($request->all(), ['name' => 'required']);
+ if ($group->update($request->only(['name']))) {
+ $group->nodes()->sync($request->input('nodes'));
- if ($validator->fails()) {
- return Redirect::back()->withInput()->withErrors($validator->errors());
+ return redirect()->back()->with('successMsg', '操作成功');
}
- $group->name = $request->input('name');
- $group->nodes = $request->input('nodes');
- if ($group->save()) {
- return Redirect::back()->with('successMsg', '操作成功');
- }
-
- return Redirect::back()->withInput()->withErrors('操作失败');
+ return redirect()->back()->withInput()->withErrors('操作失败');
}
// 删除用户分组
- public function destroy(UserGroup $group): JsonResponse
+ public function destroy(UserGroup $group)
{
// 校验该分组下是否存在关联账号
- if (User::whereGroupId($group->id)->count()) {
- return Response::json(['status' => 'fail', 'message' => '该分组下存在关联账号,请先取消关联!']);
+ if ($group->users->isNotEmpty()) {
+ return response()->json(['status' => 'fail', 'message' => '该分组下存在关联账号,请先取消关联!']);
}
try {
$group->delete();
} catch (Exception $e) {
- return Response::json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
+ return response()->json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
}
- return Response::json(['status' => 'success', 'message' => '清理成功']);
+ return response()->json(['status' => 'success', 'message' => '清理成功']);
}
}
diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php
index 27fee618..32b1dfbe 100644
--- a/app/Http/Controllers/AdminController.php
+++ b/app/Http/Controllers/AdminController.php
@@ -2,7 +2,6 @@
namespace App\Http\Controllers;
-use App\Components\Helpers;
use App\Models\Country;
use App\Models\Invite;
use App\Models\Label;
@@ -15,68 +14,56 @@ use App\Models\ReferralLog;
use App\Models\SsConfig;
use App\Models\User;
use App\Models\UserHourlyDataFlow;
-use Auth;
-use Hash;
use Illuminate\Http\JsonResponse;
-use Illuminate\Http\Request;
use Log;
use PhpOffice\PhpSpreadsheet\Exception;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
-use Redirect;
use Response;
use Str;
-/**
- * 管理员控制器.
- *
- * Class AdminController
- */
class AdminController extends Controller
{
public function index()
{
$past = strtotime('-'.sysConfig('expire_days').' days');
- $view['expireDays'] = sysConfig('expire_days');
- $view['totalUserCount'] = User::count(); // 总用户数
- $view['todayRegister'] = User::whereDate('created_at', date('Y-m-d'))->count(); // 今日注册用户
- $view['enableUserCount'] = User::whereEnable(1)->count(); // 有效用户数
- $view['activeUserCount'] = User::where('t', '>=', $past)->count(); // 活跃用户数
- $view['unActiveUserCount'] = User::whereEnable(1)->whereBetween('t', [1, $past])->count(); // 不活跃用户数
- $view['onlineUserCount'] = User::where('t', '>=', strtotime('-10 minutes'))->count(); // 10分钟内在线用户数
- $view['expireWarningUserCount'] = User::whereBetween('expired_at', [date('Y-m-d'), date('Y-m-d', strtotime('+'.sysConfig('expire_days').' days'))])->count(); // 临近过期用户数
- $view['largeTrafficUserCount'] = User::whereRaw('(u + d)/transfer_enable >= 0.9')->where('status', '<>', -1)->count(); // 流量使用超过90%的用户
- $view['flowAbnormalUserCount'] = count((new UserHourlyDataFlow)->trafficAbnormal()); // 1小时内流量异常用户
- $view['nodeCount'] = Node::count();
- $view['unnormalNodeCount'] = Node::whereStatus(0)->count();
- $view['flowCount'] = flowAutoShow(NodeDailyDataFlow::where('created_at', '>=', date('Y-m-d', strtotime('-30 days')))->sum('total'));
- $view['todayFlowCount'] = flowAutoShow(NodeDailyDataFlow::where('created_at', '>=', date('Y-m-d'))->sum('total'));
- $view['totalFlowCount'] = flowAutoShow(NodeDailyDataFlow::sum('total'));
- $view['totalCredit'] = User::where('credit', '<>', 0)->sum('credit') / 100;
- $view['totalWaitRefAmount'] = ReferralLog::whereIn('status', [0, 1])->sum('commission') / 100;
- $view['todayWaitRefAmount'] = ReferralLog::whereIn('status', [0, 1])->whereDate('created_at', date('Y-m-d'))->sum('commission') / 100;
- $view['totalRefAmount'] = ReferralApply::whereStatus(2)->sum('amount') / 100;
- $view['totalOrder'] = Order::count();
- $view['todayOrder'] = Order::whereDate('created_at', date('Y-m-d'))->count();
- $view['totalOnlinePayOrder'] = Order::where('pay_type', '<>', 0)->count();
- $view['todayOnlinePayOrder'] = Order::where('pay_type', '<>', 0)->whereDate('created_at', date('Y-m-d'))->count();
- $view['totalSuccessOrder'] = Order::whereStatus(2)->count();
- $view['todaySuccessOrder'] = Order::whereStatus(2)->whereDate('created_at', date('Y-m-d'))->count();
-
- return view('admin.index', $view);
+ return view('admin.index', [
+ 'expireDays' => sysConfig('expire_days'),
+ 'totalUserCount' => User::count(), // 总用户数
+ 'todayRegister' => User::whereDate('created_at', date('Y-m-d'))->count(), // 今日注册用户
+ 'enableUserCount' => User::whereEnable(1)->count(), // 有效用户数
+ 'activeUserCount' => User::where('t', '>=', $past)->count(), // 活跃用户数,
+ 'payingUserCount' => Order::whereStatus(2)->where('goods_id', '<>', 0)->whereIsExpire(0)->where('amount', '>', 0)->pluck('user_id')->unique()->count(), // 付费用户数
+ 'unActiveUserCount' => User::whereEnable(1)->whereBetween('t', [1, $past])->count(), // 不活跃用户数
+ 'onlineUserCount' => User::where('t', '>=', strtotime('-10 minutes'))->count(), // 10分钟内在线用户数
+ 'expireWarningUserCount' => User::whereBetween('expired_at', [date('Y-m-d'), date('Y-m-d', strtotime('+'.sysConfig('expire_days').' days'))])->count(), // 临近过期用户数
+ 'largeTrafficUserCount' => User::whereRaw('(u + d)/transfer_enable >= 0.9')->where('status', '<>', -1)->count(), // 流量使用超过90%的用户
+ 'flowAbnormalUserCount' => count((new UserHourlyDataFlow)->trafficAbnormal()), // 1小时内流量异常用户
+ 'nodeCount' => Node::count(),
+ 'unnormalNodeCount' => Node::whereStatus(0)->count(),
+ 'flowCount' => flowAutoShow(NodeDailyDataFlow::where('created_at', '>=', date('Y-m-d', strtotime('-30 days')))->sum('total')),
+ 'todayFlowCount' => flowAutoShow(NodeDailyDataFlow::where('created_at', '>=', date('Y-m-d'))->sum('total')),
+ 'totalFlowCount' => flowAutoShow(NodeDailyDataFlow::sum('total')),
+ 'totalCredit' => User::where('credit', '<>', 0)->sum('credit') / 100,
+ 'totalWaitRefAmount' => ReferralLog::whereIn('status', [0, 1])->sum('commission') / 100,
+ 'todayWaitRefAmount' => ReferralLog::whereIn('status', [0, 1])->whereDate('created_at', date('Y-m-d'))->sum('commission') / 100,
+ 'totalRefAmount' => ReferralApply::whereStatus(2)->sum('amount') / 100,
+ 'totalOrder' => Order::count(),
+ 'todayOrder' => Order::whereDate('created_at', date('Y-m-d'))->count(),
+ 'totalOnlinePayOrder' => Order::where('pay_type', '<>', 0)->count(),
+ 'todayOnlinePayOrder' => Order::where('pay_type', '<>', 0)->whereDate('created_at', date('Y-m-d'))->count(),
+ 'totalSuccessOrder' => Order::whereStatus(2)->count(),
+ 'todaySuccessOrder' => Order::whereStatus(2)->whereDate('created_at', date('Y-m-d'))->count(),
+ ]);
}
// 邀请码列表
- public function inviteList(Request $request)
+ public function inviteList()
{
- $view['inviteList'] = Invite::with(['invitee:id,email', 'inviter:id,email'])
- ->orderBy('status')
- ->orderByDesc('id')
- ->paginate(15)
- ->appends($request->except('page'));
-
- return view('admin.inviteList', $view);
+ return view('admin.inviteList', [
+ 'inviteList' => Invite::with(['invitee:id,email', 'inviter:id,email'])->orderBy('status')->orderByDesc('id')->paginate(15)->appends(request('page')),
+ ]);
}
// 生成邀请码
@@ -128,13 +115,13 @@ class AdminController extends Controller
public function config()
{
- $view['methodList'] = SsConfig::type(1)->get();
- $view['protocolList'] = SsConfig::type(2)->get();
- $view['obfsList'] = SsConfig::type(3)->get();
- $view['countryList'] = Country::all();
- $view['levelList'] = Level::all();
- $view['labelList'] = Label::with('nodes')->get();
-
- return view('admin.config.config', $view);
+ return view('admin.config.config', [
+ 'methods' => SsConfig::type(1)->get(),
+ 'protocols' => SsConfig::type(2)->get(),
+ 'obfsList' => SsConfig::type(3)->get(),
+ 'countries' => Country::all(),
+ 'levels' => Level::all(),
+ 'labels' => Label::with('nodes')->get(),
+ ]);
}
}
diff --git a/app/Http/Controllers/Api/Client/V1Controller.php b/app/Http/Controllers/Api/Client/V1Controller.php
index 34125298..2431a2d0 100644
--- a/app/Http/Controllers/Api/Client/V1Controller.php
+++ b/app/Http/Controllers/Api/Client/V1Controller.php
@@ -84,7 +84,7 @@ class V1Controller extends Controller
public function nodeList(int $id = null)
{
$user = auth()->user();
- $nodes = $user->userAccessNodes()->get();
+ $nodes = $user->nodes()->get();
if (isset($id)) {
$node = $nodes->where('id', $id)->first();
diff --git a/app/Http/Controllers/Api/WebApi/BaseController.php b/app/Http/Controllers/Api/WebApi/BaseController.php
index 02e252e4..13646c41 100644
--- a/app/Http/Controllers/Api/WebApi/BaseController.php
+++ b/app/Http/Controllers/Api/WebApi/BaseController.php
@@ -5,11 +5,8 @@ namespace App\Http\Controllers\Api\WebApi;
use App\Components\Helpers;
use App\Models\Node;
use App\Models\NodeHeartBeat;
+use App\Models\NodeOnlineIp;
use App\Models\NodeOnlineLog;
-use App\Models\NodeOnlineUserIp;
-use App\Models\Rule;
-use App\Models\RuleGroup;
-use App\Models\RuleGroupNode;
use App\Models\RuleLog;
use App\Models\User;
use App\Models\UserDataFlowLog;
@@ -74,7 +71,7 @@ class BaseController
return $this->returnData('上报节点在线用户IP信息失败,请检查字段');
}
- $obj = new NodeOnlineUserIp();
+ $obj = new NodeOnlineIp();
$obj->node_id = $id;
$obj->user_id = $input['uid'];
$obj->ip = $input['ip'];
@@ -137,27 +134,21 @@ class BaseController
}
// 获取节点的审计规则
- public function getNodeRule($id): JsonResponse
+ public function getNodeRule(Node $node): JsonResponse
{
- $nodeRule = RuleGroupNode::whereNodeId($id)->first();
$data = [];
//节点未设置任何审计规则
- if ($nodeRule) {
- $ruleGroup = RuleGroup::find($nodeRule->rule_group_id);
- if ($ruleGroup && $ruleGroup->rules) {
- foreach ($ruleGroup->rules as $ruleId) {
- $rule = Rule::find($ruleId);
- if ($rule) {
- $data[] = [
- 'id' => $rule->id,
- 'type' => $rule->type_api_label,
- 'pattern' => $rule->pattern,
- ];
- }
- }
-
- return $this->returnData('获取节点审计规则成功', 'success', 200, ['mode' => $ruleGroup->type ? 'reject' : 'allow', 'rules' => $data]);
+ if ($node->rule_group_id) {
+ $ruleGroup = $node->ruleGroup;
+ foreach ($ruleGroup->rules as $rule) {
+ $data[] = [
+ 'id' => $rule->id,
+ 'type' => $rule->type_api_label,
+ 'pattern' => $rule->pattern,
+ ];
}
+
+ return $this->returnData('获取节点审计规则成功', 'success', 200, ['mode' => $ruleGroup->type ? 'reject' : 'allow', 'rules' => $data]);
}
//放行
@@ -173,9 +164,8 @@ class BaseController
$obj->node_id = $id;
$obj->rule_id = $request->input('rule_id');
$obj->reason = $request->input('reason');
- $obj->save();
- if ($obj->id) {
+ if ($obj->save()) {
return $this->returnData('上报用户触发审计规则日志成功', 'success', 200);
}
}
diff --git a/app/Http/Controllers/Api/WebApi/TrojanController.php b/app/Http/Controllers/Api/WebApi/TrojanController.php
index 03c0056a..cbd5e3a5 100644
--- a/app/Http/Controllers/Api/WebApi/TrojanController.php
+++ b/app/Http/Controllers/Api/WebApi/TrojanController.php
@@ -8,10 +8,8 @@ use Illuminate\Http\JsonResponse;
class TrojanController extends BaseController
{
// 获取节点信息
- public function getNodeInfo($id): JsonResponse
+ public function getNodeInfo(Node $node): JsonResponse
{
- $node = Node::find($id);
-
return $this->returnData('获取节点信息成功', 'success', 200, [
'id' => $node->id,
'is_udp' => $node->is_udp ? true : false,
@@ -26,12 +24,9 @@ class TrojanController extends BaseController
}
// 获取节点可用的用户列表
- public function getUserList($id): JsonResponse
+ public function getUserList(Node $node): JsonResponse
{
- $users = Node::find($id)->node_access_users;
- $data = [];
-
- foreach ($users as $user) {
+ foreach ($node->users() as $user) {
$data[] = [
'uid' => $user->id,
'password' => $user->passwd,
@@ -39,6 +34,6 @@ class TrojanController extends BaseController
];
}
- return $this->returnData('获取用户列表成功', 'success', 200, $data, ['updateTime' => time()]);
+ return $this->returnData('获取用户列表成功', 'success', 200, $data ?? [], ['updateTime' => time()]);
}
}
diff --git a/app/Http/Controllers/Api/WebApi/V2RayController.php b/app/Http/Controllers/Api/WebApi/V2RayController.php
index 43ae8e5a..e8c6a68c 100644
--- a/app/Http/Controllers/Api/WebApi/V2RayController.php
+++ b/app/Http/Controllers/Api/WebApi/V2RayController.php
@@ -5,15 +5,13 @@ namespace App\Http\Controllers\Api\WebApi;
use App\Models\Node;
use App\Models\NodeCertificate;
use Illuminate\Http\JsonResponse;
-use Illuminate\Http\Request;
class V2RayController extends BaseController
{
// 获取节点信息
- public function getNodeInfo($id): JsonResponse
+ public function getNodeInfo(Node $node): JsonResponse
{
- $node = Node::find($id);
- $nodeDv = NodeCertificate::whereDomain($node->v2_host)->first();
+ $cert = NodeCertificate::whereDomain($node->v2_host)->first();
$tlsProvider = $node->tls_provider ?: sysConfig('v2ray_tls_provider');
if (! $tlsProvider) {
$tlsProvider = null;
@@ -27,8 +25,8 @@ class V2RayController extends BaseController
'push_port' => $node->push_port,
'redirect_url' => (string) sysConfig('redirect_url'),
'secret' => $node->auth->secret,
- 'key' => $nodeDv->key ?? '',
- 'pem' => $nodeDv->pem ?? '',
+ 'key' => $cert->key ?? '',
+ 'pem' => $cert->pem ?? '',
'v2_license' => (string) sysConfig('v2ray_license'),
'v2_alter_id' => $node->v2_alter_id,
'v2_port' => $node->v2_port,
@@ -43,12 +41,9 @@ class V2RayController extends BaseController
}
// 获取节点可用的用户列表
- public function getUserList($id): JsonResponse
+ public function getUserList(Node $node): JsonResponse
{
- $users = Node::find($id)->node_access_users;
- $data = [];
-
- foreach ($users as $user) {
+ foreach ($node->users() as $user) {
$data[] = [
'uid' => $user->id,
'vmess_uid' => $user->vmess_id,
@@ -56,29 +51,15 @@ class V2RayController extends BaseController
];
}
- return $this->returnData('获取用户列表成功', 'success', 200, $data, ['updateTime' => time()]);
+ return $this->returnData('获取用户列表成功', 'success', 200, $data ?? [], ['updateTime' => time()]);
}
// 上报节点伪装域名证书信息
- public function addCertificate(Request $request, $id): JsonResponse
+ public function addCertificate(Node $node): JsonResponse
{
- $key = $request->input('key');
- $pem = $request->input('pem');
-
- if ($request->has(['key', 'pem'])) {
- $node = Node::find($id);
- $Dv = NodeCertificate::whereDomain($node->v2_host)->first();
- if ($Dv) {
- $ret = NodeCertificate::whereId($Dv->id)->update(['key' => $key, 'pem' => $pem]);
- } else {
- $ret = new NodeCertificate();
- $ret->domain = $node->server;
- $ret->key = $request->input('key');
- $ret->pem = $request->input('pem');
- $ret->save();
- }
-
- if ($ret) {
+ if (request()->has(['key', 'pem'])) {
+ $cert = NodeCertificate::whereDomain($node->v2_host)->firstOrCreate(['domain' => $node->server]);
+ if ($cert && $cert->update(['key' => request('key'), 'pem' => request('pem')])) {
return $this->returnData('上报节点伪装域名证书成功', 'success', 200);
}
}
diff --git a/app/Http/Controllers/Api/WebApi/VNetController.php b/app/Http/Controllers/Api/WebApi/VNetController.php
index 809bd273..0d877760 100644
--- a/app/Http/Controllers/Api/WebApi/VNetController.php
+++ b/app/Http/Controllers/Api/WebApi/VNetController.php
@@ -8,10 +8,8 @@ use Illuminate\Http\JsonResponse;
class VNetController extends BaseController
{
// 获取节点信息
- public function getNodeInfo($id): JsonResponse
+ public function getNodeInfo(Node $node): JsonResponse
{
- $node = Node::find($id);
-
return $this->returnData('获取节点信息成功', 'success', 200, [
'id' => $node->id,
'method' => $node->method,
@@ -31,13 +29,9 @@ class VNetController extends BaseController
}
// 获取节点可用的用户列表
- public function getUserList($id): JsonResponse
+ public function getUserList(Node $node): JsonResponse
{
- $node = Node::find($id);
- $users = $node->node_access_users;
- $data = [];
-
- foreach ($users as $user) {
+ foreach ($node->users() as $user) {
$data[] = [
'uid' => $user->id,
'port' => $user->port,
@@ -51,7 +45,7 @@ class VNetController extends BaseController
];
}
- if ($data) {
+ if (isset($data)) {
return $this->returnData('获取用户列表成功', 'success', 200, $data, ['updateTime' => time()]);
}
diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php
index 23c51559..824cfa2d 100644
--- a/app/Http/Controllers/AuthController.php
+++ b/app/Http/Controllers/AuthController.php
@@ -51,10 +51,6 @@ class AuthController extends Controller
return Redirect::back()->withInput()->withErrors($validator->errors());
}
- $email = $request->input('email');
- $password = $request->input('password');
- $remember = $request->input('remember');
-
// 是否校验验证码
$captcha = $this->check_captcha($request);
if ($captcha !== false) {
@@ -62,7 +58,7 @@ class AuthController extends Controller
}
// 验证账号并创建会话
- if (! Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
+ if (! Auth::attempt($validator->validated(), $request->input('remember'))) {
return Redirect::back()->withInput()->withErrors(trans('auth.login_error'));
}
$user = Auth::getUser();
@@ -81,23 +77,17 @@ class AuthController extends Controller
if ($user->status === 0 && sysConfig('is_activate_account')) {
Auth::logout(); // 强制销毁会话,因为Auth::attempt的时候会产生会话
- return Redirect::back()->withInput()->withErrors(trans('auth.active_tip').'【'.trans('auth.active_account').'】');
+ return Redirect::back()->withInput()->withErrors(trans('auth.active_tip').'【'.trans('auth.active_account').'】');
}
// 写入登录日志
$this->addUserLoginLog($user->id, IP::getClientIp());
// 更新登录信息
- Auth::getUser()->update(['last_login' => time()]);
-
- // 根据权限跳转
- if ($user->hasPermissionTo('admin.index')) {
- return Redirect::route('admin.index');
- }
-
- return Redirect::route('home');
+ $user->update(['last_login' => time()]);
}
+ // 根据权限跳转
if (Auth::check()) {
if (Auth::getUser()->hasPermissionTo('admin.index')) {
return Redirect::route('admin.index');
@@ -110,7 +100,7 @@ class AuthController extends Controller
}
// 校验验证码
- private function check_captcha($request)
+ private function check_captcha(Request $request)
{
switch (sysConfig('is_captcha')) {
case 1: // 默认图形验证码
@@ -298,14 +288,14 @@ class AuthController extends Controller
$transfer_enable = MB * ((int) sysConfig('default_traffic') + ($inviter_id ? (int) sysConfig('referral_traffic') : 0));
// 创建新用户
- $uid = Helpers::addUser($email, $password, $transfer_enable, sysConfig('default_days'), $inviter_id);
+ $user = factory(User::class)->create([
+ 'username' => $username, 'email' => $email, 'password' => $password, 'transfer_enable' => $transfer_enable, 'inviter_id' => $inviter_id,
+ ]);
// 注册失败,抛出异常
- if (! $uid) {
+ if (! $user) {
return Redirect::back()->withInput()->withErrors(trans('auth.register_fail'));
}
- // 更新昵称
- User::find($uid)->update(['username' => $username]);
// 注册次数+1
if (Cache::has($cacheKey)) {
@@ -316,16 +306,16 @@ class AuthController extends Controller
// 更新邀请码
if ($affArr['code_id'] && sysConfig('is_invite_register')) {
- Invite::find($affArr['code_id'])->update(['invitee_id' => $uid, 'status' => 1]);
+ Invite::find($affArr['code_id'])->update(['invitee_id' => $user->id, 'status' => 1]);
}
// 清除邀请人Cookie
Cookie::unqueue('register_aff');
// 注册后发送激活码
- if (sysConfig('is_activate_account') == 2) {
+ if ((int) sysConfig('is_activate_account') === 2) {
// 生成激活账号的地址
- $token = $this->addVerifyUrl($uid, $email);
+ $token = $this->addVerifyUrl($user->id, $email);
$activeUserUrl = route('activeAccount', $token);
$logId = Helpers::addNotificationLog('注册激活', '请求地址:'.$activeUserUrl, 1, $email);
@@ -341,8 +331,8 @@ class AuthController extends Controller
}
}
- if (sysConfig('is_activate_account') == 1) {
- User::find($uid)->update(['status' => 1]);
+ if ((int) sysConfig('is_activate_account') === 1) {
+ $user->update(['status' => 1]);
}
Session::flash('successMsg', trans('auth.register_success'));
@@ -351,10 +341,9 @@ class AuthController extends Controller
return Redirect::route('login')->withInput();
}
- $view['emailList'] = sysConfig('is_email_filtering') != 2 ? false : EmailFilter::whereType(2)->get();
Session::put('register_token', Str::random());
- return view('auth.register', $view);
+ return view('auth.register', ['emailList' => (int) sysConfig('is_email_filtering') !== 2 ? false : EmailFilter::whereType(2)->get()]);
}
//邮箱检查
@@ -562,10 +551,7 @@ class AuthController extends Controller
$verify->save();
}
- // 重新获取一遍verify
- $view['verify'] = Verify::type(1)->whereToken($token)->first();
-
- return view('auth.reset', $view);
+ return view('auth.reset', ['verify' => Verify::type(1)->whereToken($token)->first()]); // 重新获取一遍verify
}
// 激活账号页
@@ -744,13 +730,11 @@ class AuthController extends Controller
// 公开的邀请码列表
public function free()
{
- $view['inviteList'] = Invite::whereInviterId(null)->whereStatus(0)->paginate();
-
- return view('auth.free', $view);
+ return view('auth.free', ['inviteList' => Invite::whereInviterId(null)->whereStatus(0)->paginate()]);
}
// 切换语言
- public function switchLang($locale): RedirectResponse
+ public function switchLang(string $locale): RedirectResponse
{
Session::put('locale', $locale);
diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php
index a8fa4a15..54f90f9c 100644
--- a/app/Http/Controllers/PaymentController.php
+++ b/app/Http/Controllers/PaymentController.php
@@ -95,7 +95,6 @@ class PaymentController extends Controller
$pay_type = $request->input('pay_type');
$amount = 0;
- $goods = Goods::find($goods_id);
// 充值余额
if ($credit) {
if (! is_numeric($credit) || $credit <= 0) {
@@ -104,6 +103,7 @@ class PaymentController extends Controller
$amount = $credit;
// 购买服务
} elseif ($goods_id && self::$method) {
+ $goods = Goods::find($goods_id);
if (! $goods || ! $goods->status) {
return Response::json(['status' => 'fail', 'message' => '订单创建失败:商品已下架']);
}
@@ -140,7 +140,7 @@ class PaymentController extends Controller
}
}
- // 使用优惠券 TODO 代码整合至 CouponService
+ // 使用优惠券
if ($coupon_sn) {
$coupon = Coupon::whereStatus(0)->whereIn('type', [1, 2])->whereSn($coupon_sn)->first();
if (! $coupon) {
@@ -162,31 +162,29 @@ class PaymentController extends Controller
}
}
- $orderSn = date('ymdHis').random_int(100000, 999999);
-
// 生成订单
try {
- $order = new Order();
- $order->order_sn = $orderSn;
- $order->user_id = Auth::id();
- $order->goods_id = $credit ? 0 : $goods_id;
- $order->coupon_id = $coupon->id ?? 0;
- $order->origin_amount = $credit ?: $goods->price;
- $order->amount = $amount;
- $order->pay_type = $pay_type;
- $order->pay_way = self::$method;
- $order->save();
+ $newOrder = Order::create([
+ 'order_sn' => date('ymdHis').random_int(100000, 999999),
+ 'user_id' => auth()->id(),
+ 'goods_id' => $credit ? null : $goods_id,
+ 'coupon_id' => $coupon->id ?? null,
+ 'origin_amount' => $credit ?: $goods->price ?? 0,
+ 'amount'=>$amount,
+ 'pay_type'=>$pay_type,
+ 'pay_way'=>self::$method,
+ ]);
// 使用优惠券,减少可使用次数
if (! empty($coupon)) {
if ($coupon->usable_times > 0) {
- Coupon::whereId($coupon->id)->decrement('usable_times', 1);
+ $coupon->decrement('usable_times', 1);
}
- Helpers::addCouponLog('订单支付使用', $coupon->id, $goods_id, $order->id);
+ Helpers::addCouponLog('订单支付使用', $coupon->id, $goods_id, $newOrder->id);
}
- $request->merge(['id' => $order->id, 'type' => $pay_type, 'amount' => $amount]);
+ $request->merge(['id' => $newOrder->id, 'type' => $pay_type, 'amount' => $amount]);
// 生成支付单
return self::getClient()->purchase($request);
@@ -197,15 +195,10 @@ class PaymentController extends Controller
return Response::json(['status' => 'fail', 'message' => '订单创建失败']);
}
- public function close(Request $request): JsonResponse
+ public function close(Order $order): JsonResponse
{
- $order = Order::find($request->input('id'));
- if ($order) {
- if (! $order->update(['status' => -1])) {
- return Response::json(['status' => 'fail', 'message' => '关闭订单失败']);
- }
- } else {
- return Response::json(['status' => 'fail', 'message' => '未找到订单']);
+ if (! $order->update(['status' => -1])) {
+ return Response::json(['status' => 'fail', 'message' => '关闭订单失败']);
}
return Response::json(['status' => 'success', 'message' => '关闭订单成功']);
@@ -215,13 +208,14 @@ class PaymentController extends Controller
public function detail($trade_no)
{
$payment = Payment::uid()->with(['order', 'order.goods'])->whereTradeNo($trade_no)->firstOrFail();
- $view['payment'] = $payment;
$goods = $payment->order->goods;
- $view['name'] = $goods->name ?? '余额充值';
- $view['days'] = $goods->days ?? 0;
- $view['pay_type'] = $payment->order->pay_type_label ?: 0;
- $view['pay_type_icon'] = $payment->order->pay_type_icon;
- return view('user.payment', $view);
+ return view('user.payment', [
+ 'payment' => $payment,
+ 'name' => $goods->name ?? '余额充值',
+ 'days' => $goods->days ?? 0,
+ 'pay_type' => $payment->order->pay_type_label ?: 0,
+ 'pay_type_icon' => $payment->order->pay_type_icon,
+ ]);
}
}
diff --git a/app/Http/Controllers/User/AffiliateController.php b/app/Http/Controllers/User/AffiliateController.php
index 5809c58a..7a61bc85 100644
--- a/app/Http/Controllers/User/AffiliateController.php
+++ b/app/Http/Controllers/User/AffiliateController.php
@@ -18,17 +18,18 @@ class AffiliateController extends Controller
if (ReferralLog::uid()->doesntExist() && Order::uid()->whereStatus(2)->doesntExist()) {
return Response::view('auth.error', ['message' => '本功能对非付费用户禁用!请 返 回'], 402);
}
- $view['referral_traffic'] = flowAutoShow(sysConfig('referral_traffic') * MB);
- $view['referral_percent'] = sysConfig('referral_percent');
- $view['referral_money'] = sysConfig('referral_money');
- $view['totalAmount'] = ReferralLog::uid()->sum('commission') / 100;
- $view['canAmount'] = ReferralLog::uid()->whereStatus(0)->sum('commission') / 100;
- $view['aff_link'] = route('register', ['aff' => Auth::id()]);
- $view['referralLogList'] = ReferralLog::uid()->with('invitee:id,email')->latest()->paginate(10, ['*'], 'log_page');
- $view['referralApplyList'] = ReferralApply::uid()->latest()->paginate(10, ['*'], 'apply_page');
- $view['referralUserList'] = Auth::getUser()->invitees()->select(['email', 'created_at'])->latest()->paginate(10, ['*'], 'user_page');
- return view('user.referral', $view);
+ return view('user.referral', [
+ 'referral_traffic' => flowAutoShow(sysConfig('referral_traffic') * MB),
+ 'referral_percent' => sysConfig('referral_percent'),
+ 'referral_money' => sysConfig('referral_money'),
+ 'totalAmount' => ReferralLog::uid()->sum('commission') / 100,
+ 'canAmount' => ReferralLog::uid()->whereStatus(0)->sum('commission') / 100,
+ 'aff_link' => route('register', ['aff' => Auth::id()]),
+ 'referralLogList' => ReferralLog::uid()->with('invitee:id,email')->latest()->paginate(10, ['*'], 'log_page'),
+ 'referralApplyList' => ReferralApply::uid()->latest()->paginate(10, ['*'], 'apply_page'),
+ 'referralUserList' => Auth::getUser()->invitees()->select(['email', 'created_at'])->latest()->paginate(10, ['*'], 'user_page'),
+ ]);
}
// 申请提现
diff --git a/app/Http/Controllers/User/SubscribeController.php b/app/Http/Controllers/User/SubscribeController.php
index 2b859db4..7b5c1b54 100644
--- a/app/Http/Controllers/User/SubscribeController.php
+++ b/app/Http/Controllers/User/SubscribeController.php
@@ -77,7 +77,7 @@ class SubscribeController extends Controller
$this->subscribeLog($subscribe->id, IP::getClientIp(), $request->headers);
// 获取这个账号可用节点
- $query = $user->whereIsSubscribe(1)->userAccessNodes();
+ $query = $user->whereIsSubscribe(1)->nodes();
if ($this->subType === 1) {
$query = $query->whereIn('type', [1, 4]);
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index 52094dfb..426982e0 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -16,9 +16,6 @@ use App\Models\NodePing;
use App\Models\Order;
use App\Models\Ticket;
use App\Models\TicketReply;
-use App\Models\UserLoginLog;
-use App\Models\UserSubscribe;
-use Auth;
use Cache;
use DB;
use Exception;
@@ -34,38 +31,22 @@ use Session;
use Str;
use Validator;
-/**
- * 用户控制器.
- *
- * Class UserController
- */
class UserController extends Controller
{
public function index()
{
+ // 用户转换
if (Session::has('user')) {
- Auth::loginUsingId(Session::get('user'));
+ auth()->loginUsingId(Session::get('user'));
Session::forget('user');
}
- $user = Auth::getUser();
+ $user = auth()->user();
$totalTransfer = $user->transfer_enable;
$usedTransfer = $user->usedTraffic();
$unusedTraffic = $totalTransfer - $usedTransfer > 0 ? $totalTransfer - $usedTransfer : 0;
$expireTime = $user->expired_at;
- $view['remainDays'] = $expireTime < date('Y-m-d') ? -1 : Helpers::daysToNow($expireTime);
- $view['resetDays'] = $user->reset_time ? Helpers::daysToNow($user->reset_time) : 0;
- $view['unusedTraffic'] = flowAutoShow($unusedTraffic);
- $view['expireTime'] = $expireTime;
- $view['banedTime'] = $user->ban_time ?: 0;
- $view['unusedPercent'] = $totalTransfer > 0 ? round($unusedTraffic / $totalTransfer, 2) * 100 : 0;
- $view['announcements'] = Article::type(2)->take(5)->latest()->Paginate(1); // 公告
- //流量异常判断
- $view['isTrafficWarning'] = $user->isTrafficWarning();
- //付费用户判断
- $view['paying_user'] = $user->activePayingUser();
- $view['userLoginLog'] = UserLoginLog::whereUserId($user->id)->latest()->first(); // 近期登录日志
- $nodes = $user->userAccessNodes()->get();
+ $nodes = $user->nodes()->get();
$subType = [];
if ($nodes->whereIn('type', [1, 4])->isNotEmpty()) {
$subType[] = 'ss';
@@ -77,18 +58,27 @@ class UserController extends Controller
$subType[] = 'trojan';
}
- $view['subscribe_status'] = $user->subscribe->status;
- $view['subType'] = $subType;
- $view['subUrl'] = route('sub', $user->subscribe->code);
- $view = array_merge($view, $this->dataFlowChart($user->id));
-
- return view('user.index', $view);
+ return view('user.index', array_merge([
+ 'remainDays' => $expireTime < date('Y-m-d') ? -1 : Helpers::daysToNow($expireTime),
+ 'resetDays' => $user->reset_time ? Helpers::daysToNow($user->reset_time) : 0,
+ 'unusedTraffic' => flowAutoShow($unusedTraffic),
+ 'expireTime' => $expireTime,
+ 'banedTime' => $user->ban_time ?: 0,
+ 'unusedPercent' => $totalTransfer > 0 ? round($unusedTraffic / $totalTransfer, 2) * 100 : 0,
+ 'announcements' => Article::type(2)->take(5)->latest()->Paginate(1), // 公告
+ 'isTrafficWarning' => $user->isTrafficWarning(), // 流量异常判断
+ 'paying_user' => $user->activePayingUser(), // 付费用户判断
+ 'userLoginLog' => $user->loginLogs()->latest()->first(), // 近期登录日志
+ 'subscribe_status' => $user->subscribe->status,
+ 'subType' => $subType,
+ 'subUrl' => route('sub', $user->subscribe->code),
+ ], $this->dataFlowChart($user->id)));
}
// 签到
public function checkIn(): JsonResponse
{
- $user = Auth::getUser();
+ $user = auth()->user();
// 系统开启登录加积分功能才可以签到
if (! sysConfig('is_checkin')) {
return Response::json(['status' => 'fail', 'message' => '系统未开启签到功能']);
@@ -118,7 +108,7 @@ class UserController extends Controller
// 节点列表
public function nodeList(Request $request)
{
- $user = Auth::getUser();
+ $user = auth()->user();
if ($request->isMethod('POST')) {
$infoType = $request->input('type');
@@ -135,9 +125,7 @@ class UserController extends Controller
}
// 获取当前用户可用节点
- $nodeList = $user->userAccessNodes()->with(['labels', 'level_table'])->get();
-
- $view['nodesGeo'] = $nodeList->pluck('name', 'geo')->toArray();
+ $nodeList = $user->nodes()->with(['labels', 'level_table'])->get();
$onlineNode = NodeHeartBeat::recently()->distinct()->pluck('node_id')->toArray();
$pingNodeLogs = NodePing::whereMonth('created_at', date('m'))->get(['node_id', 'ct', 'cu', 'cm', 'hk']);
foreach ($nodeList as $node) {
@@ -150,23 +138,23 @@ class UserController extends Controller
// 节点在线状态
$node->offline = ! in_array($node->id, $onlineNode, true);
}
- $view['nodeList'] = $nodeList ?? [];
- return view('user.nodeList', $view);
+ return view('user.nodeList', [
+ 'nodesGeo' => $nodeList->pluck('name', 'geo')->toArray(),
+ 'nodeList' => $nodeList,
+ ]);
}
// 公告详情
- public function article(Request $request)
+ public function article(Article $article)
{
- $view['info'] = Article::findOrFail($request->input('id'));
-
- return view('user.article', $view);
+ return view('user.article', compact($article));
}
// 修改个人资料
public function profile(Request $request)
{
- $user = Auth::getUser();
+ $user = auth()->user();
if ($request->isMethod('POST')) {
$old_password = $request->input('old_password');
$new_password = $request->input('new_password');
@@ -224,30 +212,26 @@ class UserController extends Controller
// 商品列表
public function services(Request $request)
{
- $user = Auth::getUser();
+ $user = auth()->user();
// 余额充值商品,只取10个
- $view['chargeGoodsList'] = Goods::type(3)->whereStatus(1)->orderBy('price')->limit(10)->get();
- $view['goodsList'] = Goods::whereStatus(1)
- ->where('type', '<=', '2')
- ->orderByDesc('type')
- ->orderByDesc('sort')
- ->paginate(10)
- ->appends($request->except('page'));
$renewOrder = Order::userActivePlan($user->id)->first();
$renewPrice = $renewOrder->goods ?? 0;
- $view['renewTraffic'] = $renewPrice->renew ?? 0;
// 有重置日时按照重置日为标准,否者就以过期日为标准
$dataPlusDays = $user->reset_time ?? $user->expired_at;
- $view['dataPlusDays'] = $dataPlusDays > date('Y-m-d') ? Helpers::daysToNow($dataPlusDays) : 0;
- return view('user.services', $view);
+ return view('user.services', [
+ 'chargeGoodsList' => Goods::type(3)->whereStatus(1)->orderBy('price')->limit(10)->get(),
+ 'goodsList' => Goods::whereStatus(1)->where('type', '<=', '2')->orderByDesc('type')->orderByDesc('sort')->paginate(10)->appends($request->except('page')),
+ 'renewTraffic' => $renewPrice->renew ?? 0,
+ 'dataPlusDays' => $dataPlusDays > date('Y-m-d') ? Helpers::daysToNow($dataPlusDays) : 0,
+ ]);
}
//重置流量
public function resetUserTraffic(): ?JsonResponse
{
- $user = Auth::getUser();
- $order = Order::userActivePlan()->first();
+ $user = auth()->user();
+ $order = Order::userActivePlan()->firstOrFail();
$renewCost = $order->goods->renew;
if ($user->credit < $renewCost) {
return Response::json(['status' => 'fail', 'message' => '余额不足,请充值余额']);
@@ -268,26 +252,22 @@ class UserController extends Controller
public function ticketList(Request $request)
{
return view('user.ticketList', [
- 'tickets' => Auth::user()->tickets()->latest()->paginate(10)->appends($request->except('page')),
+ 'tickets' => auth()->user()->tickets()->latest()->paginate(10)->appends($request->except('page')),
]);
}
// 订单
public function invoices(Request $request)
{
- $view['orderList'] = Auth::user()->orders()
- ->with(['goods', 'payment'])
- ->orderByDesc('id')
- ->paginate(10)
- ->appends($request->except('page'));
- $view['prepaidPlan'] = Order::userPrepay()->exists();
-
- return view('user.invoices', $view);
+ return view('user.invoices', [
+ 'orderList' => auth()->user()->orders()->with(['goods', 'payment'])->orderByDesc('id')->paginate(10)->appends($request->except('page')),
+ 'prepaidPlan' => Order::userPrepay()->exists(),
+ ]);
}
public function closePlan(): JsonResponse
{
- $activePlan = Order::userActivePlan()->first();
+ $activePlan = Order::userActivePlan()->firstOrFail();
$activePlan->is_expire = 1;
if ($activePlan->save()) {
@@ -305,15 +285,13 @@ class UserController extends Controller
// 订单明细
public function invoiceDetail($sn)
{
- $view['order'] = Order::uid()->whereOrderSn($sn)->with(['goods', 'coupon', 'payment'])->firstOrFail();
-
- return view('user.invoiceDetail', $view);
+ return view('user.invoiceDetail', ['order' => Order::uid()->whereOrderSn($sn)->with(['goods', 'coupon', 'payment'])->firstOrFail()]);
}
// 添加工单
public function createTicket(Request $request): ?JsonResponse
{
- $user = Auth::getUser();
+ $user = auth()->user();
$title = $request->input('title');
$content = clean($request->input('content'));
$content = str_replace(['atob', 'eval'], '', $content);
@@ -367,7 +345,7 @@ class UserController extends Controller
$obj = new TicketReply();
$obj->ticket_id = $id;
- $obj->user_id = Auth::id();
+ $obj->user_id = auth()->user()->id;
$obj->content = $content;
if ($obj->save()) {
@@ -392,10 +370,10 @@ class UserController extends Controller
return Response::json(['status' => 'fail', 'message' => '回复失败']);
}
- $view['ticket'] = $ticket;
- $view['replyList'] = TicketReply::whereTicketId($id)->with('user')->oldest()->get();
-
- return view('user.replyTicket', $view);
+ return view('user.replyTicket', [
+ 'ticket' => $ticket,
+ 'replyList' => $ticket->reply()->with('user')->oldest()->get(),
+ ]);
}
// 关闭工单
@@ -423,18 +401,18 @@ class UserController extends Controller
);
}
- $view['num'] = Auth::getUser()->invite_num; // 还可以生成的邀请码数量
- $view['inviteList'] = Invite::uid()->with(['invitee', 'inviter'])->paginate(10); // 邀请码列表
- $view['referral_traffic'] = flowAutoShow(sysConfig('referral_traffic') * MB);
- $view['referral_percent'] = sysConfig('referral_percent');
-
- return view('user.invite', $view);
+ return view('user.invite', [
+ 'num' => auth()->user()->invite_num, // 还可以生成的邀请码数量
+ 'inviteList' => Invite::uid()->with(['invitee', 'inviter'])->paginate(10), // 邀请码列表
+ 'referral_traffic' => flowAutoShow(sysConfig('referral_traffic') * MB),
+ 'referral_percent' => sysConfig('referral_percent'),
+ ]);
}
// 生成邀请码
public function makeInvite(): JsonResponse
{
- $user = Auth::getUser();
+ $user = auth()->user();
if ($user->invite_num <= 0) {
return Response::json(['status' => 'fail', 'message' => '生成失败:已无邀请码生成名额']);
}
@@ -483,7 +461,7 @@ class UserController extends Controller
return Response::json(['status' => 'fail', 'title' => '抱歉', 'message' => '优惠券已失效!']);
}
- if ($coupon->start_time > time()) {
+ if ($coupon->start_time > date('Y-m-d H:i:s')) {
return Response::json(['status' => 'fail', 'title' => '优惠券尚未生效', 'message' => '请等待活动正式开启']);
}
@@ -501,20 +479,17 @@ class UserController extends Controller
}
// 购买服务
- public function buy($goods_id)
+ public function buy(Goods $good)
{
- $user = Auth::getUser();
- $goods = Goods::whereId($goods_id)->whereStatus(1)->first();
- if (empty($goods)) {
- return Redirect::route('shop');
- }
+ $user = auth()->user();
// 有重置日时按照重置日为标准,否者就以过期日为标准
$dataPlusDays = $user->reset_time ?? $user->expired_at;
- $view['dataPlusDays'] = $dataPlusDays > date('Y-m-d') ? Helpers::daysToNow($dataPlusDays) : 0;
- $view['activePlan'] = Order::userActivePlan()->exists();
- $view['goods'] = $goods;
- return view('user.buy', $view);
+ return view('user.buy', [
+ 'dataPlusDays' => $dataPlusDays > date('Y-m-d') ? Helpers::daysToNow($dataPlusDays) : 0,
+ 'activePlan' => Order::userActivePlan()->exists(),
+ 'goods' => $good,
+ ]);
}
// 帮助中心
@@ -533,25 +508,22 @@ class UserController extends Controller
$data[] = 'trojan';
}
- $view['sub'] = $data;
-
- //付费用户判断
- $view['paying_user'] = Auth::user()->activePayingUser();
- //客户端安装
- $view['Shadowrocket_install'] = 'itms-services://?action=download-manifest&url='.sysConfig('website_url').'/clients/Shadowrocket.plist';
- $view['Quantumult_install'] = 'itms-services://?action=download-manifest&url='.sysConfig('website_url').'/clients/Quantumult.plist';
- // 订阅连接
- $subscribe = UserSubscribe::whereUserId(Auth::id())->firstOrFail();
- $view['subscribe_status'] = $subscribe->status;
+ $subscribe = auth()->user()->subscribe;
$subscribe_link = route('sub', $subscribe->code);
- $view['link'] = $subscribe_link;
- $view['subscribe_link'] = 'sub://'.base64url_encode($subscribe_link);
- $view['Shadowrocket_link'] = 'shadowrocket://add/sub://'.base64url_encode($subscribe_link).'?remarks='.(sysConfig('website_name').'-'.sysConfig('website_url'));
- $view['Shadowrocket_linkQrcode'] = 'sub://'.base64url_encode($subscribe_link).'#'.base64url_encode(sysConfig('website_name'));
- $view['Quantumult_linkOut'] = 'quantumult://configuration?server='.base64url_encode($subscribe_link).'&filter='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/Pro.conf').'&rejection='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/Rejection.conf');
- $view['Quantumult_linkIn'] = 'quantumult://configuration?server='.base64url_encode($subscribe_link).'&filter='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/BacktoCN.conf').'&rejection='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/Rejection.conf');
- return view('user.help', $view);
+ return view('user.help', [
+ 'sub' => $data,
+ 'paying_user' => auth()->user()->activePayingUser(), // 付费用户判断
+ 'Shadowrocket_install' => 'itms-services://?action=download-manifest&url='.sysConfig('website_url').'/clients/Shadowrocket.plist', // 客户端安装
+ 'Quantumult_install' => 'itms-services://?action=download-manifest&url='.sysConfig('website_url').'/clients/Quantumult.plist', // 客户端安装
+ 'subscribe_status' => $subscribe->status, // 订阅连接
+ 'link' => $subscribe_link,
+ 'subscribe_link' => 'sub://'.base64url_encode($subscribe_link),
+ 'Shadowrocket_link' => 'shadowrocket://add/sub://'.base64url_encode($subscribe_link).'?remarks='.(sysConfig('website_name').'-'.sysConfig('website_url')),
+ 'Shadowrocket_linkQrcode' => 'sub://'.base64url_encode($subscribe_link).'#'.base64url_encode(sysConfig('website_name')),
+ 'Quantumult_linkOut' => 'quantumult://configuration?server='.base64url_encode($subscribe_link).'&filter='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/Pro.conf').'&rejection='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/Rejection.conf'),
+ 'Quantumult_linkIn' => 'quantumult://configuration?server='.base64url_encode($subscribe_link).'&filter='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/BacktoCN.conf').'&rejection='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/Rejection.conf'),
+ ]);
}
// 更换订阅地址
@@ -561,10 +533,10 @@ class UserController extends Controller
DB::beginTransaction();
// 更换订阅码
- Auth::getUser()->subscribe->update(['code' => Helpers::makeSubscribeCode()]);
+ auth()->user()->subscribe->update(['code' => Helpers::makeSubscribeCode()]);
// 更换连接信息
- Auth::getUser()->update(['passwd' => Str::random(), 'vmess_id' => Str::uuid()]);
+ auth()->user()->update(['passwd' => Str::random(), 'vmess_id' => Str::uuid()]);
DB::commit();
@@ -586,7 +558,7 @@ class UserController extends Controller
}
// 管理员信息重新写入user
- $user = Auth::loginUsingId(Session::get('admin'));
+ $user = auth()->loginUsingId(Session::get('admin'));
Session::forget('admin');
if ($user) {
return Response::json(['status' => 'success', 'message' => '身份切换成功']);
@@ -615,14 +587,14 @@ class UserController extends Controller
try {
DB::beginTransaction();
// 写入日志
- $user = Auth::getUser();
+ $user = auth()->user();
Helpers::addUserCreditLog($user->id, null, $user->credit, $user->credit + $coupon->value, $coupon->value, '用户手动充值 - [充值券:'.$request->input('coupon_sn').']');
// 余额充值
$user->updateCredit($coupon->value);
// 更改卡券状态
- Coupon::find($coupon->id)->update(['status' => 1]);
+ $coupon->update(['status' => 1]);
// 写入卡券日志
Helpers::addCouponLog('账户余额充值使用', $coupon->id);
diff --git a/app/Http/Requests/Admin/ArticleRequest.php b/app/Http/Requests/Admin/ArticleRequest.php
index 8fcd53f8..2acb1553 100644
--- a/app/Http/Requests/Admin/ArticleRequest.php
+++ b/app/Http/Requests/Admin/ArticleRequest.php
@@ -9,12 +9,12 @@ class ArticleRequest extends FormRequest
public function rules(): array
{
return [
- 'title' => 'required',
- 'type' => 'required|numeric',
- 'summary' => 'nullable',
- 'logo' => 'nullable|exclude_if:type,4|image',
- 'content' => 'required',
+ 'type' => 'required|numeric|between:1,4',
+ 'title' => 'required|string',
+ 'summary' => 'string|nullable',
'sort' => 'required_if:type,1|numeric',
+ 'logo' => 'nullable|exclude_if:type,4|image',
+ 'content' => 'required|string',
];
}
}
diff --git a/app/Http/Requests/Admin/CertRequest.php b/app/Http/Requests/Admin/CertRequest.php
new file mode 100644
index 00000000..69abdf9d
--- /dev/null
+++ b/app/Http/Requests/Admin/CertRequest.php
@@ -0,0 +1,17 @@
+ 'required|string',
+ 'key' => 'string|nullable',
+ 'pem' => 'string|nullable',
+ ];
+ }
+}
diff --git a/app/Http/Requests/Admin/CouponRequest.php b/app/Http/Requests/Admin/CouponRequest.php
index 11ab8c0e..1c6decad 100644
--- a/app/Http/Requests/Admin/CouponRequest.php
+++ b/app/Http/Requests/Admin/CouponRequest.php
@@ -9,13 +9,14 @@ class CouponRequest extends FormRequest
public function rules(): array
{
return [
- 'name' => 'required',
+ 'name' => 'required|string',
'sn' => 'unique:coupon',
'logo' => 'nullable|image',
- 'type' => 'required|integer|between:1,3',
- 'usable_times' => 'integer|nullable',
- 'num' => 'required|integer|min:1',
+ 'type' => 'required|numeric|between:1,3',
+ 'usable_times' => 'numeric|nullable',
'value' => 'required|numeric|min:0',
+ 'rule' => 'required_unless:type,3',
+ 'num' => 'required|numeric|min:1',
'start_time' => 'required|date|before_or_equal:end_time',
'end_time' => 'required|date|after_or_equal:start_time',
];
diff --git a/app/Http/Requests/Admin/PermissionRequest.php b/app/Http/Requests/Admin/PermissionRequest.php
new file mode 100644
index 00000000..a9bef815
--- /dev/null
+++ b/app/Http/Requests/Admin/PermissionRequest.php
@@ -0,0 +1,16 @@
+ 'required|string',
+ 'description' => 'required|string',
+ ];
+ }
+}
diff --git a/app/Http/Requests/Admin/RbacRequest.php b/app/Http/Requests/Admin/RbacRequest.php
new file mode 100644
index 00000000..b10d6d56
--- /dev/null
+++ b/app/Http/Requests/Admin/RbacRequest.php
@@ -0,0 +1,16 @@
+ 'required|string',
+ 'description' => 'required|string',
+ ];
+ }
+}
diff --git a/app/Http/Requests/Admin/RoleRequest.php b/app/Http/Requests/Admin/RoleRequest.php
new file mode 100644
index 00000000..129abe6e
--- /dev/null
+++ b/app/Http/Requests/Admin/RoleRequest.php
@@ -0,0 +1,17 @@
+ 'required|string',
+ 'description' => 'required|string',
+ 'permissions' => 'exists:permissions,name',
+ ];
+ }
+}
diff --git a/app/Http/Requests/Admin/RuleGroupRequest.php b/app/Http/Requests/Admin/RuleGroupRequest.php
new file mode 100644
index 00000000..cca8acbf
--- /dev/null
+++ b/app/Http/Requests/Admin/RuleGroupRequest.php
@@ -0,0 +1,17 @@
+ 'required|string',
+ 'type' => 'required|boolean',
+ 'rules' => 'exists:rule,id',
+ ];
+ }
+}
diff --git a/app/Http/Requests/Admin/RuleRequest.php b/app/Http/Requests/Admin/RuleRequest.php
new file mode 100644
index 00000000..a56914e3
--- /dev/null
+++ b/app/Http/Requests/Admin/RuleRequest.php
@@ -0,0 +1,17 @@
+ 'required|numeric|between:1,4',
+ 'name' => 'required|string',
+ 'pattern' => 'required|string',
+ ];
+ }
+}
diff --git a/app/Http/Requests/Admin/UserGroupRequest.php b/app/Http/Requests/Admin/UserGroupRequest.php
new file mode 100644
index 00000000..459b0d8b
--- /dev/null
+++ b/app/Http/Requests/Admin/UserGroupRequest.php
@@ -0,0 +1,16 @@
+ 'required|string',
+ 'nodes' => 'exists:node,id',
+ ];
+ }
+}
diff --git a/app/Models/Coupon.php b/app/Models/Coupon.php
index 1c89463a..6737d29e 100644
--- a/app/Models/Coupon.php
+++ b/app/Models/Coupon.php
@@ -13,12 +13,23 @@ class Coupon extends Model
use SoftDeletes;
protected $table = 'coupon';
+ protected $casts = ['start_time' => 'date:Y-m-d', 'end_time' => 'date:Y-m-d'];
protected $dates = ['deleted_at'];
- protected $fillable = ['usable_times', 'status'];
+ protected $guarded = [];
// 筛选类型
public function scopeType($query, $type)
{
return $query->whereType($type);
}
+
+ public function setStartTimeAttribute($value)
+ {
+ return $this->attributes['start_time'] = strtotime($value);
+ }
+
+ public function setEndTimeAttribute($value)
+ {
+ return $this->attributes['end_time'] = strtotime($value);
+ }
}
diff --git a/app/Models/Label.php b/app/Models/Label.php
index d9a3a74e..4ee06539 100644
--- a/app/Models/Label.php
+++ b/app/Models/Label.php
@@ -14,8 +14,8 @@ class Label extends Model
protected $table = 'label';
protected $guarded = ['id'];
- public function nodes(): HasMany
+ public function nodes()
{
- return $this->hasMany(NodeLabel::class);
+ return $this->belongsToMany(Node::class);
}
}
diff --git a/app/Models/Node.php b/app/Models/Node.php
index 73342873..25995aa1 100644
--- a/app/Models/Node.php
+++ b/app/Models/Node.php
@@ -3,6 +3,8 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
@@ -11,12 +13,12 @@ use Illuminate\Database\Eloquent\Relations\HasOne;
*/
class Node extends Model
{
- protected $table = 'ss_node';
- protected $guarded = ['id', 'created_at'];
+ protected $table = 'node';
+ protected $guarded = [];
- public function labels(): HasMany
+ public function labels()
{
- return $this->hasMany(NodeLabel::class);
+ return $this->belongsToMany(Label::class);
}
public function heartBeats(): HasMany
@@ -44,14 +46,14 @@ class Node extends Model
return $this->hasMany(NodeHourlyDataFlow::class);
}
- public function rules(): hasMany
+ public function ruleGroup(): BelongsTo
{
- return $this->hasMany(NodeRule::class);
+ return $this->belongsTo(RuleGroup::class);
}
- public function ruleGroup(): hasOne
+ public function userGroups(): BelongsToMany
{
- return $this->hasOne(RuleGroupNode::class);
+ return $this->belongsToMany(UserGroup::class);
}
public function auth(): HasOne
@@ -64,14 +66,10 @@ class Node extends Model
return $this->hasOne(Level::class, 'level', 'level');
}
- public function scopeUserAllowNodes($query, $user_group_id, $user_level)
+ public function users()
{
- $userGroup = UserGroup::find($user_group_id);
- if ($userGroup) {
- $query->whereIn('id', $userGroup->nodes);
- }
-
- return $query->whereStatus(1)->where('level', '<=', $user_level ?: 0);
+ return User::activeUser()->whereIn('user_group_id', $this->userGroups->pluck('id')->toArray())->orwhereNull('user_group_id')->where('level', '>=',
+ $this->attributes['level'])->get();
}
public function config($user)
@@ -149,11 +147,6 @@ class Node extends Model
return $this->attributes['speed_limit'] = $value * Mbps;
}
- public function getNodeAccessUsersAttribute()
- {
- return User::nodeAllowUsers($this->attributes['id'], $this->attributes['level'])->get();
- }
-
public function getTypeLabelAttribute(): string
{
switch ($this->attributes['type']) {
diff --git a/app/Models/NodeHeartBeat.php b/app/Models/NodeHeartBeat.php
index bae00e16..b8b405b1 100644
--- a/app/Models/NodeHeartBeat.php
+++ b/app/Models/NodeHeartBeat.php
@@ -7,10 +7,10 @@ use Illuminate\Database\Eloquent\Model;
/**
* 节点负载信息.
*/
-class NodeHeartBeat extends Model
+class NodeHeartbeat extends Model
{
public $timestamps = false;
- protected $table = 'ss_node_info';
+ protected $table = 'node_heartbeat';
public function scopeRecently($query)
{
diff --git a/app/Models/NodeLabel.php b/app/Models/NodeLabel.php
deleted file mode 100644
index fc50be91..00000000
--- a/app/Models/NodeLabel.php
+++ /dev/null
@@ -1,25 +0,0 @@
-belongsTo(Node::class);
- }
-
- public function label(): BelongsTo
- {
- return $this->belongsTo(Label::class);
- }
-}
diff --git a/app/Models/NodeOnlineUserIp.php b/app/Models/NodeOnlineIp.php
similarity index 84%
rename from app/Models/NodeOnlineUserIp.php
rename to app/Models/NodeOnlineIp.php
index 697d7100..0e323032 100644
--- a/app/Models/NodeOnlineUserIp.php
+++ b/app/Models/NodeOnlineIp.php
@@ -8,10 +8,10 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* 节点在线用户IP信息.
*/
-class NodeOnlineUserIp extends Model
+class NodeOnlineIp extends Model
{
public $timestamps = false;
- protected $table = 'ss_node_ip';
+ protected $table = 'node_online_ip';
public function node(): BelongsTo
{
diff --git a/app/Models/NodeOnlineLog.php b/app/Models/NodeOnlineLog.php
index a547738d..7f895251 100644
--- a/app/Models/NodeOnlineLog.php
+++ b/app/Models/NodeOnlineLog.php
@@ -10,5 +10,5 @@ use Illuminate\Database\Eloquent\Model;
class NodeOnlineLog extends Model
{
public $timestamps = false;
- protected $table = 'ss_node_online_log';
+ protected $table = 'node_online_log';
}
diff --git a/app/Models/NodeRule.php b/app/Models/NodeRule.php
deleted file mode 100644
index d2ad0b5f..00000000
--- a/app/Models/NodeRule.php
+++ /dev/null
@@ -1,13 +0,0 @@
-active()->with('goods')->whereHas('goods', static function ($list) {
- $list->whereType(2);
+ return $query->active()->with('goods')->whereHas('goods', static function ($query) {
+ $query->whereType(2);
});
}
public function scopeActivePackage($query)
{
- return $query->active()->with('goods')->whereHas('goods', static function ($list) {
- $list->whereType(1);
+ return $query->active()->with('goods')->whereHas('goods', static function ($query) {
+ $query->whereType(1);
});
}
diff --git a/app/Models/ReferralApply.php b/app/Models/ReferralApply.php
index 1d4038c7..a8e73382 100644
--- a/app/Models/ReferralApply.php
+++ b/app/Models/ReferralApply.php
@@ -24,6 +24,11 @@ class ReferralApply extends Model
return $this->belongsTo(User::class);
}
+ public function referral_logs()
+ {
+ return ReferralLog::whereIn('id', $this->link_logs);
+ }
+
public function getBeforeAttribute($value)
{
return $value / 100;
diff --git a/app/Models/Rule.php b/app/Models/Rule.php
index 4a1dfa11..d45a0023 100644
--- a/app/Models/Rule.php
+++ b/app/Models/Rule.php
@@ -56,4 +56,9 @@ class Rule extends Model
return $type_api_label;
}
+
+ public function rule_groups()
+ {
+ return $this->belongsToMany(RuleGroup::class);
+ }
}
diff --git a/app/Models/RuleGroup.php b/app/Models/RuleGroup.php
index 8a83bbf0..046ce0d0 100644
--- a/app/Models/RuleGroup.php
+++ b/app/Models/RuleGroup.php
@@ -10,8 +10,7 @@ use Illuminate\Database\Eloquent\Model;
class RuleGroup extends Model
{
protected $table = 'rule_group';
- protected $casts = ['rules' => 'array', 'nodes' => 'array'];
- protected $guarded = ['id'];
+ protected $guarded = [];
public function getTypeLabelAttribute(): string
{
@@ -23,4 +22,9 @@ class RuleGroup extends Model
return $type_label;
}
+
+ public function rules()
+ {
+ return $this->belongsToMany(Rule::class);
+ }
}
diff --git a/app/Models/RuleGroupNode.php b/app/Models/RuleGroupNode.php
deleted file mode 100644
index afff9235..00000000
--- a/app/Models/RuleGroupNode.php
+++ /dev/null
@@ -1,13 +0,0 @@
-BelongsTo(User::class);
+ return $this->belongsTo(User::class);
+ }
+
+ public function reply(): HasMany
+ {
+ return $this->hasMany(TicketReply::class);
}
public function close(): bool
diff --git a/app/Models/User.php b/app/Models/User.php
index dd4b1e00..1f2d88b3 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -22,7 +22,7 @@ class User extends Authenticatable implements JWTSubject
protected $table = 'user';
protected $casts = ['expired_at' => 'date:Y-m-d', 'reset_time' => 'date:Y-m-d', 'ban_time' => 'date:Y-m-d'];
protected $dates = ['expired_at', 'reset_time'];
- protected $guarded = ['id'];
+ protected $guarded = [];
public function usedTrafficPercentage()
{
@@ -63,7 +63,7 @@ class User extends Authenticatable implements JWTSubject
public function onlineIpLogs(): HasMany
{
- return $this->hasMany(NodeOnlineUserIp::class);
+ return $this->hasMany(NodeOnlineIp::class);
}
public function payments(): HasMany
@@ -151,11 +151,6 @@ class User extends Authenticatable implements JWTSubject
return $this->hasMany(Verify::class);
}
- public function group(): BelongsTo
- {
- return $this->belongsTo(UserGroup::class);
- }
-
public function inviter(): BelongsTo
{
return $this->belongsTo(__CLASS__);
@@ -221,24 +216,20 @@ class User extends Authenticatable implements JWTSubject
return $query->where('status', '<>', -1)->whereEnable(1);
}
- public function scopeNodeAllowUsers($query, $node_id, $node_level)
+ public function nodes()
{
- $groups = [0];
- if ($node_id) {
- foreach (UserGroup::all() as $userGroup) {
- $nodes = $userGroup->nodes;
- if ($nodes && in_array($node_id, $nodes)) {
- $groups[] = $userGroup->id;
- }
- }
+ if ($this->attributes['user_group_id']) {
+ $query = $this->group->nodes();
+ } else {
+ $query = Node::query();
}
- return $query->activeUser()->whereIn('group_id', $groups)->where('level', '>=', $node_level);
+ return $query->whereStatus(1)->where('level', '<=', $this->attributes['level'] ?? 0);
}
- public function scopeUserAccessNodes()
+ public function group(): BelongsTo
{
- return Node::userAllowNodes($this->attributes['group_id'] ?? 0, $this->attributes['level'] ?? 0);
+ return $this->belongsTo(UserGroup::class);
}
public function getIsAvailableAttribute(): bool
diff --git a/app/Models/UserGroup.php b/app/Models/UserGroup.php
index 3acc9ce9..185f66d0 100644
--- a/app/Models/UserGroup.php
+++ b/app/Models/UserGroup.php
@@ -11,6 +11,15 @@ class UserGroup extends Model
{
public $timestamps = false;
protected $table = 'user_group';
- protected $casts = ['nodes' => 'array'];
- protected $guarded = ['id'];
+ protected $guarded = [];
+
+ public function users()
+ {
+ return $this->hasMany(User::class);
+ }
+
+ public function nodes()
+ {
+ return $this->belongsToMany(Node::class);
+ }
}
diff --git a/app/Models/UserSubscribe.php b/app/Models/UserSubscribe.php
index 9d22c317..ad85664a 100644
--- a/app/Models/UserSubscribe.php
+++ b/app/Models/UserSubscribe.php
@@ -13,7 +13,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
class UserSubscribe extends Model
{
protected $table = 'user_subscribe';
- protected $guarded = ['id', 'user_id'];
+ protected $guarded = [];
public function scopeUid($query)
{
diff --git a/app/Observers/RuleGroupObserver.php b/app/Observers/RuleGroupObserver.php
deleted file mode 100644
index 4f85e186..00000000
--- a/app/Observers/RuleGroupObserver.php
+++ /dev/null
@@ -1,34 +0,0 @@
-getChanges();
- if ($ruleGroup->nodes && Arr::hasAny($changes, ['type', 'rules'])) {
- $nodes = Node::whereType(4)->whereIn('id', $ruleGroup->nodes)->get();
- if ($nodes->isNotEmpty()) {
- reloadNode::dispatch($nodes);
- }
- } elseif ($ruleGroup->rules && Arr::exists($changes, 'nodes')) {
- $arrayDiff = array_merge(
- array_diff($ruleGroup->nodes ?? [], $ruleGroup->getOriginal('nodes') ?? []),
- array_diff($ruleGroup->getOriginal('nodes') ?? [], $ruleGroup->nodes ?? [])
- );
-
- if ($arrayDiff) {
- $nodes = Node::whereType(4)->whereIn('id', $arrayDiff)->get();
- if ($nodes->isNotEmpty()) {
- reloadNode::dispatch($nodes);
- }
- }
- }
- }
-}
diff --git a/app/Observers/UserObserver.php b/app/Observers/UserObserver.php
index 74a5a04c..5c103b1d 100644
--- a/app/Observers/UserObserver.php
+++ b/app/Observers/UserObserver.php
@@ -19,7 +19,7 @@ class UserObserver
$subscribe->code = Helpers::makeSubscribeCode();
$subscribe->save();
- $allowNodes = $user->userAccessNodes()->whereType(4)->pluck('id');
+ $allowNodes = $user->nodes()->whereType(4)->pluck('id');
if ($allowNodes) {
addUser::dispatch($user->id, $allowNodes);
}
@@ -28,7 +28,7 @@ class UserObserver
public function updated(User $user): void
{
$changes = $user->getChanges();
- $allowNodes = $user->userAccessNodes()->whereType(4)->get();
+ $allowNodes = $user->nodes()->whereType(4)->get();
if ($allowNodes->isNotEmpty() && Arr::hasAny($changes, ['level', 'group_id', 'port', 'passwd', 'speed_limit', 'enable'])) {
editUser::dispatch($user, $allowNodes);
}
@@ -36,7 +36,7 @@ class UserObserver
public function deleted(User $user): void
{
- $allowNodes = $user->userAccessNodes()->whereType(4)->get();
+ $allowNodes = $user->nodes()->whereType(4)->get();
if ($allowNodes->isNotEmpty()) {
delUser::dispatch($user->id, $allowNodes);
}
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index f517d543..eaa2fa95 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -5,7 +5,6 @@ namespace App\Providers;
use App\Models\Config;
use App\Models\Node;
use App\Models\Order;
-use App\Models\RuleGroup;
use App\Models\User;
use App\Models\UserGroup;
use App\Observers\ConfigObserver;
@@ -51,7 +50,6 @@ class AppServiceProvider extends ServiceProvider
Config::observe(ConfigObserver::class);
Node::observe(NodeObserver::class);
Order::observe(OrderObserver::class);
- RuleGroup::observe(RuleGroupObserver::class);
UserGroup::observe(UserGroupObserver::class);
User::observe(UserObserver::class);
}
diff --git a/app/Services/NodeService.php b/app/Services/NodeService.php
index ae17d4fd..ec5ef58e 100644
--- a/app/Services/NodeService.php
+++ b/app/Services/NodeService.php
@@ -4,7 +4,6 @@ namespace App\Services;
use App\Components\IP;
use App\Models\Node;
-use App\Models\NodeLabel;
class NodeService
{
@@ -26,20 +25,4 @@ class NodeService
return $result;
}
-
- // 生成节点标签
- public function makeLabels($nodeId, $labels): void
- {
- // 先删除所有该节点的标签
- NodeLabel::whereNodeId($nodeId)->delete();
-
- if (! empty($labels) && is_array($labels)) {
- foreach ($labels as $label) {
- $nodeLabel = new NodeLabel();
- $nodeLabel->node_id = $nodeId;
- $nodeLabel->label_id = $label;
- $nodeLabel->save();
- }
- }
- }
}
diff --git a/composer.lock b/composer.lock
index cbcd2775..973d6ab3 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1687,16 +1687,16 @@
},
{
"name": "laravel/framework",
- "version": "v7.30.0",
+ "version": "v7.30.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
- "reference": "629c36a0fe87b66d8dccd3c82927950d0f59d3f9"
+ "reference": "e73855b18dcfc645c36d2474f437e4e73dd3c11d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/framework/zipball/629c36a0fe87b66d8dccd3c82927950d0f59d3f9",
- "reference": "629c36a0fe87b66d8dccd3c82927950d0f59d3f9",
+ "url": "https://api.github.com/repos/laravel/framework/zipball/e73855b18dcfc645c36d2474f437e4e73dd3c11d",
+ "reference": "e73855b18dcfc645c36d2474f437e4e73dd3c11d",
"shasum": ""
},
"require": {
@@ -1845,7 +1845,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
- "time": "2020-12-01T15:01:25+00:00"
+ "time": "2020-12-22T17:00:45+00:00"
},
{
"name": "laravel/tinker",
@@ -2595,16 +2595,16 @@
},
{
"name": "mews/captcha",
- "version": "3.2.3",
+ "version": "3.2.4",
"source": {
"type": "git",
"url": "https://github.com/mewebstudio/captcha.git",
- "reference": "b5549a90110ec6c32a93073aba3ea9ade288c6f7"
+ "reference": "616d006be6f53e87b93f6dc0f298fb29ca0b7d6c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mewebstudio/captcha/zipball/b5549a90110ec6c32a93073aba3ea9ade288c6f7",
- "reference": "b5549a90110ec6c32a93073aba3ea9ade288c6f7",
+ "url": "https://api.github.com/repos/mewebstudio/captcha/zipball/616d006be6f53e87b93f6dc0f298fb29ca0b7d6c",
+ "reference": "616d006be6f53e87b93f6dc0f298fb29ca0b7d6c",
"shasum": ""
},
"require": {
@@ -2662,9 +2662,9 @@
],
"support": {
"issues": "https://github.com/mewebstudio/captcha/issues",
- "source": "https://github.com/mewebstudio/captcha/tree/3.2.3"
+ "source": "https://github.com/mewebstudio/captcha/tree/3.2.4"
},
- "time": "2020-11-03T19:44:37+00:00"
+ "time": "2020-12-14T12:34:10+00:00"
},
{
"name": "mews/purifier",
@@ -2805,16 +2805,16 @@
},
{
"name": "monolog/monolog",
- "version": "2.1.1",
+ "version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
- "reference": "f9eee5cec93dfb313a38b6b288741e84e53f02d5"
+ "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f9eee5cec93dfb313a38b6b288741e84e53f02d5",
- "reference": "f9eee5cec93dfb313a38b6b288741e84e53f02d5",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1cb1cde8e8dd0f70cc0fe51354a59acad9302084",
+ "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084",
"shasum": ""
},
"require": {
@@ -2827,16 +2827,17 @@
"require-dev": {
"aws/aws-sdk-php": "^2.4.9 || ^3.0",
"doctrine/couchdb": "~1.0@dev",
- "elasticsearch/elasticsearch": "^6.0",
+ "elasticsearch/elasticsearch": "^7",
"graylog2/gelf-php": "^1.4.2",
+ "mongodb/mongodb": "^1.8",
"php-amqplib/php-amqplib": "~2.4",
"php-console/php-console": "^3.1.3",
- "php-parallel-lint/php-parallel-lint": "^1.0",
"phpspec/prophecy": "^1.6.1",
+ "phpstan/phpstan": "^0.12.59",
"phpunit/phpunit": "^8.5",
"predis/predis": "^1.1",
"rollbar/rollbar": "^1.3",
- "ruflin/elastica": ">=0.90 <3.0",
+ "ruflin/elastica": ">=0.90 <7.0.1",
"swiftmailer/swiftmailer": "^5.3|^6.0"
},
"suggest": {
@@ -2856,7 +2857,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.x-dev"
+ "dev-main": "2.x-dev"
}
},
"autoload": {
@@ -2872,11 +2873,11 @@
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
+ "homepage": "https://seld.be"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
- "homepage": "http://github.com/Seldaek/monolog",
+ "homepage": "https://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
@@ -2884,7 +2885,7 @@
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
- "source": "https://github.com/Seldaek/monolog/tree/2.1.1"
+ "source": "https://github.com/Seldaek/monolog/tree/2.2.0"
},
"funding": [
{
@@ -2896,7 +2897,7 @@
"type": "tidelift"
}
],
- "time": "2020-07-23T08:41:23+00:00"
+ "time": "2020-12-14T13:15:25+00:00"
},
{
"name": "myclabs/php-enum",
@@ -3027,16 +3028,16 @@
},
{
"name": "nesbot/carbon",
- "version": "2.42.0",
+ "version": "2.43.0",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
- "reference": "d0463779663437392fe42ff339ebc0213bd55498"
+ "reference": "d32c57d8389113742f4a88725a170236470012e2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d0463779663437392fe42ff339ebc0213bd55498",
- "reference": "d0463779663437392fe42ff339ebc0213bd55498",
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d32c57d8389113742f4a88725a170236470012e2",
+ "reference": "d32c57d8389113742f4a88725a170236470012e2",
"shasum": ""
},
"require": {
@@ -3116,20 +3117,20 @@
"type": "tidelift"
}
],
- "time": "2020-11-28T14:25:28+00:00"
+ "time": "2020-12-17T20:55:32+00:00"
},
{
"name": "nikic/php-parser",
- "version": "v4.10.3",
+ "version": "v4.10.4",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984"
+ "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984",
- "reference": "dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e",
+ "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e",
"shasum": ""
},
"require": {
@@ -3170,9 +3171,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
- "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.3"
+ "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4"
},
- "time": "2020-12-03T17:45:45+00:00"
+ "time": "2020-12-20T10:01:03+00:00"
},
{
"name": "opis/closure",
@@ -4521,16 +4522,16 @@
},
{
"name": "symfony/console",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "3e0564fb08d44a98bd5f1960204c958e57bd586b"
+ "reference": "47c02526c532fb381374dab26df05e7313978976"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/3e0564fb08d44a98bd5f1960204c958e57bd586b",
- "reference": "3e0564fb08d44a98bd5f1960204c958e57bd586b",
+ "url": "https://api.github.com/repos/symfony/console/zipball/47c02526c532fb381374dab26df05e7313978976",
+ "reference": "47c02526c532fb381374dab26df05e7313978976",
"shasum": ""
},
"require": {
@@ -4598,7 +4599,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v5.2.0"
+ "source": "https://github.com/symfony/console/tree/v5.2.1"
},
"funding": [
{
@@ -4614,20 +4615,20 @@
"type": "tidelift"
}
],
- "time": "2020-11-28T11:24:18+00:00"
+ "time": "2020-12-18T08:03:05+00:00"
},
{
"name": "symfony/css-selector",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "b8d8eb06b0942e84a69e7acebc3e9c1e6e6e7256"
+ "reference": "f789e7ead4c79e04ca9a6d6162fc629c89bd8054"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/b8d8eb06b0942e84a69e7acebc3e9c1e6e6e7256",
- "reference": "b8d8eb06b0942e84a69e7acebc3e9c1e6e6e7256",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/f789e7ead4c79e04ca9a6d6162fc629c89bd8054",
+ "reference": "f789e7ead4c79e04ca9a6d6162fc629c89bd8054",
"shasum": ""
},
"require": {
@@ -4663,7 +4664,7 @@
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/css-selector/tree/v5.2.0"
+ "source": "https://github.com/symfony/css-selector/tree/v5.2.1"
},
"funding": [
{
@@ -4679,7 +4680,7 @@
"type": "tidelift"
}
],
- "time": "2020-10-28T21:31:18+00:00"
+ "time": "2020-12-08T17:02:38+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -4750,16 +4751,16 @@
},
{
"name": "symfony/error-handler",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/error-handler.git",
- "reference": "289008c5be039e39908d33ae0a8ac99be1210bba"
+ "reference": "59b190ce16ddf32771a22087b60f6dafd3407147"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/error-handler/zipball/289008c5be039e39908d33ae0a8ac99be1210bba",
- "reference": "289008c5be039e39908d33ae0a8ac99be1210bba",
+ "url": "https://api.github.com/repos/symfony/error-handler/zipball/59b190ce16ddf32771a22087b60f6dafd3407147",
+ "reference": "59b190ce16ddf32771a22087b60f6dafd3407147",
"shasum": ""
},
"require": {
@@ -4799,7 +4800,7 @@
"description": "Symfony ErrorHandler Component",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/error-handler/tree/v5.2.0"
+ "source": "https://github.com/symfony/error-handler/tree/v5.2.1"
},
"funding": [
{
@@ -4815,20 +4816,20 @@
"type": "tidelift"
}
],
- "time": "2020-10-28T21:46:03+00:00"
+ "time": "2020-12-09T18:54:12+00:00"
},
{
"name": "symfony/event-dispatcher",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "aa13a09811e6d2ad43f8fb336bebdb7691d85d3c"
+ "reference": "1c93f7a1dff592c252574c79a8635a8a80856042"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/aa13a09811e6d2ad43f8fb336bebdb7691d85d3c",
- "reference": "aa13a09811e6d2ad43f8fb336bebdb7691d85d3c",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1c93f7a1dff592c252574c79a8635a8a80856042",
+ "reference": "1c93f7a1dff592c252574c79a8635a8a80856042",
"shasum": ""
},
"require": {
@@ -4884,7 +4885,7 @@
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/event-dispatcher/tree/v5.2.0"
+ "source": "https://github.com/symfony/event-dispatcher/tree/v5.2.1"
},
"funding": [
{
@@ -4900,7 +4901,7 @@
"type": "tidelift"
}
],
- "time": "2020-11-01T16:14:45+00:00"
+ "time": "2020-12-18T08:03:05+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
@@ -4983,16 +4984,16 @@
},
{
"name": "symfony/finder",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "fd8305521692f27eae3263895d1ef1571c71a78d"
+ "reference": "0b9231a5922fd7287ba5b411893c0ecd2733e5ba"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/fd8305521692f27eae3263895d1ef1571c71a78d",
- "reference": "fd8305521692f27eae3263895d1ef1571c71a78d",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/0b9231a5922fd7287ba5b411893c0ecd2733e5ba",
+ "reference": "0b9231a5922fd7287ba5b411893c0ecd2733e5ba",
"shasum": ""
},
"require": {
@@ -5024,7 +5025,7 @@
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/finder/tree/v5.2.0"
+ "source": "https://github.com/symfony/finder/tree/v5.2.1"
},
"funding": [
{
@@ -5040,7 +5041,7 @@
"type": "tidelift"
}
],
- "time": "2020-11-18T09:42:36+00:00"
+ "time": "2020-12-08T17:02:38+00:00"
},
{
"name": "symfony/http-client-contracts",
@@ -5123,16 +5124,16 @@
},
{
"name": "symfony/http-foundation",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "e4576271ee99123aa59a40564c7b5405f0ebd1e6"
+ "reference": "a1f6218b29897ab52acba58cfa905b83625bef8d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e4576271ee99123aa59a40564c7b5405f0ebd1e6",
- "reference": "e4576271ee99123aa59a40564c7b5405f0ebd1e6",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a1f6218b29897ab52acba58cfa905b83625bef8d",
+ "reference": "a1f6218b29897ab52acba58cfa905b83625bef8d",
"shasum": ""
},
"require": {
@@ -5176,7 +5177,7 @@
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-foundation/tree/v5.2.0"
+ "source": "https://github.com/symfony/http-foundation/tree/v5.2.1"
},
"funding": [
{
@@ -5192,20 +5193,20 @@
"type": "tidelift"
}
],
- "time": "2020-11-27T06:13:25+00:00"
+ "time": "2020-12-18T10:00:10+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "38907e5ccb2d9d371191a946734afc83c7a03160"
+ "reference": "1feb619286d819180f7b8bc0dc44f516d9c62647"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/38907e5ccb2d9d371191a946734afc83c7a03160",
- "reference": "38907e5ccb2d9d371191a946734afc83c7a03160",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1feb619286d819180f7b8bc0dc44f516d9c62647",
+ "reference": "1feb619286d819180f7b8bc0dc44f516d9c62647",
"shasum": ""
},
"require": {
@@ -5288,7 +5289,7 @@
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-kernel/tree/v5.2.0"
+ "source": "https://github.com/symfony/http-kernel/tree/v5.2.1"
},
"funding": [
{
@@ -5304,20 +5305,20 @@
"type": "tidelift"
}
],
- "time": "2020-11-30T05:54:18+00:00"
+ "time": "2020-12-18T13:49:39+00:00"
},
{
"name": "symfony/mime",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
- "reference": "05f667e8fa029568964fd3bec6bc17765b853cc5"
+ "reference": "de97005aef7426ba008c46ba840fc301df577ada"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mime/zipball/05f667e8fa029568964fd3bec6bc17765b853cc5",
- "reference": "05f667e8fa029568964fd3bec6bc17765b853cc5",
+ "url": "https://api.github.com/repos/symfony/mime/zipball/de97005aef7426ba008c46ba840fc301df577ada",
+ "reference": "de97005aef7426ba008c46ba840fc301df577ada",
"shasum": ""
},
"require": {
@@ -5368,7 +5369,7 @@
"mime-type"
],
"support": {
- "source": "https://github.com/symfony/mime/tree/v5.2.0"
+ "source": "https://github.com/symfony/mime/tree/v5.2.1"
},
"funding": [
{
@@ -5384,7 +5385,7 @@
"type": "tidelift"
}
],
- "time": "2020-10-30T14:55:39+00:00"
+ "time": "2020-12-09T18:54:12+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -6185,16 +6186,16 @@
},
{
"name": "symfony/process",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "240e74140d4d956265048f3025c0aecbbc302d54"
+ "reference": "bd8815b8b6705298beaa384f04fabd459c10bedd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/240e74140d4d956265048f3025c0aecbbc302d54",
- "reference": "240e74140d4d956265048f3025c0aecbbc302d54",
+ "url": "https://api.github.com/repos/symfony/process/zipball/bd8815b8b6705298beaa384f04fabd459c10bedd",
+ "reference": "bd8815b8b6705298beaa384f04fabd459c10bedd",
"shasum": ""
},
"require": {
@@ -6227,7 +6228,7 @@
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/process/tree/v5.2.0"
+ "source": "https://github.com/symfony/process/tree/v5.2.1"
},
"funding": [
{
@@ -6243,20 +6244,20 @@
"type": "tidelift"
}
],
- "time": "2020-11-02T15:47:15+00:00"
+ "time": "2020-12-08T17:03:37+00:00"
},
{
"name": "symfony/routing",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "130ac5175ad2fd417978baebd8062e2e6b2bc28b"
+ "reference": "934ac2720dcc878a47a45c986b483a7ee7193620"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/130ac5175ad2fd417978baebd8062e2e6b2bc28b",
- "reference": "130ac5175ad2fd417978baebd8062e2e6b2bc28b",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/934ac2720dcc878a47a45c986b483a7ee7193620",
+ "reference": "934ac2720dcc878a47a45c986b483a7ee7193620",
"shasum": ""
},
"require": {
@@ -6317,7 +6318,7 @@
"url"
],
"support": {
- "source": "https://github.com/symfony/routing/tree/v5.2.0"
+ "source": "https://github.com/symfony/routing/tree/v5.2.1"
},
"funding": [
{
@@ -6333,7 +6334,7 @@
"type": "tidelift"
}
],
- "time": "2020-11-27T00:39:34+00:00"
+ "time": "2020-12-08T17:03:37+00:00"
},
{
"name": "symfony/service-contracts",
@@ -6416,16 +6417,16 @@
},
{
"name": "symfony/string",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "40e975edadd4e32cd16f3753b3bad65d9ac48242"
+ "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/40e975edadd4e32cd16f3753b3bad65d9ac48242",
- "reference": "40e975edadd4e32cd16f3753b3bad65d9ac48242",
+ "url": "https://api.github.com/repos/symfony/string/zipball/5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed",
+ "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed",
"shasum": ""
},
"require": {
@@ -6479,7 +6480,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v5.2.0"
+ "source": "https://github.com/symfony/string/tree/v5.2.1"
},
"funding": [
{
@@ -6495,20 +6496,20 @@
"type": "tidelift"
}
],
- "time": "2020-10-24T12:08:07+00:00"
+ "time": "2020-12-05T07:33:16+00:00"
},
{
"name": "symfony/translation",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
- "reference": "52f486a707510884450df461b5a6429dd7a67379"
+ "reference": "a04209ba0d1391c828e5b2373181dac63c52ee70"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/52f486a707510884450df461b5a6429dd7a67379",
- "reference": "52f486a707510884450df461b5a6429dd7a67379",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/a04209ba0d1391c828e5b2373181dac63c52ee70",
+ "reference": "a04209ba0d1391c828e5b2373181dac63c52ee70",
"shasum": ""
},
"require": {
@@ -6572,7 +6573,7 @@
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/translation/tree/v5.2.0"
+ "source": "https://github.com/symfony/translation/tree/v5.2.1"
},
"funding": [
{
@@ -6588,7 +6589,7 @@
"type": "tidelift"
}
],
- "time": "2020-11-28T11:24:18+00:00"
+ "time": "2020-12-08T17:03:37+00:00"
},
{
"name": "symfony/translation-contracts",
@@ -6670,16 +6671,16 @@
},
{
"name": "symfony/var-dumper",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "173a79c462b1c81e1fa26129f71e41333d846b26"
+ "reference": "13e7e882eaa55863faa7c4ad7c60f12f1a8b5089"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/173a79c462b1c81e1fa26129f71e41333d846b26",
- "reference": "173a79c462b1c81e1fa26129f71e41333d846b26",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/13e7e882eaa55863faa7c4ad7c60f12f1a8b5089",
+ "reference": "13e7e882eaa55863faa7c4ad7c60f12f1a8b5089",
"shasum": ""
},
"require": {
@@ -6738,7 +6739,7 @@
"dump"
],
"support": {
- "source": "https://github.com/symfony/var-dumper/tree/v5.2.0"
+ "source": "https://github.com/symfony/var-dumper/tree/v5.2.1"
},
"funding": [
{
@@ -6754,20 +6755,20 @@
"type": "tidelift"
}
],
- "time": "2020-11-27T00:39:34+00:00"
+ "time": "2020-12-16T17:02:19+00:00"
},
{
"name": "symfony/yaml",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "bb73619b2ae5121bbbcd9f191dfd53ded17ae598"
+ "reference": "290ea5e03b8cf9b42c783163123f54441fb06939"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/bb73619b2ae5121bbbcd9f191dfd53ded17ae598",
- "reference": "bb73619b2ae5121bbbcd9f191dfd53ded17ae598",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/290ea5e03b8cf9b42c783163123f54441fb06939",
+ "reference": "290ea5e03b8cf9b42c783163123f54441fb06939",
"shasum": ""
},
"require": {
@@ -6813,7 +6814,7 @@
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/yaml/tree/v5.2.0"
+ "source": "https://github.com/symfony/yaml/tree/v5.2.1"
},
"funding": [
{
@@ -6829,7 +6830,7 @@
"type": "tidelift"
}
],
- "time": "2020-11-28T10:57:20+00:00"
+ "time": "2020-12-08T17:02:38+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
@@ -7547,16 +7548,16 @@
},
{
"name": "andrey-helldar/support",
- "version": "v1.26.0",
+ "version": "v1.30.2",
"source": {
"type": "git",
"url": "https://github.com/andrey-helldar/support.git",
- "reference": "608895d7324d44167a97a88ebec766e99dee92c7"
+ "reference": "e463d3c5ed4302ab04001a04d3264fc78acac858"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/andrey-helldar/support/zipball/608895d7324d44167a97a88ebec766e99dee92c7",
- "reference": "608895d7324d44167a97a88ebec766e99dee92c7",
+ "url": "https://api.github.com/repos/andrey-helldar/support/zipball/e463d3c5ed4302ab04001a04d3264fc78acac858",
+ "reference": "e463d3c5ed4302ab04001a04d3264fc78acac858",
"shasum": ""
},
"require": {
@@ -7585,7 +7586,7 @@
},
"autoload": {
"psr-4": {
- "Helldar\\Support\\": "src/"
+ "Helldar\\Support\\": "src"
},
"files": [
"src/helpers/digit.php",
@@ -7627,7 +7628,7 @@
"type": "custom"
}
],
- "time": "2020-11-30T12:10:47+00:00"
+ "time": "2020-12-25T21:28:47+00:00"
},
{
"name": "arcanedev/laravel-lang",
@@ -8611,16 +8612,16 @@
},
{
"name": "fakerphp/faker",
- "version": "v1.12.0",
+ "version": "v1.13.0",
"source": {
"type": "git",
"url": "https://github.com/FakerPHP/Faker.git",
- "reference": "9aa6c9e289860951e6b4d010c7a841802d015cd8"
+ "reference": "ab3f5364d01f2c2c16113442fb987d26e4004913"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/9aa6c9e289860951e6b4d010c7a841802d015cd8",
- "reference": "9aa6c9e289860951e6b4d010c7a841802d015cd8",
+ "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/ab3f5364d01f2c2c16113442fb987d26e4004913",
+ "reference": "ab3f5364d01f2c2c16113442fb987d26e4004913",
"shasum": ""
},
"require": {
@@ -8657,9 +8658,9 @@
],
"support": {
"issues": "https://github.com/FakerPHP/Faker/issues",
- "source": "https://github.com/FakerPHP/Faker/tree/v1.12.0"
+ "source": "https://github.com/FakerPHP/Faker/tree/v1.13.0"
},
- "time": "2020-11-23T09:33:08+00:00"
+ "time": "2020-12-18T16:50:48+00:00"
},
{
"name": "filp/whoops",
@@ -9252,6 +9253,127 @@
],
"time": "2020-10-29T15:12:23+00:00"
},
+ {
+ "name": "paragonie/constant_time_encoding",
+ "version": "v2.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/constant_time_encoding.git",
+ "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c",
+ "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7|^8"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6|^7|^8|^9",
+ "vimeo/psalm": "^1|^2|^3|^4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "ParagonIE\\ConstantTime\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Steve 'Sc00bz' Thomas",
+ "email": "steve@tobtu.com",
+ "homepage": "https://www.tobtu.com",
+ "role": "Original Developer"
+ }
+ ],
+ "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
+ "keywords": [
+ "base16",
+ "base32",
+ "base32_decode",
+ "base32_encode",
+ "base64",
+ "base64_decode",
+ "base64_encode",
+ "bin2hex",
+ "encoding",
+ "hex",
+ "hex2bin",
+ "rfc4648"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/constant_time_encoding/issues",
+ "source": "https://github.com/paragonie/constant_time_encoding"
+ },
+ "time": "2020-12-06T15:14:20+00:00"
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "v2.0.19",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/446fc9faa5c2a9ddf65eb7121c0af7e857295241",
+ "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "lib/random.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "polyfill",
+ "pseudorandom",
+ "random"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/random_compat/issues",
+ "source": "https://github.com/paragonie/random_compat"
+ },
+ "time": "2020-10-15T10:06:57+00:00"
+ },
{
"name": "phar-io/manifest",
"version": "2.0.1",
@@ -9314,16 +9436,16 @@
},
{
"name": "phar-io/version",
- "version": "3.0.3",
+ "version": "3.0.4",
"source": {
"type": "git",
"url": "https://github.com/phar-io/version.git",
- "reference": "726c026815142e4f8677b7cb7f2249c9ffb7ecae"
+ "reference": "e4782611070e50613683d2b9a57730e9a3ba5451"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/version/zipball/726c026815142e4f8677b7cb7f2249c9ffb7ecae",
- "reference": "726c026815142e4f8677b7cb7f2249c9ffb7ecae",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/e4782611070e50613683d2b9a57730e9a3ba5451",
+ "reference": "e4782611070e50613683d2b9a57730e9a3ba5451",
"shasum": ""
},
"require": {
@@ -9359,9 +9481,9 @@
"description": "Library for handling version information and constraints",
"support": {
"issues": "https://github.com/phar-io/version/issues",
- "source": "https://github.com/phar-io/version/tree/3.0.3"
+ "source": "https://github.com/phar-io/version/tree/3.0.4"
},
- "time": "2020-11-30T09:21:21+00:00"
+ "time": "2020-12-13T23:18:30+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@@ -9523,26 +9645,26 @@
},
{
"name": "phpseclib/bcmath_compat",
- "version": "1.0.5",
+ "version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/bcmath_compat.git",
- "reference": "89cbb63742a32730b7187773a60b6b12b9db4479"
+ "reference": "fd896dfceffc13d8cf45d2ee3470777a70026f3c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpseclib/bcmath_compat/zipball/89cbb63742a32730b7187773a60b6b12b9db4479",
- "reference": "89cbb63742a32730b7187773a60b6b12b9db4479",
+ "url": "https://api.github.com/repos/phpseclib/bcmath_compat/zipball/fd896dfceffc13d8cf45d2ee3470777a70026f3c",
+ "reference": "fd896dfceffc13d8cf45d2ee3470777a70026f3c",
"shasum": ""
},
"require": {
- "phpseclib/phpseclib": ">=2.0.19"
+ "phpseclib/phpseclib": "^3.0"
},
"provide": {
- "ext-bcmath": "7.3.5"
+ "ext-bcmath": "8.0.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.8.35|^5.7|^6.0",
+ "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4",
"squizlabs/php_codesniffer": "^3.0"
},
"suggest": {
@@ -9581,28 +9703,30 @@
"issues": "https://github.com/phpseclib/bcmath_compat/issues",
"source": "https://github.com/phpseclib/bcmath_compat"
},
- "time": "2020-04-26T16:34:33+00:00"
+ "time": "2020-12-22T16:38:51+00:00"
},
{
"name": "phpseclib/phpseclib",
- "version": "2.0.29",
+ "version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
- "reference": "497856a8d997f640b4a516062f84228a772a48a8"
+ "reference": "7a9418e4e02a3da7950b6b85c30e694d68daf995"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/497856a8d997f640b4a516062f84228a772a48a8",
- "reference": "497856a8d997f640b4a516062f84228a772a48a8",
+ "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7a9418e4e02a3da7950b6b85c30e694d68daf995",
+ "reference": "7a9418e4e02a3da7950b6b85c30e694d68daf995",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "paragonie/constant_time_encoding": "^1|^2",
+ "paragonie/random_compat": "^1.4|^2.0",
+ "php": ">=5.6.1"
},
"require-dev": {
"phing/phing": "~2.7",
- "phpunit/phpunit": "^4.8.35|^5.7|^6.0",
+ "phpunit/phpunit": "^5.7|^6.0|^9.4",
"squizlabs/php_codesniffer": "~2.0"
},
"suggest": {
@@ -9617,7 +9741,7 @@
"phpseclib/bootstrap.php"
],
"psr-4": {
- "phpseclib\\": "phpseclib/"
+ "phpseclib3\\": "phpseclib/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -9674,7 +9798,7 @@
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
- "source": "https://github.com/phpseclib/phpseclib/tree/2.0"
+ "source": "https://github.com/phpseclib/phpseclib/tree/3.0.2"
},
"funding": [
{
@@ -9690,20 +9814,20 @@
"type": "tidelift"
}
],
- "time": "2020-09-08T04:24:43+00:00"
+ "time": "2020-12-23T16:39:00+00:00"
},
{
"name": "phpspec/prophecy",
- "version": "1.12.1",
+ "version": "1.12.2",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
- "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d"
+ "reference": "245710e971a030f42e08f4912863805570f23d39"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d",
- "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39",
+ "reference": "245710e971a030f42e08f4912863805570f23d39",
"shasum": ""
},
"require": {
@@ -9715,7 +9839,7 @@
},
"require-dev": {
"phpspec/phpspec": "^6.0",
- "phpunit/phpunit": "^8.0 || ^9.0 <9.3"
+ "phpunit/phpunit": "^8.0 || ^9.0"
},
"type": "library",
"extra": {
@@ -9755,9 +9879,9 @@
],
"support": {
"issues": "https://github.com/phpspec/prophecy/issues",
- "source": "https://github.com/phpspec/prophecy/tree/1.12.1"
+ "source": "https://github.com/phpspec/prophecy/tree/1.12.2"
},
- "time": "2020-09-29T09:10:42+00:00"
+ "time": "2020-12-19T10:15:11+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -11307,16 +11431,16 @@
},
{
"name": "symfony/debug",
- "version": "v4.4.17",
+ "version": "v4.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
- "reference": "65fe7b49868378319b82da3035fb30801b931c47"
+ "reference": "5dfc7825f3bfe9bb74b23d8b8ce0e0894e32b544"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/65fe7b49868378319b82da3035fb30801b931c47",
- "reference": "65fe7b49868378319b82da3035fb30801b931c47",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/5dfc7825f3bfe9bb74b23d8b8ce0e0894e32b544",
+ "reference": "5dfc7825f3bfe9bb74b23d8b8ce0e0894e32b544",
"shasum": ""
},
"require": {
@@ -11356,7 +11480,7 @@
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/debug/tree/v4.4.17"
+ "source": "https://github.com/symfony/debug/tree/v4.4.18"
},
"funding": [
{
@@ -11372,20 +11496,20 @@
"type": "tidelift"
}
],
- "time": "2020-10-28T20:42:29+00:00"
+ "time": "2020-12-10T16:34:26+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v5.2.0",
+ "version": "v5.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "bb92ba7f38b037e531908590a858a04d85c0e238"
+ "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/bb92ba7f38b037e531908590a858a04d85c0e238",
- "reference": "bb92ba7f38b037e531908590a858a04d85c0e238",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/fa8f8cab6b65e2d99a118e082935344c5ba8c60d",
+ "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d",
"shasum": ""
},
"require": {
@@ -11418,7 +11542,7 @@
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/filesystem/tree/v5.2.0"
+ "source": "https://github.com/symfony/filesystem/tree/v5.2.1"
},
"funding": [
{
@@ -11434,7 +11558,7 @@
"type": "tidelift"
}
],
- "time": "2020-11-12T09:58:18+00:00"
+ "time": "2020-11-30T17:05:38+00:00"
},
{
"name": "theseer/tokenizer",
diff --git a/config/version.php b/config/version.php
index 5ff19d4b..7f840569 100644
--- a/config/version.php
+++ b/config/version.php
@@ -2,5 +2,5 @@
return [
'name' => 'ProxyPanel',
- 'number' => '2.5.x',
+ 'number' => '2.6.a',
];
diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php
index 5f6dcf19..08faf1fc 100644
--- a/database/factories/UserFactory.php
+++ b/database/factories/UserFactory.php
@@ -1,16 +1,23 @@
define(User::class, function (Faker $faker) {
return [
'username' => $faker->name,
'email' => $faker->unique()->safeEmail,
'password' => Hash::make(Str::random()),
+ 'port' => Helpers::getPort(),
'passwd' => Str::random(),
'vmess_id' => $faker->uuid,
+ 'method' => Helpers::getDefaultMethod(),
+ 'protocol' => Helpers::getDefaultProtocol(),
+ 'obfs' => Helpers::getDefaultObfs(),
+ 'transfer_enable' => (int) sysConfig('default_traffic') * MB,
+ 'expired_at' => date('Y-m-d', strtotime('+'.sysConfig('default_days').' days')),
];
});
diff --git a/database/migrations/2020_12_24_074739_table_improvement.php b/database/migrations/2020_12_24_074739_table_improvement.php
new file mode 100644
index 00000000..31a831cf
--- /dev/null
+++ b/database/migrations/2020_12_24_074739_table_improvement.php
@@ -0,0 +1,192 @@
+unique('level');
+ });
+
+ Schema::table('node_certificate', function (Blueprint $table) {
+ $table->unique('domain');
+ });
+
+ Schema::table('ss_node', function (Blueprint $table) {
+ $table->unsignedInteger('rule_group_id')->nullable()->comment('从属规则分组ID')->after('level');
+ $table->foreign('rule_group_id')->references('id')->on('rule_group')->nullOnDelete();
+ $table->rename('node');
+ });
+
+ Schema::table('ss_node_info', function (Blueprint $table) {
+ $table->unsignedInteger('node_id')->comment('节点ID')->change();
+ $table->rename('node_heartbeat');
+ });
+
+ Schema::table('ss_node_ip', function (Blueprint $table) {
+ $table->rename('node_online_ip');
+ });
+ NodeOnlineIp::whereNodeId(0)->update(['node_id' => null]);
+ NodeOnlineIp::whereUserId(0)->update(['user_id' => null]);
+ Schema::table('node_online_ip', function (Blueprint $table) {
+ $table->unsignedInteger('node_id')->comment('节点ID')->change();
+ $table->unsignedInteger('user_id')->default(null)->nullable()->change();
+ });
+
+ Schema::table('ss_node_online_log', function (Blueprint $table) {
+ $table->rename('node_online_log');
+ });
+
+ Schema::table('node_label', function (Blueprint $table) {
+ $table->unsignedInteger('node_id')->comment('节点ID')->change();
+ $table->unsignedInteger('label_id')->comment('标签ID')->change();
+ $table->unique(['node_id', 'label_id']);
+ $table->rename('label_node');
+ });
+
+ Schema::table('node_ping', function (Blueprint $table) {
+ $table->unsignedInteger('node_id')->comment('对应节点ID')->change();
+ });
+
+ Order::whereGoodsId(0)->update(['goods_id' => null]);
+ Order::whereCouponId(0)->orWhereNotIn('coupon_id', Coupon::withTrashed()->pluck('id')->toArray())->update(['coupon_id' => null]);
+ Schema::table('order', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('购买者ID')->change();
+ $table->foreign('goods_id')->references('id')->on('goods')->nullOnDelete();
+ $table->foreign('coupon_id')->references('id')->on('coupon')->nullOnDelete();
+ });
+
+ Schema::create('node_user_group', function (Blueprint $table) {
+ $table->increments('id');
+ $table->unsignedInteger('node_id')->comment('节点ID');
+ $table->unsignedInteger('user_group_id')->comment('从属用户分组ID');
+
+ $table->unique(['user_group_id', 'node_id']);
+ $table->foreign('node_id')->references('id')->on('node')->cascadeOnDelete();
+ $table->foreign('user_group_id')->references('id')->on('user_group')->cascadeOnDelete();
+ });
+
+ Schema::table('payment', function (Blueprint $table) {
+ $table->foreign('order_id')->references('id')->on('order')->cascadeOnDelete();
+ });
+
+ Schema::table('referral_apply', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('申请者ID')->change();
+ });
+
+ Schema::table('rule_log', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('触发者ID')->change();
+ });
+
+ Schema::create('rule_rule_group', function (Blueprint $table) {
+ $table->increments('id');
+ $table->unsignedInteger('rule_id')->comment('规则ID');
+ $table->unsignedInteger('rule_group_id')->comment('从属规则分组ID');
+
+ $table->unique(['rule_group_id', 'rule_id']);
+ $table->foreign('rule_id')->references('id')->on('rule')->cascadeOnDelete();
+ $table->foreign('rule_group_id')->references('id')->on('rule_group')->cascadeOnDelete();
+ });
+
+ Schema::table('ticket', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('用户ID')->change();
+ });
+
+ Schema::table('ticket_reply', function (Blueprint $table) {
+ $table->unsignedInteger('ticket_id')->comment('工单ID')->change();
+ });
+
+ Schema::table('user', function (Blueprint $table) {
+ $table->unsignedInteger('group_id')->nullable()->default(null)->comment('所属分组')->change();
+ });
+ User::whereGroupId(0)->update(['group_id' => null]);
+ Schema::table('user', function (Blueprint $table) {
+ $table->renameColumn('group_id', 'user_group_id');
+ $table->foreign('user_group_id')->references('id')->on('user_group')->nullOnDelete();
+ });
+
+ Schema::table('user_baned_log', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('用户ID')->change();
+ });
+
+ Schema::table('user_credit_log', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('用户ID')->change();
+ });
+
+ Schema::table('user_daily_data_flow', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('用户ID')->change();
+ });
+
+ Schema::table('user_data_modify_log', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('用户ID')->change();
+ });
+
+ Schema::table('user_hourly_data_flow', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('用户ID')->change();
+ });
+
+ Schema::table('user_login_log', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('用户ID')->change();
+ });
+
+ Schema::table('user_subscribe', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('用户ID')->change();
+ });
+
+ Schema::table('user_traffic_log', function (Blueprint $table) {
+ $table->unsignedInteger('user_id')->comment('用户ID')->change();
+ $table->unsignedInteger('node_id')->comment('节点ID')->change();
+ });
+ // ----- 结束 数据库表关系优化 -----
+
+ // ----- 开始 数据转化 & 弃用数据 -----
+ foreach (RuleGroup::all() as $group) {
+ $group->rules()->attach(json_decode($group->rules, true));
+ foreach (json_decode($group->nodes, true) as $id) {
+ $node = Node::find($id);
+ if ($node) {
+ $node->update(['rule_group_id' => $group->id]);
+ }
+ }
+ }
+
+ foreach (UserGroup::all() as $group) {
+ $group->nodes()->attach(json_decode($group->nodes, true));
+ }
+
+ Schema::table('rule_group', function (Blueprint $table) {
+ $table->dropColumn('nodes');
+ $table->dropColumn('rules');
+ });
+
+ Schema::table('user_group', function (Blueprint $table) {
+ $table->dropColumn('nodes');
+ });
+
+ Schema::table('node_rule', function (Blueprint $table) {
+ $table->drop();
+ });
+
+ Schema::table('rule_group_node', function (Blueprint $table) {
+ $table->drop();
+ });
+ // ----- 结束 数据转化 & 弃用数据 -----
+ }
+
+ public function down()
+ {
+ // 不可逆
+ }
+}
diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php
index 237dfc5d..a0a2fd34 100644
--- a/database/seeds/DatabaseSeeder.php
+++ b/database/seeds/DatabaseSeeder.php
@@ -1,5 +1,6 @@
call(UserSeeder::class);
+ if (User::doesntExist()) {
+ $this->call(PresetSeeder::class);
+ }
}
}
diff --git a/database/migrations/2020_08_21_150711_preset_data.php b/database/seeds/PresetSeeder.php
similarity index 72%
rename from database/migrations/2020_08_21_150711_preset_data.php
rename to database/seeds/PresetSeeder.php
index ed8db159..8cc81929 100644
--- a/database/migrations/2020_08_21_150711_preset_data.php
+++ b/database/seeds/PresetSeeder.php
@@ -8,73 +8,18 @@ use App\Models\Level;
use App\Models\Rule;
use App\Models\SsConfig;
use App\Models\User;
-use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Seeder;
-class PresetData extends Migration
+class PresetSeeder extends Seeder
{
/**
- * Run the migrations.
+ * Run the database seeds.
*
* @return void
*/
- public function up()
+ public function run()
{
- // 生成初始管理账号
- User::create([
- 'username' => '管理员',
- 'email' => 'test@test.com',
- 'password' => '123456',
- 'port' => 10000,
- 'passwd' => Str::random(),
- 'vmess_id' => Str::uuid(),
- 'is_admin' => 1,
- ]);
-
- // 生成最初的等级
- Level::insert(['level' => 0, 'name' => 'Free']);
- for ($i = 1; $i < 8; $i++) {
- Level::insert(['level' => $i, 'name' => 'VIP-'.$i]);
- }
-
- // ss系列 加密方式
- SsConfig::insert(['name' => 'none', 'type' => 1, 'is_default' => 1]);
- SsConfig::insert(['name' => 'rc4-md5']);
- SsConfig::insert(['name' => 'aes-128-cfb']);
- SsConfig::insert(['name' => 'aes-192-cfb']);
- SsConfig::insert(['name' => 'aes-256-cfb']);
- SsConfig::insert(['name' => 'aes-128-ctr']);
- SsConfig::insert(['name' => 'aes-192-ctr']);
- SsConfig::insert(['name' => 'aes-256-ctr']);
- SsConfig::insert(['name' => 'aes-128-gcm']);
- SsConfig::insert(['name' => 'aes-192-gcm']);
- SsConfig::insert(['name' => 'aes-256-gcm']);
- SsConfig::insert(['name' => 'bf-cfb']);
- SsConfig::insert(['name' => 'cast5-cfb']);
- SsConfig::insert(['name' => 'des-cfb']);
- SsConfig::insert(['name' => 'salsa20']);
- SsConfig::insert(['name' => 'chacha20']);
- SsConfig::insert(['name' => 'chacha20-ietf']);
- SsConfig::insert(['name' => 'chacha20-ietf-poly1305']);
-
- // ss系列 协议
- SsConfig::insert(['name' => 'origin', 'type' => 2, 'is_default' => 1]);
- SsConfig::insert(['name' => 'auth_sha1_v4', 'type' => 2]);
- SsConfig::insert(['name' => 'auth_aes128_md5', 'type' => 2]);
- SsConfig::insert(['name' => 'auth_aes128_sha1', 'type' => 2]);
- SsConfig::insert(['name' => 'auth_chain_a', 'type' => 2]);
- SsConfig::insert(['name' => 'auth_chain_b', 'type' => 2]);
- SsConfig::insert(['name' => 'auth_chain_c', 'type' => 2]);
- SsConfig::insert(['name' => 'auth_chain_d', 'type' => 2]);
- SsConfig::insert(['name' => 'auth_chain_e', 'type' => 2]);
- SsConfig::insert(['name' => 'auth_chain_f', 'type' => 2]);
-
- // ss系列 混淆
- SsConfig::insert(['name' => 'plain', 'type' => 3, 'is_default' => 1]);
- SsConfig::insert(['name' => 'http_simple', 'type' => 3]);
- SsConfig::insert(['name' => 'http_post', 'type' => 3]);
- SsConfig::insert(['name' => 'tls1.2_ticket_auth', 'type' => 3]);
- SsConfig::insert(['name' => 'tls1.2_ticket_fastauth', 'type' => 3]);
-
+ // 系统参数
$configList = [
'is_rand_port',
'is_user_rand_port',
@@ -198,49 +143,94 @@ class PresetData extends Migration
}
$presetDates = [
- 'invite_num' => 3,
- 'is_register' => 1,
- 'is_invite_register' => 2,
- 'website_name' => 'ProxyPanel',
- 'is_reset_password' => 1,
- 'reset_password_times' => 3,
- 'website_url' => 'https://demo.proxypanel.ml',
- 'active_times' => 3,
- 'is_checkin' => 1,
- 'min_rand_traffic' => 10,
- 'max_rand_traffic' => 500,
- 'traffic_limit_time' => 1440,
- 'referral_traffic' => 1024,
- 'referral_percent' => 0.2,
- 'referral_money' => 100,
- 'referral_status' => 1,
- 'default_traffic' => 1024,
+ 'invite_num' => 3,
+ 'is_register' => 1,
+ 'is_invite_register' => 2,
+ 'website_name' => 'ProxyPanel',
+ 'is_reset_password' => 1,
+ 'reset_password_times' => 3,
+ 'website_url' => 'https://demo.proxypanel.ml',
+ 'active_times' => 3,
+ 'is_checkin' => 1,
+ 'min_rand_traffic' => 10,
+ 'max_rand_traffic' => 500,
+ 'traffic_limit_time' => 1440,
+ 'referral_traffic' => 1024,
+ 'referral_percent' => 0.2,
+ 'referral_money' => 100,
+ 'referral_status' => 1,
+ 'default_traffic' => 1024,
'traffic_warning_percent' => 80,
- 'expire_days' => 15,
- 'reset_traffic' => 1,
- 'default_days' => 7,
- 'subscribe_max' => 3,
- 'min_port' => 10000,
- 'max_port' => 65535,
- 'is_traffic_ban' => 1,
- 'traffic_ban_value' => 10,
- 'traffic_ban_time' => 60,
- 'is_clear_log' => 1,
- 'is_subscribe_ban' => 1,
- 'subscribe_ban_times' => 20,
- 'auto_release_port' => 1,
- 'register_ip_limit' => 5,
- 'detection_check_times' => 3,
- 'alipay_transport' => 'http',
- 'alipay_currency' => 'USD',
- 'user_invite_days' => 7,
- 'admin_invite_days' => 7,
+ 'expire_days' => 15,
+ 'reset_traffic' => 1,
+ 'default_days' => 7,
+ 'subscribe_max' => 3,
+ 'min_port' => 10000,
+ 'max_port' => 65535,
+ 'is_traffic_ban' => 1,
+ 'traffic_ban_value' => 10,
+ 'traffic_ban_time' => 60,
+ 'is_clear_log' => 1,
+ 'is_subscribe_ban' => 1,
+ 'subscribe_ban_times' => 20,
+ 'auto_release_port' => 1,
+ 'register_ip_limit' => 5,
+ 'detection_check_times' => 3,
+ 'alipay_transport' => 'http',
+ 'alipay_currency' => 'USD',
+ 'user_invite_days' => 7,
+ 'admin_invite_days' => 7,
];
foreach ($presetDates as $key => $value) {
Config::find($key)->update(['value' => $value]);
}
+ // 生成最初的等级
+ Level::insert(['level' => 0, 'name' => 'Free']);
+ for ($i = 1; $i < 8; $i++) {
+ Level::insert(['level' => $i, 'name' => 'VIP-'.$i]);
+ }
+
+ // ss系列 加密方式
+ SsConfig::insert(['name' => 'none', 'type' => 1, 'is_default' => 1]);
+ SsConfig::insert(['name' => 'rc4-md5']);
+ SsConfig::insert(['name' => 'aes-128-cfb']);
+ SsConfig::insert(['name' => 'aes-192-cfb']);
+ SsConfig::insert(['name' => 'aes-256-cfb']);
+ SsConfig::insert(['name' => 'aes-128-ctr']);
+ SsConfig::insert(['name' => 'aes-192-ctr']);
+ SsConfig::insert(['name' => 'aes-256-ctr']);
+ SsConfig::insert(['name' => 'aes-128-gcm']);
+ SsConfig::insert(['name' => 'aes-192-gcm']);
+ SsConfig::insert(['name' => 'aes-256-gcm']);
+ SsConfig::insert(['name' => 'bf-cfb']);
+ SsConfig::insert(['name' => 'cast5-cfb']);
+ SsConfig::insert(['name' => 'des-cfb']);
+ SsConfig::insert(['name' => 'salsa20']);
+ SsConfig::insert(['name' => 'chacha20']);
+ SsConfig::insert(['name' => 'chacha20-ietf']);
+ SsConfig::insert(['name' => 'chacha20-ietf-poly1305']);
+
+ // ss系列 协议
+ SsConfig::insert(['name' => 'origin', 'type' => 2, 'is_default' => 1]);
+ SsConfig::insert(['name' => 'auth_sha1_v4', 'type' => 2]);
+ SsConfig::insert(['name' => 'auth_aes128_md5', 'type' => 2]);
+ SsConfig::insert(['name' => 'auth_aes128_sha1', 'type' => 2]);
+ SsConfig::insert(['name' => 'auth_chain_a', 'type' => 2]);
+ SsConfig::insert(['name' => 'auth_chain_b', 'type' => 2]);
+ SsConfig::insert(['name' => 'auth_chain_c', 'type' => 2]);
+ SsConfig::insert(['name' => 'auth_chain_d', 'type' => 2]);
+ SsConfig::insert(['name' => 'auth_chain_e', 'type' => 2]);
+ SsConfig::insert(['name' => 'auth_chain_f', 'type' => 2]);
+
+ // ss系列 混淆
+ SsConfig::insert(['name' => 'plain', 'type' => 3, 'is_default' => 1]);
+ SsConfig::insert(['name' => 'http_simple', 'type' => 3]);
+ SsConfig::insert(['name' => 'http_post', 'type' => 3]);
+ SsConfig::insert(['name' => 'tls1.2_ticket_auth', 'type' => 3]);
+ SsConfig::insert(['name' => 'tls1.2_ticket_fastauth', 'type' => 3]);
+
// 节点用标签
$labelList = [
'Netflix',
@@ -499,39 +489,32 @@ class PresetData extends Migration
// 审核规则
$ruleList = [
- '360' => '(.*.||)(^360|0360|1360|3600|360safe|^so|qhimg|qhmsg|^yunpan|qihoo|qhcdn|qhupdate|360totalsecurity|360shouji|qihucdn|360kan|secmp).(cn|com|net)',
- '腾讯管家' => '(.guanjia.qq.com|qqpcmgr|QQPCMGR)',
- '金山毒霸' => '(.*.||)(rising|kingsoft|duba|xindubawukong|jinshanduba).(com|net|org)',
- '暗网相关' => '(.*.||)(netvigator|torproject).(cn|com|net|org)',
- '百度定位' => '(api|ps|sv|offnavi|newvector|ulog.imap|newloc|tracknavi)(.map|).(baidu|n.shifen).com',
- '法轮功类' => '(.*.||)(dafahao|minghui|dongtaiwang|dajiyuan|falundata|shenyun|tuidang|epochweekly|epochtimes|ntdtv|falundafa|wujieliulan|zhengjian).(org|com|net)',
- 'BT扩展名' => '(torrent|.torrent|peer_id=|info_hash|get_peers|find_node|BitTorrent|announce_peer|announce.php?passkey=)',
- '邮件滥发' => '((^.*@)(guerrillamail|guerrillamailblock|sharklasers|grr|pokemail|spam4|bccto|chacuo|027168).(info|biz|com|de|net|org|me|la)|Subject|HELO|SMTP)',
- '迅雷下载' => '(.?)(xunlei|sandai|Thunder|XLLiveUD)(.)',
- '大陆应用' => '(.*.||)(baidu|qq|163|189|10000|10010|10086|sohu|sogoucdn|sogou|uc|58|taobao|qpic|bilibili|hdslb|acgvideo|sina|douban|doubanio|xiaohongshu|sinaimg|weibo|xiaomi|youzanyun|meituan|dianping|biliapi|huawei|pinduoduo|cnzz).(org|com|net|cn)',
- '大陆银行' => '(.*.||)(icbc|ccb|boc|bankcomm|abchina|cmbchina|psbc|cebbank|cmbc|pingan|spdb|citicbank|cib|hxb|bankofbeijing|hsbank|tccb|4001961200|bosc|hkbchina|njcb|nbcb|lj-bank|bjrcb|jsbchina|gzcb|cqcbank|czbank|hzbank|srcb|cbhb|cqrcb|grcbank|qdccb|bocd|hrbcb|jlbank|bankofdl|qlbchina|dongguanbank|cscb|hebbank|drcbank|zzbank|bsb|xmccb|hljrcc|jxnxs|gsrcu|fjnx|sxnxs|gx966888|gx966888|zj96596|hnnxs|ahrcu|shanxinj|hainanbank|scrcu|gdrcu|hbxh|ynrcc|lnrcc|nmgnxs|hebnx|jlnls|js96008|hnnx|sdnxs).(org|com|net|cn)',
- '台湾银行' => '(.*.||)(firstbank|bot|cotabank|megabank|tcb-bank|landbank|hncb|bankchb|tbb|ktb|tcbbank|scsb|bop|sunnybank|kgibank|fubon|ctbcbank|cathaybk|eximbank|bok|ubot|feib|yuantabank|sinopac|esunbank|taishinbank|jihsunbank|entiebank|hwataibank|csc|skbank).(org|com|net|tw)',
+ '360' => '(.*.||)(^360|0360|1360|3600|360safe|^so|qhimg|qhmsg|^yunpan|qihoo|qhcdn|qhupdate|360totalsecurity|360shouji|qihucdn|360kan|secmp).(cn|com|net)',
+ '腾讯管家' => '(.guanjia.qq.com|qqpcmgr|QQPCMGR)',
+ '金山毒霸' => '(.*.||)(rising|kingsoft|duba|xindubawukong|jinshanduba).(com|net|org)',
+ '暗网相关' => '(.*.||)(netvigator|torproject).(cn|com|net|org)',
+ '百度定位' => '(api|ps|sv|offnavi|newvector|ulog.imap|newloc|tracknavi)(.map|).(baidu|n.shifen).com',
+ '法轮功类' => '(.*.||)(dafahao|minghui|dongtaiwang|dajiyuan|falundata|shenyun|tuidang|epochweekly|epochtimes|ntdtv|falundafa|wujieliulan|zhengjian).(org|com|net)',
+ 'BT扩展名' => '(torrent|.torrent|peer_id=|info_hash|get_peers|find_node|BitTorrent|announce_peer|announce.php?passkey=)',
+ '邮件滥发' => '((^.*@)(guerrillamail|guerrillamailblock|sharklasers|grr|pokemail|spam4|bccto|chacuo|027168).(info|biz|com|de|net|org|me|la)|Subject|HELO|SMTP)',
+ '迅雷下载' => '(.?)(xunlei|sandai|Thunder|XLLiveUD)(.)',
+ '大陆应用' => '(.*.||)(baidu|qq|163|189|10000|10010|10086|sohu|sogoucdn|sogou|uc|58|taobao|qpic|bilibili|hdslb|acgvideo|sina|douban|doubanio|xiaohongshu|sinaimg|weibo|xiaomi|youzanyun|meituan|dianping|biliapi|huawei|pinduoduo|cnzz).(org|com|net|cn)',
+ '大陆银行' => '(.*.||)(icbc|ccb|boc|bankcomm|abchina|cmbchina|psbc|cebbank|cmbc|pingan|spdb|citicbank|cib|hxb|bankofbeijing|hsbank|tccb|4001961200|bosc|hkbchina|njcb|nbcb|lj-bank|bjrcb|jsbchina|gzcb|cqcbank|czbank|hzbank|srcb|cbhb|cqrcb|grcbank|qdccb|bocd|hrbcb|jlbank|bankofdl|qlbchina|dongguanbank|cscb|hebbank|drcbank|zzbank|bsb|xmccb|hljrcc|jxnxs|gsrcu|fjnx|sxnxs|gx966888|gx966888|zj96596|hnnxs|ahrcu|shanxinj|hainanbank|scrcu|gdrcu|hbxh|ynrcc|lnrcc|nmgnxs|hebnx|jlnls|js96008|hnnx|sdnxs).(org|com|net|cn)',
+ '台湾银行' => '(.*.||)(firstbank|bot|cotabank|megabank|tcb-bank|landbank|hncb|bankchb|tbb|ktb|tcbbank|scsb|bop|sunnybank|kgibank|fubon|ctbcbank|cathaybk|eximbank|bok|ubot|feib|yuantabank|sinopac|esunbank|taishinbank|jihsunbank|entiebank|hwataibank|csc|skbank).(org|com|net|tw)',
'大陆第三方支付' => '(.*.||)(alipay|baifubao|yeepay|99bill|95516|51credit|cmpay|tenpay|lakala|jdpay).(org|com|net|cn)',
- '台湾特供' => '(.*.||)(visa|mycard|mastercard|gov|gash|beanfun|bank|line).(org|com|net|cn|tw|jp|kr)',
- '涉政治类' => '(.*.||)(shenzhoufilm|secretchina|renminbao|aboluowang|mhradio|guangming|zhengwunet|soundofhope|yuanming|zhuichaguoji|fgmtv|xinsheng|shenyunperformingarts|epochweekly|tuidang|shenyun|falundata|bannedbook|pincong|rfi|mingjingnews|boxun|rfa|scmp|ogate|voachinese).(org|com|net|rocks|fr)',
- '流媒体' => '(.*.||)(youtube|googlevideo|hulu|netflix|nflxvideo|akamai|nflximg|hbo|mtv|bbc|tvb).(org|club|com|net|tv)',
- '测速类' => '(.*.||)(fast|speedtest).(org|com|net|cn)',
- '外汇交易类' => '(.*.||)(metatrader4|metatrader5|mql5).(org|com|net)',
+ '台湾特供' => '(.*.||)(visa|mycard|mastercard|gov|gash|beanfun|bank|line).(org|com|net|cn|tw|jp|kr)',
+ '涉政治类' => '(.*.||)(shenzhoufilm|secretchina|renminbao|aboluowang|mhradio|guangming|zhengwunet|soundofhope|yuanming|zhuichaguoji|fgmtv|xinsheng|shenyunperformingarts|epochweekly|tuidang|shenyun|falundata|bannedbook|pincong|rfi|mingjingnews|boxun|rfa|scmp|ogate|voachinese).(org|com|net|rocks|fr)',
+ '流媒体' => '(.*.||)(youtube|googlevideo|hulu|netflix|nflxvideo|akamai|nflximg|hbo|mtv|bbc|tvb).(org|club|com|net|tv)',
+ '测速类' => '(.*.||)(fast|speedtest).(org|com|net|cn)',
+ '外汇交易类' => '(.*.||)(metatrader4|metatrader5|mql5).(org|com|net)',
];
foreach ($ruleList as $name => $pattern) {
Rule::insert(['type' => 1, 'name' => $name, 'pattern' => $pattern]);
}
- }
- /**
- * Reverse the migrations.
- *
- * @return void
- */
- public function down()
- {
- echo 'plz run php artisan migrate:fresh'.PHP_EOL;
- echo '请运行 php artisan migrate:fresh'.PHP_EOL;
+ // 生成初始管理账号
+ $user = factory(User::class)->create(['username' => '管理员', 'email' => 'test@test.com', 'password' => '123456']);
+ $user->assignRole('Super Admin');
}
}
diff --git a/public/downloads/convert.json b/public/downloads/convert.json
deleted file mode 100644
index e69de29b..00000000
diff --git a/resources/views/admin/aff/detail.blade.php b/resources/views/admin/aff/detail.blade.php
index 0897498e..7aa30f51 100644
--- a/resources/views/admin/aff/detail.blade.php
+++ b/resources/views/admin/aff/detail.blade.php
@@ -8,9 +8,9 @@