laravel的地址管理restful api

这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战

一、地址管理

1.1 创建地址模型以及迁移文件

运行命令php artisan make:model Address -m 在这里插入图片描述 在迁移文件中创建表结构:

Schema::create('addresses', function (Blueprint $table) {
            $table->id();
            $table->integer('user_id')->comment('用户id');
            $table->string('name')->comment('收获人');
            $table->integer('city_id')->comment('city表中的id');
            $table->string('address')->comment('详细地址');
            $table->string('phone')->comment('手机号');
            $table->tinyInteger('is_default')->default(0)->comment('默认地址 0=>不是默认,1=>是默认');
            $table->timestamps();
            $table->index('user_id'); // 查询索引
        });
复制代码

在这里插入图片描述 运行命令php artisan migrate在这里插入图片描述


1.2 创建地址验证类

运行命令php artisan make:request Web/AddressRequest在这里插入图片描述 写入:

    public function rules()
    {
        return [
            'name' => 'required',
            'city_id' => [
                'required',
                function ($attribute, $value, $fail) {
                    $city = City::find($value);
                    if (empty($city)) $fail('城市不存在');
                },
            ],
            'address' => 'required',
            'phone' => 'required|regex:/^1[3-9]\d{9}$/',
        ];
    }

    /**
     * 提示消息
     */
    public function messages() {
        return [
            'name.required' => '收货人必填',
            'city_id.required' => '地址不能为空',
            'address.required' => '详细地址不能为空',
            'phone.required' => '手机号不能为空',
        ];
    }
复制代码

在这里插入图片描述


1.3 配置地址transform创建地址资源API控制器

给模型配置可批量插入的字段:

    use HasFactory;
    protected $fillable = ['user_id','name', 'phone', 'address', 'city_id', 'is_default'];
复制代码

在这里插入图片描述


City.php模型中写入查找父级的联动:

    /**
     * 查找父类
     */
    public function parent() {
        return $this->belongsTo(City::class, 'pid', 'id');
    }
复制代码

在这里插入图片描述

在辅助函数中写入根据区id查找上级联动数据:

    /**
     * 通过区ID 查询完整省市区数据
     */
    if (!function_exists('city_name')) {
        function city_name($city_id) {
            $city = City::where('id', $city_id)->with('parent.parent.parent')->first();
            // $str = $city['parent']['parent']['parent']['name'] ?? '';
            // $str .= $city['parent']['parent']['name'] ?? '';
            // $str .= $city['parent']['name'] ?? '';
            // $str .= $city['name'] ?? '';
            $str = [ 
                $city['parent']['parent']['parent']['name'] ?? '',
                $city['parent']['parent']['name'] ?? '',
                $city['parent']['name'] ?? '',
                $city['name'] ?? ''
            ];

            return trim(implode(' ', $str));
        }
    }
复制代码

在这里插入图片描述

创建AddressTransformer.php写入:

<?php 

namespace App\Transformers;

use App\Models\Address;
use League\Fractal\TransformerAbstract;

class AddressTransformer extends TransformerAbstract {
    public function transform(Address $address) {
        return [ 
            'id' => $address->id,
            'name' => $address->name,
            'city_id' => $address->city_id,
            'city_name' => city_name($address->city_id),
            'phone' => $address->phone,
            'address' => $address->address,
            'is_default' => $address->is_default,
            'created_at' => $address->created_at,
            'updated_at' => $address->updated_at,
        ];
    }
}
 
复制代码

在这里插入图片描述

运行命令php artisan make:controller Web/AddressController --api 在这里插入图片描述 写入增删改查以及是否默认方法:

<?php

namespace App\Http\Controllers\Web;

use App\Http\Controllers\BaseController;
use App\Http\Requests\Web\AddressRequest;
use App\Models\Address;
use App\Transformers\AddressTransformer;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class AddressController extends BaseController
{
    /**
     * 我的地址列表
     */
    public function index()
    {
        $address = Address::where('user_id', auth('api')->id())->get();
        return $this->response->collection($address, new AddressTransformer());
    }

    /**
     * 添加地址
     */
    public function store(AddressRequest $request)
    {
        Address::create([
            'user_id' => auth('api')->id(),
            'name' => $request->input('name'),
            'phone' => $request->input('phone'),
            'address' => $request->input('address'),
            'city_id' => $request->input('city_id'),
        ]);
        return $this->response->created();
    }

    /**
     * 地址详情
     */
    public function show(Address $address)
    {
        return $this->response->item($address, new AddressTransformer());
    }

    /**
     * 更新地址
     */
    public function update(AddressRequest $request, Address $address)
    {
        $address->update([
            'user_id' => auth('api')->id(),
            'name' => $request->input('name'),
            'phone' => $request->input('phone'),
            'address' => $request->input('address'),
            'city_id' => $request->input('city_id'),
            'is_default' => $request->input('is_default')
        ]);
        return $this->response->noContent();
    }

    /**
     * 删除地址
     */
    public function destroy(Address $address)
    {
        $address->delete();
        return $this->response->noContent();
    }

    /**
     * 默认地址
     */
    public function isDefault(Address $address)
    {
        if ($address->is_default == 1) { 
            return $this->response->noContent(); // 如果改地址已经设置默认地址 直接返回
        }
        try {
            DB::beginTransaction(); // 开启事物, 防止一个设置成功一个设置失败
            // 先把所有的地址都设置为非默认
            $default_address = Address::where('user_id', auth('api')->id())
                ->where('is_default', 1)
                ->first();
            if (!empty($default_address)) {
                
                $default_address->is_default = 0;
                $default_address->save();
            }
            // 在把当前的设置成默认
            $address->is_default = 1;
            $address->save();
            DB::commit();
            return $this->response->noContent();
        } catch (\Exception $e) {
            DB::rollback();
            throw $e;
        }
    }
}

复制代码

1.4 配置地址路由

 // 地址增删改查
        $api->resource('address', AddressController::class);
        // 设置默认地址
        $api->patch('address/{address}/default', [AddressController::class, 'isDefault']);
复制代码

在这里插入图片描述


1.5 订单地址修改

由于之前没有写地址相关的api,地址那块是模拟的假数据,现在把它修改过来:

// 地址数据
        $address = Address::where('user_id', auth('api')->id())
                    ->orderBy('is_default', 'desc')
                    ->get();

复制代码

在这里插入图片描述


还有一处地方就是在提交订单时候验证地址是否存在:

'address_id' => 'required|exixts:addresses,id'
复制代码

在这里插入图片描述


1.6 测试效果

1、添加地址 在这里插入图片描述

2、地址列表

在这里插入图片描述

3、修改地址 在这里插入图片描述

4、地址详情 在这里插入图片描述 5、删除地址 在这里插入图片描述 6、设置默认地址 在这里插入图片描述

在学习的php的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。

Guess you like

Origin juejin.im/post/7034681635912024094