visuddhinanda 2 роки тому
батько
коміт
e7d9dda865

+ 129 - 0
app/Http/Controllers/InviteController.php

@@ -0,0 +1,129 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Models\Invite;
+use App\Models\UserInfo;
+use Illuminate\Http\Request;
+use App\Http\Api\AuthApi;
+use App\Http\Api\StudioApi;
+use App\Http\Resources\InviteResource;
+use Illuminate\Support\Str;
+use Mail;
+use App\Mail\InviteMail;
+
+class InviteController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index(Request $request)
+    {
+        //
+        $table = Invite::select(['id','user_uid','email',
+                                 'status','created_at','updated_at']);
+        switch ($request->get('view')) {
+            case 'studio':
+                $user = AuthApi::current($request);
+                if(!$user){
+                    return $this->error(__('auth.failed'));
+                }
+                //判断当前用户是否有指定的studio的权限
+                if($user['user_uid'] !== StudioApi::getIdByName($request->get('studio'))){
+                    return $this->error(__('auth.failed'));
+                }
+                $table = $table->where('user_uid', $user["user_uid"]);
+                break;
+        }
+        if($request->has('search')){
+            $table = $table->where('email', 'like', '%'.$request->get('search')."%");
+        }
+        $count = $table->count();
+        $table = $table->orderBy($request->get('order','updated_at'),
+                                 $request->get('dir','desc'));
+
+        $table = $table->skip($request->get('offset',0))
+                       ->take($request->get('limit',1000));
+
+        $result = $table->get();
+        return $this->ok(["rows"=>InviteResource::collection($result),"count"=>$count]);
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return \Illuminate\Http\Response
+     */
+    public function store(Request $request)
+    {
+        //
+        $user = AuthApi::current($request);
+        if(!$user){
+            return $this->error(__('auth.failed'));
+        }
+        //判断当前用户是否有指定的studio的权限
+        $studio_id = StudioApi::getIdByName($request->get('studio'));
+        if($user['user_uid'] !== $studio_id){
+            return $this->error(__('auth.failed'));
+        }
+        //查询是否重复
+        if(Invite::where('email',$request->get('email'))->exists() ||
+            UserInfo::where('email',$request->get('email'))->exists()){
+            return $this->error(__('validation.exists',['email']),[],200);
+        }
+
+
+        Mail::to($request->get('email'))
+            ->send(new InviteMail());
+        if(Mail::failures()){
+            return $this->error('send email fail',[],200);
+        }else{
+            $invite = new Invite;
+            $invite->id = Str::uuid();
+            $invite->email = $request->get('email');
+            $invite->user_uid = $user['user_uid'];
+            $invite->status = 'invited';
+            $invite->save();
+        }
+        return $this->ok(new InviteResource($invite));
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  \App\Models\Invite  $invite
+     * @return \Illuminate\Http\Response
+     */
+    public function show(Invite $invite)
+    {
+        //
+        return $this->ok(new InviteResource($invite));
+
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\Models\Invite  $invite
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, Invite $invite)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\Models\Invite  $invite
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(Invite $invite)
+    {
+        //
+    }
+}

+ 19 - 0
app/Http/Resources/InviteResource.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class InviteResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
+     */
+    public function toArray($request)
+    {
+        return parent::toArray($request);
+    }
+}

+ 40 - 0
app/Mail/InviteMail.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Mail;
+
+use App\Models\Invite;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Mail\Mailable;
+use Illuminate\Queue\SerializesModels;
+
+class InviteMail extends Mailable
+{
+    use Queueable, SerializesModels;
+
+    protected $invite;
+    /**
+     * Create a new message instance.
+     *
+     * @return void
+     */
+    public function __construct(string $uuid)
+    {
+        //
+        $this->invite = $uuid;
+    }
+
+    /**
+     * Build the message.
+     *
+     * @return $this
+     */
+    public function build()
+    {
+        return $this->view('emails.invite')
+                    ->with([
+                        'url' => env('APP_URL').'/anonymous/users/sign-up/'.$this->invite,
+                        'uuid' => $this->invite,
+                    ]);
+    }
+}

+ 11 - 0
app/Models/Invite.php

@@ -0,0 +1,11 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class Invite extends Model
+{
+    use HasFactory;
+}

+ 34 - 0
database/migrations/2023_07_10_111723_create_invites_table.php

@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateInvitesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('invites', function (Blueprint $table) {
+            $table->uuid("id")->primary();
+            $table->uuid("user_uid")->index();
+            $table->string('email',256)->unique();
+            $table->string('status',63)->index();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('invites');
+    }
+}

+ 12 - 0
resources/views/emails/invite.blade.php

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>invite</title>
+</head>
+<body>
+wikipali 注册邀请
+点击此链接注册wikipali账号。此链接邀请只可以注册一个账户。有效期7天。
+<a href='{{ $url }}{{ $uuid }}'>{{ $url }}{{ $uuid }}</a><br>
+此邮件为系统自动发送,请勿回复。
+</body>
+</html>

+ 24 - 0
tests/Feature/InviteTest.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace Tests\Feature;
+
+use Illuminate\Foundation\Testing\RefreshDatabase;
+use Illuminate\Foundation\Testing\WithFaker;
+use Tests\TestCase;
+
+class InviteTest extends TestCase
+{
+    /**
+     * A basic feature test example.
+     *
+     * @return void
+     */
+    public function test_index()
+    {
+        $response = $this->withHeaders([
+            'Authorization' => env('TEST_USER_TOKEN'),
+        ])->get('/api/v2/invite?view=studio&studio=visuddhinanda');
+
+        $response->assertOk();
+    }
+}