laravel ajax 收藏与取消收藏功能开发

laravel ajax 点赞与取消赞功能在很多的时候 应用非常广泛,同样的原理有产品的收藏功能,都是一个思路,接下来是我的代码,有很多的不足,仅用于参考。

点赞功能


点赞商品是电商网站一个常用的功能,本章节要实现收藏商品的基本功能。

1. 数据库结构


收藏商品本质上是用户和商品的多对多关联,因此不需要创建新的模型,只需要增加一个中间表即可:

$ php artisan make:migration create_user_fabulous_products_table --create=user_fabulous_products
注意:中间表命名,要越直白越好,名字长点也无所谓。一个简单的判断命名是否合格的方法是 —— 想象自己半年一年以后是否能快速地从数据库表名得知此表的功能。

database/migrations/< your_date >_create_user_fabulous_products_table.php

...
    public function up()
    {
        Schema::create('user_fabulous_products', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->unsignedInteger('product_id');
            $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
            $table->timestamps();
        });
    }...
这里我们保留了时间戳的字段,这是因为我们希望用户看到的点赞商品是按用户点赞时间排序的,所以需要有一个时间字段用于排序。

然后执行数据库迁移:

$ php artisan migrate

2. 模型文件增加关联


接下来我们在 User 模型中增加与商品的关联关系:

app/Models/User.php

...
    public function fabulousProducts()
    {
        return $this->belongsToMany(Product::class, 'user_fabulous_products')
            ->withTimestamps()
            ->orderBy('user_fabulous_products.created_at', 'desc');
    }...

代码解析:

belongsToMany() 方法用于定义一个多对多的关联,第一个参数是关联的模型类名,第二个参数是中间表的表名。

withTimestamps() 代表中间表带有时间戳字段。

orderBy('user_fabulous_products.created_at', 'desc') 代表默认的排序方式是根据中间表的创建时间倒序排序。

3. 控制器


接下来我们需要在 ProductsController 中新增点赞与取消赞的接口:

app/Http/Controllers/ProductsController.php

...
    public function fabulous(Product $product, Request $request)
    {
        $user = $request->user();
        if ($user->fabulousProducts()->find($product->id)) {
            return [];
        }

        $user->fabulousProducts()->attach($product);

        return [];
    }...

这段代码先是判断当前用户是否已经点赞了此商品,如果已经点赞则不做任何操作直接返回,否则通过 attach() 方法将当前用户和此商品关联起来.

attach() 方法的参数可以是模型的 id,也可以是模型对象本身,因此这里还可以写成 attach($product->id)。

然后是取消点赞的接口:

app/Http/Controllers/ProductsController.php

...
    public function disfabulous(Product $product, Request $request)
    {
        $user = $request->user();
        $user->fabulousProducts()->detach($product);

        return [];
    }...

detach() 方法用于取消多对多的关联,接受的参数个数与 attach() 方法一致。

4. 路由


接下来把这两个接口添加到路由中:

routes/web.php

...Route::group(['middleware' => 'auth'], function() {...
    Route::group(['middleware' => 'email_verified'], function() {
        .
        .
        .
        Route::post('products/{product}/fabulous', 'ProductsController@fabulous')->name('products.fabulous');
        Route::delete('products/{product}/fabulous', 'ProductsController@disfabulous')->name('products.disfabulous');
    });});

5. 『点赞』按钮


接下来我们需要在前端模板页面实现『点赞』按钮的功能:

resources/views/products/show.blade.php

6. 『详情页面-点赞-取消攒』 按钮


接下来我们要在页面添加按钮及其功能,对于已经点赞了当前商品的用户,我们不展示 按钮,而展示 取消赞 按钮,因此需要在控制器中把收藏状态注入到模板中:

app/Http/Controllers/ProductsController.php

...
    public function show(Product $product,Request $request)
    {
        // 判断商品是否已经上架,如果没有上架则抛出异常。
        if(!$product->on_sale){
            throw new InvalidRequestException('商品未上架');
        }
        $fabulous = false;
        // 用户未登录时返回的是 null,已登录时返回的是对应的用户对象
        if($user = $request->user()){
            // 从当前用户已收藏的商品中搜索 id 为当前商品 id 的商品
            // boolval() 函数用于把值转为布尔值
            $fabulous = boolval($user->fabulousProducts()->find($product->id));
        }
        $zancount = \DB::table('user_fabulous_products')->where('product_id',$product->id)->count();
        return view('products.show',[
            'product'=>$product,
            'fabulous'=>$fabulous,
            'zancount'=>$zancount,
        ]);
    }...

有了 $fabulous 这个变量之后,我们在模板里加上判断:

resources/views/products/show.blade.php

...
   @guest
   @else
   
@if($fabulous) @else @endif {{$zancount}} +1
... @endguest
1:在加载详情页面的时候 会检查用户是否登录,如果未登录将不现实点赞按钮。
2:js原理:获取当前点赞图片src参数 并进行比较,如果是点赞图片image/zan.png将进行点赞功能,如果不是就发送取消赞 信息。

7. 点赞按钮-CSS


这样就将文章点赞功能完成了。本文参考与《L05 Laravel 教程 - 电商实战》5.7收藏商品章节https://laravel-china.org/courses/laravel-shop/1562/collection-of-goods

读书破万卷,下笔如有神.

评论

返回顶部