关键代码示例:
/** @var MemberUser $user */
// 获取当前登录用户
$user = Auth::user(); // 返回 MemberUser 实例
// 获取用户关联的技师信息
$coach = $user->coach; // 返回 CoachUser 实例
// 常见的验证模式
abort_if(!$user->coach, 404, '技师信息不存在');
主要模型关系:
技师表认证状态字段:
ALTER TABLE coach_users
ADD COLUMN base_auth_status tinyint(1) COMMENT '基础信息认证状态 1:审核中 2:已通过 3:已拒绝',
ADD COLUMN real_name_auth_status tinyint(1) COMMENT '实名认证状态 1:审核中 2:已通过 3:已拒绝',
ADD COLUMN qualification_auth_status tinyint(1) COMMENT '资质认证状态 1:审核中 2:已通过 3:已拒绝',
ADD COLUMN base_auth_at timestamp NULL COMMENT '基础信息认证时间',
ADD COLUMN real_name_auth_at timestamp NULL COMMENT '实名认证时间',
ADD COLUMN qualification_auth_at timestamp NULL COMMENT '资质认证时间',
ADD COLUMN base_auth_remark varchar(255) NULL COMMENT '基础信息认证备注',
ADD COLUMN real_name_auth_remark varchar(255) NULL COMMENT '实名认证备注',
ADD COLUMN qualification_auth_remark varchar(255) NULL COMMENT '资质认证备注';
认证记录表:
-- 基础信息认证记录表
CREATE TABLE coach_base_auth_records (
id bigint unsigned NOT NULL AUTO_INCREMENT,
coach_id bigint unsigned NOT NULL COMMENT '技师ID',
name varchar(50) NOT NULL COMMENT '姓名',
mobile varchar(20) NOT NULL COMMENT '手机号',
id_card varchar(20) NOT NULL COMMENT '身份证号',
gender tinyint(1) NOT NULL COMMENT '性别 1:男 2:女',
birthday date NOT NULL COMMENT '出生日期',
address varchar(255) NOT NULL COMMENT '居住地址',
status tinyint(1) NOT NULL DEFAULT 1 COMMENT '状态 1:审核中 2:已通过 3:已拒绝',
remark varchar(255) NULL COMMENT '审核备注',
created_at timestamp NULL,
updated_at timestamp NULL,
PRIMARY KEY (id)
) COMMENT='技师基础信息认证记录表';
-- 实名认证记录表
CREATE TABLE coach_real_name_auth_records (
id bigint unsigned NOT NULL AUTO_INCREMENT,
coach_id bigint unsigned NOT NULL COMMENT '技师ID',
id_card_front varchar(255) NOT NULL COMMENT '身份证正面照',
id_card_back varchar(255) NOT NULL COMMENT '身份证背面照',
id_card_hand varchar(255) NOT NULL COMMENT '手持身份证照',
status tinyint(1) NOT NULL DEFAULT 1 COMMENT '状态 1:审核中 2:已通过 3:已拒绝',
remark varchar(255) NULL COMMENT '审核备注',
created_at timestamp NULL,
updated_at timestamp NULL,
PRIMARY KEY (id)
) COMMENT='技师实名认证记录表';
-- 资质认证记录表
CREATE TABLE coach_qualification_auth_records (
id bigint unsigned NOT NULL AUTO_INCREMENT,
coach_id bigint unsigned NOT NULL COMMENT '技师ID',
certificate_type tinyint(1) NOT NULL COMMENT '证书类型',
certificate_no varchar(50) NOT NULL COMMENT '证书编号',
certificate_image varchar(255) NOT NULL COMMENT '证书照片',
status tinyint(1) NOT NULL DEFAULT 1 COMMENT '状态 1:审核中 2:已通过 3:已拒绝',
remark varchar(255) NULL COMMENT '审核备注',
created_at timestamp NULL,
updated_at timestamp NULL,
PRIMARY KEY (id)
) COMMENT='技师资质认证记录表';
提交校验:
/**
* 检查是否可以提交认证
*/
public function canSubmitAuth(int $coachId, string $type): bool
{
$coach = CoachUser::find($coachId);
$status = match($type) {
'base' => $coach->base_auth_status,
'real_name' => $coach->real_name_auth_status,
'qualification' => $coach->qualification_auth_status,
};
// 审核中或已通过的状态下不允许重新提交
return !in_array($status, [
TechnicianAuthStatus::AUDITING, // 审核中
TechnicianAuthStatus::PASSED // 已通过
]);
}
提交认证:
/**
* 提交基础信息认证
*/
public function submitBaseAuth(int $coachId, array $data): void
{
// 检查是否可以提交
if (!$this->canSubmitAuth($coachId, 'base')) {
throw new BusinessException('当前状态不允许提交认证');
}
DB::transaction(function () use ($coachId, $data) {
// 1. 创建认证记录
$record = CoachBaseAuthRecord::create([
'coach_id' => $coachId,
'name' => $data['name'],
'mobile' => $data['mobile'],
// ... 其他字段
]);
// 2. 更新技师认证状态
CoachUser::where('id', $coachId)->update([
'base_auth_status' => TechnicianAuthStatus::AUDITING,
'base_auth_record_id' => $record->id
]);
// 3. 发送提交通知
event(new CoachAuthSubmitted($coachId, 'base'));
});
}
审核操作:
/**
* 审核基础信息认证
*/
public function auditBaseAuth(int $recordId, bool $passed, ?string $remark = null): void
{
DB::transaction(function () use ($recordId, $passed, $remark) {
// 1. 获取认证记录
$record = CoachBaseAuthRecord::findOrFail($recordId);
// 2. 更新认证记录状态
$status = $passed ? TechnicianAuthStatus::PASSED : TechnicianAuthStatus::REJECTED;
$record->update([
'status' => $status,
'remark' => $remark
]);
// 3. 更新技师认证状态
CoachUser::where('id', $record->coach_id)->update([
'base_auth_status' => $status,
'base_auth_remark' => $remark,
'base_auth_at' => $passed ? now() : null
]);
// 4. 如果通过,更新技师基本信息
if ($passed) {
CoachUser::where('id', $record->coach_id)->update([
'name' => $record->name,
'mobile' => $record->mobile,
// ... 其他字段
]);
}
// 5. 发送审核结果通知
event(new CoachAuthAudited($record->coach_id, 'base', $passed, $remark));
});
}
认证状态查询:
/**
* 获取认证状态
*/
public function getAuthStatus(int $coachId): array
{
$coach = CoachUser::find($coachId);
return [
'base' => [
'status' => $coach->base_auth_status,
'remark' => $coach->base_auth_remark,
'updated_at' => $coach->base_auth_at,
],
'real_name' => [
'status' => $coach->real_name_auth_status,
'remark' => $coach->real_name_auth_remark,
'updated_at' => $coach->real_name_auth_at,
],
'qualification' => [
'status' => $coach->qualification_auth_status,
'remark' => $coach->qualification_auth_remark,
'updated_at' => $coach->qualification_auth_at,
],
];
}
认证历史记录:
/**
* 获取认证历史记录
*/
public function getAuthHistory(int $coachId, string $type): Collection
{
$model = match($type) {
'base' => CoachBaseAuthRecord::class,
'real_name' => CoachRealNameAuthRecord::class,
'qualification' => CoachQualificationAuthRecord::class,
};
return $model::where('coach_id', $coachId)
->orderBy('id', 'desc')
->get();
}
验证方法:
/**
* 技师认证状态验证
*
* @param MemberUser $user 当前登录用户
* @throws BusinessException 认证未通过时抛出异常
*/
private function validateTechnicianAuth(MemberUser $user): void
{
// 验证技师是否存在
abort_if(!$user->coach, 404, '技师信息不存在');
$coach = $user->coach;
// 基础信息认证验证
if (!$coach->isBaseInfoVerified()) {
throw new BusinessException('请先完成基础信息认证');
}
// 实名认证验证
if (!$coach->isRealNameVerified()) {
throw new BusinessException('请先完成实名认证');
}
// 资质认证验证
if (!$coach->isQualificationVerified()) {
throw new BusinessException('请先完成资质认证');
}
}
使用说明:
TechnicianStatus: 技师状态
TechnicianAuthStatus: 认证状态
TechnicianWorkStatus: 工 �� 状态
TechnicianLocationType: 位置类型
OrderStatus: 订单状态
OrderType: 订单类型
OrderRecordStatus: 订单记录状态
/api/coach
前缀/api/coach/auth/*
/api/coach/orders/*
/api/coach/projects/*
/api/coach/wallet/*
标准 RESTful 路由:
// 订单相关路由示例
Route::prefix('api/coach')->group(function () {
// 订单列表
Route::get('orders', 'OrderController@index');
// 订单详情
Route::get('orders/{id}', 'OrderController@show');
// 接受订单
Route::post('orders/{id}/accept', 'OrderController@accept');
// 拒绝订单
Route::post('orders/{id}/reject', 'OrderController@reject');
// 开始服务
Route::post('orders/{id}/start', 'OrderController@start');
// 完成服务
Route::post('orders/{id}/finish', 'OrderController@finish');
});
请求头要求:
Accept: application/json
Content-Type: application/json
Authorization: Bearer {token}
分页查询参数:
{
"page": 1, // 当前页码
"per_page": 15, // 每页数量
"order_by": "created_at", // 排序字段
"order_type": "desc" // 排序方式
}
响应格式:
{
"code": 0, // 业务状态码
"message": "success", // 状态描述
"data": {
// 响应数据
"items": [
// 列表数据
{
"id": 1,
"order_no": "O202401010001",
"status": 1,
"created_at": "2024-01-01 00:00:00"
}
],
"total": 100 // 总记录数
}
}
错误响应格式:
{
"code": 422, // HTTP状态码
"message": "验证失败", // 错误描述
"errors": {
// 详细错误信息
"field": ["错误描述1", "错误描述2"]
}
}
分页查询参数:
{
"page": 1, // 当前页码
"per_page": 15, // 每页数量
"order_by": "created_at", // 排序字段
"order_type": "desc" // 排序方式
}
文档注解要求:
/**
* 获取订单列表
*
* @group 订单管理
*
* @queryParam page int 页码 Example: 1
* @queryParam per_page int 每页数量 Example: 15
* @queryParam status int 订单状态 Example: 1
*
* @response {
* "code": 0,
* "message": "success",
* "data": {
* "items": [
* {
* "id": 1,
* "order_no": "O202401010001",
* "status": 1,
* "created_at": "2024-01-01 00:00:00"
* }
* ],
* "total": 100
* }
* }
*/
版本控制:
控制器命名:
class OrderController extends Controller
{
// 获取订单列表
public function index()
// 获取订单详情
public function show($id)
// 接受订单
public function accept($id)
// 拒绝订单
public function reject($id)
}
请求验证:
class AcceptOrderRequest extends FormRequest
{
public function rules(): array
{
return [
'id' => 'required|integer|exists:orders,id',
'remark' => 'nullable|string|max:255'
];
}
}
响应封装:
class OrderResource extends JsonResource
{
public function toArray($request): array
{
return [
'id' => $this->id,
'order_no' => $this->order_no,
'status' => $this->status,
'status_text' => $this->status_text,
'created_at' => $this->created_at->format('Y-m-d H:i:s')
];
}
}