MemberController.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <?php
  2. namespace Longyi\Member\Http\Controllers\Admin;
  3. use Illuminate\Http\JsonResponse;
  4. use Illuminate\Http\RedirectResponse;
  5. use Illuminate\Http\Request;
  6. use Illuminate\View\View;
  7. use Longyi\Member\DataGrids\Member\MemberDataGrid;
  8. use Longyi\Member\Imports\MemberPlusSpreadsheet;
  9. use Longyi\Member\Services\MemberPlusImportException;
  10. use Longyi\Member\Services\MemberPlusImportService;
  11. use Longyi\Member\Services\MemberPlusStatisticsService;
  12. use Maatwebsite\Excel\Facades\Excel;
  13. use Webkul\Admin\Http\Controllers\Controller;
  14. class MemberController extends Controller
  15. {
  16. /**
  17. * Create a new controller instance.
  18. */
  19. public function __construct(
  20. protected MemberPlusImportService $importService,
  21. protected MemberPlusStatisticsService $statisticsService
  22. ) {}
  23. /**
  24. * Display a listing of the resource.
  25. */
  26. public function index(): View|JsonResponse
  27. {
  28. if (request()->ajax()) {
  29. return datagrid(MemberDataGrid::class)->process();
  30. }
  31. return view('member::admin.index');
  32. }
  33. /**
  34. * Plus 会员统计:新增 / 过期。
  35. */
  36. public function statistics(Request $request): JsonResponse
  37. {
  38. $request->validate([
  39. 'start' => ['nullable', 'date'],
  40. 'end' => ['nullable', 'date'],
  41. ]);
  42. $end = $request->date('end') ?? now();
  43. $start = $request->date('start') ?? $end->copy()->subDays(29);
  44. return new JsonResponse($this->statisticsService->get($start, $end));
  45. }
  46. /**
  47. * 批量导入 Plus 会员(邮箱 + 过期天数)。
  48. */
  49. public function import(Request $request): RedirectResponse
  50. {
  51. $request->validate([
  52. 'import_file' => [
  53. 'required',
  54. 'file',
  55. 'extensions:xlsx,xls,csv',
  56. 'mimetypes:text/csv,text/plain,application/csv,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  57. 'max:10240',
  58. ],
  59. ]);
  60. try {
  61. $sheets = Excel::toArray(new MemberPlusSpreadsheet, $request->file('import_file'));
  62. $result = $this->importService->import($sheets[0] ?? []);
  63. } catch (MemberPlusImportException $e) {
  64. return $this->redirectToIndex('error', $e->getMessage());
  65. } catch (\Throwable $e) {
  66. return $this->redirectToIndex('error', trans('member::app.member.import.errors.generic', [
  67. 'message' => $this->sanitizeMessage($e->getMessage()),
  68. ]));
  69. }
  70. return redirect()
  71. ->route('admin.member.index')
  72. ->with('member_import_result', $result)
  73. ->with(
  74. $result['failed'] > 0 ? 'warning' : 'success',
  75. trans('member::app.member.import.summary', [
  76. 'updated' => $result['updated'],
  77. 'failed' => $result['failed'],
  78. 'skipped' => $result['skipped'],
  79. ])
  80. );
  81. }
  82. /**
  83. * 返回列表页并带上提示信息。
  84. */
  85. protected function redirectToIndex(string $type, string $message): RedirectResponse
  86. {
  87. return redirect()
  88. ->route('admin.member.index')
  89. ->with($type, $this->sanitizeMessage($message));
  90. }
  91. /**
  92. * 去掉会破坏前端提示脚本的引号与换行。
  93. */
  94. protected function sanitizeMessage(string $message): string
  95. {
  96. return trim(str_replace(['"', "\r", "\n"], ["'", ' ', ' '], $message));
  97. }
  98. }