# 技师端架构说明 ## 用户与技师关系 1. 技师端的用户模型: - 基础用户模型为 MemberUser - 技师信息通过 coach 关联获取 - Auth::user() 获取的是当前登录的 MemberUser 实例 - 技师信息通过 Auth::user()->coach 获取 2. 关键代码示例: ```php /** @var MemberUser $user */ // 获取当前登录用户 $user = Auth::user(); // 返回 MemberUser 实例 // 获取用户关联的技师信息 $coach = $user->coach; // 返回 CoachUser 实例 // 常见的验证模式 abort_if(!$user->coach, 404, '技师信息不存在'); ``` 3. 主要模型关系: - MemberUser: 基础用户模型 - CoachUser: 技师模型 - 一对一关联: MemberUser hasOne CoachUser 4. 技师相关验证: - 需要验证用户是否为技师(coach 关联是否存在) - 需要验证技师状态是否正常 - 需要验证技师认证状态 ## 技师认证与审核 ### 1. 认证类型 1. 基础信息认证: - 个人基本信息(姓名、手机号、身份证号等) - 居住地址信息 - 联系人信息 2. 实名认证: - 身份证正面照 - 身份证背面 �� - 手持身份证照 3. 资质认证: - 职业资格证书 - 相关培训证书 - 其他资质证明 ### 2. 数据库设计 1. 技师表认证状态字段: ```sql 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 '资质认证备注'; ``` 2. 认证记录表: ```sql -- 基础信息认证记录表 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='技师资质认证记录表'; ``` ### 3. 认证提交规则 1. 提交限制: - 审核中状态不允许重新提交 - 已通过状态不允许重新提交 - 只有未提交或审核拒绝状态可以提交 2. 提交校验: ```php /** * 检查是否可以提交认证 */ 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 // 已通过 ]); } ``` ### 4. 审核流程 1. 提交认证: ```php /** * 提交基础信息认证 */ 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')); }); } ``` 2. 审核操作: ```php /** * 审核基础信息认证 */ 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)); }); } ``` ### 5. 状态查询 1. 认证状态查询: ```php /** * 获取认证状态 */ 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, ], ]; } ``` 2. 认证历史记录: ```php /** * 获取认证历史记录 */ 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(); } ``` ### 6. 注意事项 1. 数据安全: - 敏感信息加密存储 - 图片资源需要进行安全验证 - 审核操作需要有操作日志 2. 并发处理: - 使用数据库事务确保数据一致性 - 状态变更时需要考虑并发情况 - 关键操作需要加锁处理 3. 通知机制: - 状态变更时需要通知相关人员 - 审核结果需要实时推送给技师 - 重要操作需要短信或其他方式通知 4. 数据验证: - 提交时严格验证数据格式 - 图片资源需要验证大小和格式 - 身份证号等关键信息需要验证真实性 5. 异常处理: - 所有操作需要有完善的异常处理 - 异常发生时需要有友好的提示 - 关键异常需要告警通知 ### 7. 认证验证中间件 1. 验证方法: ```php /** * 技师认证状态验证 * * @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('请先完成资质认证'); } } ``` 2. 使用说明: - 除认证相关接口外,所有技师端接口都需要进行完整的认证验证 - 在 Service 层基类中实现认证验证方法 - 所有需要认证验证的方法必须调用验证方法 - 可以使用中间件统一处理认证验证 3. 验证规则: - 所有认证状态必须为 PASSED (已通过) - 未提交认证时提示"请先完成 XX 认证" - 认证审核中时提示"XX 认证审核中" - 认证被拒绝时提示"XX 认证未通过,请重新提交" 4. 异常处理: - 认证验证失败时抛出 BusinessException - 异常信息需要明确指出具体未通过的认证项 - 前端需要根据异常信息引导用户完成认证 5. 注意事项: - 认证验证应该在业务逻辑执行前进行 - 需要考虑多个认证未通过的情况 - 验证提示信息要友好且明确 - 记录认证验证失败的日志 ## 目录结构 1. 控制器位置: - app/Http/Controllers/Coach/\* 2. 服务类位置: - app/Services/Coach/\* 3. 请求验证类位置: - app/Http/Requests/Coach/\* ## 核心服务类说明 1. AccountService: - 处理技师账户相关操作 - 包括基本信息、资质信息、实名认证的提交和查询 - 处理技师位置信息和排班设置 2. AuthService: - 处理技师认证相关操作 - 包括基本信息认证、实名认证、资质认证 - 提供认证状态查询 3. OrderService: - 处理技师订单相关操作 - 包括订单列表查询、抢单、接单、拒单 - 处理订单状态流转(出发、到达、开始服务、撤离) 4. ProjectService: - 处理技师项目相关操作 - 包括可开通项目查询、项目开通 - 处理项目设置(折扣、性别限制等) 5. WalletService: - 处理技师钱包相关操作 - 包括钱包信息查询、流水记录 - 处理提现申请 ## 注意事项 1. 权限验证: - 所有技师端接口都需要验证用户是否为技师 - 使用 abort_if(!$user->coach, 404, '技师信息不存在') 进行验证 2. 数据获取: - 优先通过关联关系获取数据 - 使用 with() 进行预加载以优化性能 3. 错误处理: - 使用 abort_if 行前置条件验证 - 在 Service 层进行详细的业务逻辑验证 4. 事务处理: - 涉及多表操作时使用数据库事务 - 在 Service 层实现事务逻辑 5. 缓存策略: - 技师信息优先使用缓存 - 更新操作时及时处理相关缓存 6. 日志记录: - 重要操作需要记录日志 - 包含用户 ID、技师 ID、操作内容等关键信息 7. 敏感数据处理: - 手机号、身份证等敏感信息需要脱敏处理 - 日志中不应该出现完整的敏感信息 ## 常用枚举类型 1. 技师状态相关: - TechnicianStatus: 技师状态 - PENDING: 待认证 (1) - ACTIVE: 正常服务 (2) - SUSPENDED: 暂停服务 (3) - BLACKLIST: 黑名单 (4) - TERMINATED: 已终止 (5) - TechnicianAuthStatus: 认证状态 - AUDITING: 审核中 (1) - PASSED: 审核通过 (2) - REJECTED: 审核拒绝 (3) - TechnicianWorkStatus: 工 �� 状态 - REST: 休息 (1) - FREE: 空闲 (2) - BUSY: 忙碌 (3) - TechnicianLocationType: 位置类型 - CURRENT: 当前定位 (1) - COMMON: 常用定位 (2) 2. 订单相关: - OrderStatus: 订单状态 - CREATED: 下单 (1) - ASSIGNED: 指定 (2) - PAID: 支付 (3) - CANCELLED: 取消 (4) - REFUNDING: 退款中 (5) - REFUNDED: 退款成功 (6) - REFUND_FAILED: 退款失败 (7) - ACCEPTED: 接单 (8) - DEPARTED: 出发 (9) - ARRIVED: 到达 (10) - STARTED: 开始服务 (11) - SERVING: 服务中 (12) - FINISHED: 服务结束 (13) - LEFT: 撤离 (14) - COMMENTED: 已评价 (15) - REJECTED: 已拒单 (16) - ALARM: 报警 (17) - COMPLETED: 服务完成 (18) - OrderType: 订单类型 - VISIT: 上门 (1) - GRAB: 抢单 (2) - OVERTIME: 加钟 (3) - SHOP: 到店 (4) - EMERGENCY: 应急 (5) - OrderRecordStatus: 订单记录状态 - CREATED: 创建订单 (1) - PAID: 支付完成 (2) - ASSIGNED: 已分配技师 (3) - ARRIVED: 技师到达 (4) - STARTED: 开始服务 (5) - COMPLETED: 服务完成 (6) - EVALUATED: 已评价 (7) - CANCELLED: 已取消 (8) - REJECTED: 已拒单 (9) - DEPARTED: 技师出发 (10) - LEFT: 技师撤离 (11) - REFUNDING: 退款中 (12) - REFUNDED: 退款完成 (13) - CHANGE_COACH: 更换技师 (14) - RESET_COACH: 重置技师 (15) - TEMPORARY_ACCEPTED: 临时接单 (16) - ALARM_HANDLED: 报警已处理 (17) 3. 项目相关: - ProjectStatus: 项目状态 - OPEN: 开 (1) - CLOSE: 关闭 (2) 4. 钱包相关: - WithdrawStatus: 提现状态 - PROCESSING: 提现中 (1) - SUCCESS: 提现成功 (2) - FAILED: 提现失败 (3) ## 数据验证和安全 1. 输入验证: - 使用专门的 Request 类进行请求验证 - 在 Service 层进行业务规则验证 - 所有外部输入都必须经过验证 2. 数据安全: - 敏感数据传输需要加密 - 关键操作需要验证用户身份 - 定期清理临时数据和日志 3. 并发处理: - 使用数据库事务确保数据一致性 - 关键操作使用锁机制防止并发问题 - 使用队列处理耗时操作 ## 开发规范 1. 代码风格: - 遵循 PSR-12 编码规范 - 使用类型提示和返回值类型声明 - 所有属性和方法都要有清晰的访问修饰符 2. 注释规范: - 类和方法必须有 PHPDoc 注释 - 复杂的业务逻辑需要添加行内注释 - 关键参数和返回值要有说明 3. 异常处理: - 使用自定义异常类区分不同类型的错误 - 统一的异常处理机制 - 详细的错误日志记录 4. 测试要求: - 核心业务逻辑需要单元测试 - 关键接口需要集成测试 - 定期进行性能测试 ## API 接口规范 ### 1. 路由规范 1. 路由前缀: - 所有技师端 API 统一使用 `/api/coach` 前缀 - 认证相关: `/api/coach/auth/*` - 订单相关: `/api/coach/orders/*` - 项目相关: `/api/coach/projects/*` - 钱包相关: `/api/coach/wallet/*` 2. 路由命名规范: - 资源集合使用复数形式 - 使用 kebab-case 命名方式 - 遵循 RESTful 设计原则 3. 标准 RESTful 路由: ```php // 订单相关路由示例 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'); }); ``` ### 2. 请求规范 1. 请求方法: - GET: 获取资源 - POST: 创建资源 - PUT: 更新资源(完整更新) - PATCH: 更新资源(部分更新) - DELETE: 删除资源 2. 请求头要求: ```http Accept: application/json Content-Type: application/json Authorization: Bearer {token} ``` 3. 分页查询参数: ```json { "page": 1, // 当前页码 "per_page": 15, // 每页数量 "order_by": "created_at", // 排序字段 "order_type": "desc" // 排序方式 } ``` ### 3. 响应规范 1. 响应格式: ```json { "code": 0, // 业务状态码 "message": "success", // 状态描述 "data": { // 响应数据 "items": [ // 列表数据 { "id": 1, "order_no": "O202401010001", "status": 1, "created_at": "2024-01-01 00:00:00" } ], "total": 100 // 总记录数 } } ``` 2. 错误响应格式: ```json { "code": 422, // HTTP状态码 "message": "验证失败", // 错误描述 "errors": { // 详细错误信息 "field": ["错误描述1", "错误描述2"] } } ``` 3. 分页查询参数: ```json { "page": 1, // 当前页码 "per_page": 15, // 每页数量 "order_by": "created_at", // 排序字段 "order_type": "desc" // 排序方式 } ``` ### 4. 状态码规范 1. HTTP 状态码: - 200: 请求成功 - 201: 创建成功 - 204: 删除成功 - 400: 请求参数错误 - 401: 未授权 - 403: 禁止访问 - 404: 资源不存在 - 422: 参数验证失败 - 429: 请求过于频繁 - 500: 服务器错误 2. 业务状态码: - 0: 成功 - 1000-1999: 用户相关错误 - 2000-2999: 订单相关错误 - 3000-3999: 支付相关错误 - 4000-4999: ��� 统相关错误 ### 5. 接口文档规范 1. 文档注解要求: ```php /** * 获取订单列表 * * @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 * } * } */ ``` 2. 版本控制: - URI 版本控制: /api/v1/coach/\* - 在请求头中指定版本: Accept: application/vnd.app.v1+json ### 6. 安全规范 1. 认证要求: - 使用 Bearer Token 认证 - Token 有效期控制 - 敏感接口需要二次验证 2. 访问控制: - 接口访问频率限制 - IP 白名单控制 - 关键操作需要验证码 3. 数据安全: - 敏感数据传输加密 - 参数防注入处理 - 上传文件类型限制 ### 7. 开发规范 1. 控制器命名: ```php class OrderController extends Controller { // 获取订单列表 public function index() // 获取订单详情 public function show($id) // 接受订单 public function accept($id) // 拒绝订单 public function reject($id) } ``` 2. 请求验证: ```php class AcceptOrderRequest extends FormRequest { public function rules(): array { return [ 'id' => 'required|integer|exists:orders,id', 'remark' => 'nullable|string|max:255' ]; } } ``` 3. 响应封装: ```php 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') ]; } } ```