mirror of
https://github.com/lkddi/Xboard.git
synced 2026-04-14 19:40:53 +08:00
feat: enhance user management and system optimization
New Features: - Add bulk ban and email notification in user management - Add CSV export for batch coupon generation - Optimize subscription description template Bug Fixes: - Fix knowledge base pagination issue - Fix permission group filtering in node management - Fix unauthorized order placement for free subscription periods
This commit is contained in:
@@ -15,6 +15,7 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
@@ -243,7 +244,7 @@ class UserController extends Controller
|
||||
try {
|
||||
$user->update($params);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
Log::error($e);
|
||||
return $this->fail([500, '保存失败']);
|
||||
}
|
||||
return $this->success(true);
|
||||
@@ -251,8 +252,9 @@ class UserController extends Controller
|
||||
|
||||
public function dumpCSV(Request $request)
|
||||
{
|
||||
ini_set('memory_limit', -1);
|
||||
$userModel = User::orderBy('id', 'asc');
|
||||
$this->filter($request, $userModel);
|
||||
$this->applyFiltersAndSorts($request, $userModel);
|
||||
$res = $userModel->get();
|
||||
$plan = Plan::get();
|
||||
for ($i = 0; $i < count($res); $i++) {
|
||||
@@ -341,7 +343,7 @@ class UserController extends Controller
|
||||
DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
\Log::error($e);
|
||||
Log::error($e);
|
||||
return $this->fail([500, '生成失败']);
|
||||
}
|
||||
$data = "账号,密码,过期时间,UUID,创建时间,订阅地址\r\n";
|
||||
@@ -357,11 +359,13 @@ class UserController extends Controller
|
||||
|
||||
public function sendMail(UserSendMail $request)
|
||||
{
|
||||
ini_set('memory_limit', '-1');
|
||||
$sortType = in_array($request->input('sort_type'), ['ASC', 'DESC']) ? $request->input('sort_type') : 'DESC';
|
||||
$sort = $request->input('sort') ? $request->input('sort') : 'created_at';
|
||||
$builder = User::orderBy($sort, $sortType);
|
||||
$this->filter($request, $builder);
|
||||
$this->applyFilters($request, $builder);
|
||||
$users = $builder->get();
|
||||
return $this->success($users->count());
|
||||
foreach ($users as $user) {
|
||||
SendEmailJob::dispatch(
|
||||
[
|
||||
@@ -386,13 +390,13 @@ class UserController extends Controller
|
||||
$sortType = in_array($request->input('sort_type'), ['ASC', 'DESC']) ? $request->input('sort_type') : 'DESC';
|
||||
$sort = $request->input('sort') ? $request->input('sort') : 'created_at';
|
||||
$builder = User::orderBy($sort, $sortType);
|
||||
$this->filter($request, $builder);
|
||||
$this->applyFilters($request, $builder);
|
||||
try {
|
||||
$builder->update([
|
||||
'banned' => 1
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
Log::error($e);
|
||||
return $this->fail([500, '处理失败']);
|
||||
}
|
||||
|
||||
@@ -425,7 +429,7 @@ class UserController extends Controller
|
||||
return $this->success(true);
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
\Log::error($e);
|
||||
Log::error($e);
|
||||
return $this->fail([500, '删除失败']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use Illuminate\Http\Resources\Json\JsonResource;
|
||||
class PlanResource extends JsonResource
|
||||
{
|
||||
private const PRICE_MULTIPLIER = 100;
|
||||
|
||||
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
@@ -23,7 +23,7 @@ class PlanResource extends JsonResource
|
||||
'id' => $this->resource['id'],
|
||||
'group_id' => $this->resource['group_id'],
|
||||
'name' => $this->resource['name'],
|
||||
'content' => $this->resource['content'],
|
||||
'content' => $this->formatContent(),
|
||||
...$this->getPeriodPrices(),
|
||||
'capacity_limit' => $this->getFormattedCapacityLimit(),
|
||||
'transfer_enable' => $this->resource['transfer_enable'],
|
||||
@@ -49,8 +49,8 @@ class PlanResource extends JsonResource
|
||||
->mapWithKeys(function (string $newPeriod, string $legacyPeriod): array {
|
||||
$price = $this->resource['prices'][$newPeriod] ?? null;
|
||||
return [
|
||||
$legacyPeriod => $price !== null
|
||||
? (float) $price * self::PRICE_MULTIPLIER
|
||||
$legacyPeriod => $price !== null
|
||||
? (float) $price * self::PRICE_MULTIPLIER
|
||||
: null
|
||||
];
|
||||
})
|
||||
@@ -72,4 +72,49 @@ class PlanResource extends JsonResource
|
||||
default => (int) $limit,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format content with template variables
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function formatContent(): string
|
||||
{
|
||||
$content = $this->resource['content'];
|
||||
|
||||
$replacements = [
|
||||
'{{transfer}}' => $this->resource['transfer_enable'],
|
||||
'{{speed}}' => $this->resource['speed_limit'] === NULL ? __('No Limit') : $this->resource['speed_limit'],
|
||||
'{{devices}}' => $this->resource['device_limit'] === NULL ? __('No Limit') : $this->resource['device_limit'],
|
||||
'{{reset_method}}' => $this->getResetMethodText(),
|
||||
];
|
||||
|
||||
return str_replace(
|
||||
array_keys($replacements),
|
||||
array_values($replacements),
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reset method text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getResetMethodText(): string
|
||||
{
|
||||
$method = $this->resource['reset_traffic_method'];
|
||||
|
||||
if ($method === Plan::RESET_TRAFFIC_FOLLOW_SYSTEM) {
|
||||
$method = admin_setting('reset_traffic_method', Plan::RESET_TRAFFIC_MONTHLY);
|
||||
}
|
||||
return match ($method) {
|
||||
Plan::RESET_TRAFFIC_FIRST_DAY_MONTH => __('First Day of Month'),
|
||||
Plan::RESET_TRAFFIC_MONTHLY => __('Monthly'),
|
||||
Plan::RESET_TRAFFIC_NEVER => __('Never'),
|
||||
Plan::RESET_TRAFFIC_FIRST_DAY_YEAR => __('First Day of Year'),
|
||||
Plan::RESET_TRAFFIC_YEARLY => __('Yearly'),
|
||||
default => __('Monthly')
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ class AdminRoute
|
||||
$router->get('/getUserInfoById', [UserController::class, 'getUserInfoById']);
|
||||
$router->post('/generate', [UserController::class, 'generate']);
|
||||
$router->post('/dumpCSV', [UserController::class, 'dumpCSV']);
|
||||
$router->post('/user/sendMail', [UserController::class, 'sendMail']);
|
||||
$router->post('/sendMail', [UserController::class, 'sendMail']);
|
||||
$router->post('/ban', [UserController::class, 'ban']);
|
||||
$router->post('/resetSecret', [UserController::class, 'resetSecret']);
|
||||
$router->post('/setInviteUser', [UserController::class, 'setInviteUser']);
|
||||
|
||||
Reference in New Issue
Block a user