这是我参与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的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。