Browse Source

feat:完成技师申请、实名认证、资质认证

景好勇win11 3 months ago
parent
commit
a571188670

+ 4 - 4
app/Admin/Controllers/CoachQualRecordController.php

@@ -106,15 +106,15 @@ class CoachQualRecordController extends AdminController
     public function audit(Request $request)
     {
         $validated = $request->validate([
-            'qualification_record_id' => 'required|integer|exists:coach_qual_records,id',
+            'id' => 'required|integer|exists:coach_qual_records,id',
             'qualification_record_state' => 'required|integer|in:2,3', // 2:通过 3:驳回
-            'audit_remark' => 'required|string|max:255',
+            'audit_remark' => 'nullable|string|max:255',
         ]);
 
         $result = $this->service->audit(
-            $validated['qualification_record_id'],
+            $validated['id'],
             $validated['qualification_record_state'],
-            $validated['audit_remark'],
+            $validated['audit_remark'] ?? '',
             Admin::user()->id
         );
 

+ 41 - 0
app/Admin/Controllers/TechnicianController.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use Illuminate\Http\Request;
+use App\Services\TechnicianService;
+use App\Http\Controllers\Controller;
+
+class TechnicianController extends Controller
+{
+    protected $service;
+
+    public function __construct(TechnicianService $service)
+    {
+        $this->service = $service;
+    }
+
+    protected function autoResponse($data)
+    {
+        return response()->json($data);
+    }
+
+    /**
+     * 修改技师资质认证信息
+     */
+    public function updateCertification(Request $request)
+    {
+        // 验证请求数据
+        $validated = $request->validate([
+            'id' => 'required|integer',
+            'qual_photo' => 'required|string',
+            'business_license' => 'required|string',
+            'health_cert' => 'required|string',
+        ]);
+
+        $result = $this->service->updateCertification($validated['id'], $validated);
+
+        // 返回成功响应
+        return $this->autoResponse(['success' => $result]);
+    }
+}

+ 4 - 0
app/Enums/TechnicianAuthStatus.php

@@ -65,6 +65,10 @@ enum TechnicianAuthStatus: int
      */
     public static function fromValue(int $value): ?self
     {
+        if (!is_int($value)) {
+            return null;
+        }
+
         return match ($value) {
             self::AUDITING->value => self::AUDITING,
             self::PASSED->value => self::PASSED,

+ 7 - 1
app/Models/CoachInfoRecord.php

@@ -39,7 +39,13 @@ class CoachInfoRecord extends Model
      */
     public function getStateTextAttribute(): string
     {
-        return TechnicianAuthStatus::fromValue($this->state)?->label() ?? '未知状态';
+        $value = $this->state;
+        if ($value !== null) {
+            $status = TechnicianAuthStatus::fromValue($value);
+        } else {
+            // 处理 null 值的情况,例如设置默认状态或抛出异常
+        }
+        return $status?->label() ?? '未知状态';
     }
 
     /**

+ 1 - 1
app/Models/VCoachQualRecord.php

@@ -53,7 +53,7 @@ class VCoachQualRecord extends Model
         'avatar' => 'array',
         'portrait_images' => 'array',
         'business_license' => 'array',
-        'health_certificate' => 'array',
+        'health_cert' => 'array',
         'life_photos' => 'array',
     ];
 }

+ 1 - 0
app/Models/VCoachRealRecord.php

@@ -53,5 +53,6 @@ class VCoachRealRecord extends Model
         'id_card_front_photo' => 'array',
         'id_card_back_photo' => 'array',
         'id_card_hand_photo' => 'array',
+        'avatar' => 'array',
     ];
 }

+ 2 - 2
app/Services/CoachQualRecordService.php

@@ -28,7 +28,7 @@ class CoachQualRecordService extends AdminService
      * @return bool
      * @throws \Exception
      */
-    public function audit(int $id, int $state, string $remark, int $adminId): bool
+    public function audit(int $id, int $state, string $remark = '', int $adminId = 0): bool
     {
         DB::beginTransaction();
         try {
@@ -51,7 +51,7 @@ class CoachQualRecordService extends AdminService
             // 如果审核通过,更新技师状态
             if ($state == TechnicianAuthStatus::PASSED->value) {
                 CoachUser::where('id', $record->coach_id)->update([
-                    'qual_record_id' => $record->id
+                    'qualification_record_id' => $record->id
                 ]);
             }
 

+ 68 - 0
app/Services/TechnicianService.php

@@ -0,0 +1,68 @@
+<?php
+
+namespace App\Services;
+
+use App\Models\CoachQualRecord;
+use Illuminate\Support\Facades\DB;
+use App\Models\TechnicianCertification;
+use Slowlyo\OwlAdmin\Services\AdminService;
+
+/**
+ * 技师资质认证
+ *
+ * @method CoachQualRecord getModel()
+ * @method CoachQualRecord|\Illuminate\Database\Query\Builder query()
+ */
+class TechnicianService extends AdminService
+{
+    protected string $modelName = CoachQualRecord::class;
+
+    /**
+     * 更新技师资质信息
+     *
+     * @param int $id 资质记录ID
+     * @param array $data 更新的数据
+     * @return bool
+     * @throws \Exception
+     */
+    public function updateCertification(int $id, array $data): bool
+    {
+        DB::beginTransaction();
+        try {
+            // 获取资质记录
+            $record = $this->getModel()::findOrFail($id);
+
+            // 准备更新数据,确保不为 null
+            $updateData = [];
+
+            if (isset($data['qual_photo'])) {
+                $updateData['qual_photo'] = json_encode($data['qual_photo']);
+            }
+
+            if (isset($data['business_license'])) {
+                // 确保存储的值是有效的 JSON 格式
+                $updateData['business_license'] = json_encode($data['business_license']);
+            }
+
+            if (isset($data['health_cert'])) {
+                // 确保存储的值是有效的 JSON 格式
+                $updateData['health_cert'] = json_encode($data['health_cert']);
+            }
+
+
+            // 确保更新数据不为空
+            if (empty($updateData)) {
+                throw new \Exception('没有提供有效的更新数据');
+            }
+
+            // 更新资质记录
+            $record->update($updateData);
+
+            DB::commit();
+            return true;
+        } catch (\Exception $e) {
+            DB::rollBack();
+            throw $e;
+        }
+    }
+}

+ 40 - 120
doc/系统设计/数据库设计/物理模型/分析后台设计增加/03技师认证.sql

@@ -1,83 +1,3 @@
-DROP TABLE IF EXISTS report_coach_auth;
-
-CREATE TABLE report_coach_auth AS
-
-/* 技师认证视图 */
-
-DROP VIEW IF EXISTS manage_coach_auth;
-
-CREATE OR REPLACE VIEW manage_coach_auth AS
-WITH
-    /* 资质证书信息 */
-    qualification_photos AS (
-        SELECT
-            cq.id,
-            /* 从业资格证 */
-            MAX(
-                CASE
-                    WHEN cq.qual_type = 'QUALIFICATION' THEN cq.qual_photo
-                END
-            ) AS qualification_photo,
-            /* 健康证 */
-            MAX(
-                CASE
-                    WHEN cq.qual_type = 'HEALTH' THEN cq.qual_photo
-                END
-            ) AS health_photo,
-            /* 生活照 */
-            MAX(
-                CASE
-                    WHEN cq.qual_type = 'LIFE_PHOTO' THEN cq.qual_photo
-                END
-            ) AS life_photo,
-            /* 工作照 */
-            MAX(
-                CASE
-                    WHEN cq.qual_type = 'WORK_PHOTO' THEN cq.qual_photo
-                END
-            ) AS work_photo
-        FROM coach_qual_records cq
-        WHERE
-            cq.deleted_at IS NULL
-        GROUP BY
-            cq.id
-    )
-SELECT
-    cu.id AS id /* 技师ID */,
-    ci.id AS info_record_id /* 技师信息记录ID */,
-    cr.id AS real_auth_record_id /* 实名认证记录ID */,
-    qp.id AS qualification_record_id /* 资质证书记录ID */,
-    ci.nickname AS nickname /* 技师昵称 */,
-    ci.gender AS gender /* 性别 */,
-    ci.birthday AS birthday /* 出生日期 */,
-    ci.intention_city AS intention_city /* 期望城市 */,
-    ci.mobile AS mobile /* 手机号码 */,
-    ci.introduction AS introduction /* 个人简介 */,
-    CASE
-        WHEN cu.real_auth_record_id IS NULL THEN '未认证'
-        WHEN cu.qualification_record_id IS NULL THEN '实名认证完成'
-        ELSE '全部认证完成'
-    END AS auth_state /* 认证进度 */,
-    cu.state AS state /* 认证状态 */,
-    cr.id_card_front_photo AS id_card_front_photo /* 身份证照片正面 */,
-    cr.id_card_back_photo AS id_card_back_photo /* 身份证照片反面 */,
-    qp.qualification_photo AS qualification_photo /* 从业资格证图片 */,
-    qp.health_photo AS health_photo /* 健康证 */,
-    qp.life_photo AS life_photo /* 生活照 */,
-    qp.work_photo AS work_photo /* 工作照 */
-FROM
-    coach_users cu
-    LEFT JOIN coach_info_records ci ON cu.info_record_id = ci.id
-    LEFT JOIN coach_real_records cr ON cu.real_auth_record_id = cr.id
-    LEFT JOIN qualification_photos qp ON cu.qualification_record_id = qp.id
-WHERE
-    cu.deleted_at IS NULL
-    AND ci.deleted_at IS NULL
-    AND (
-        cr.deleted_at IS NULL
-        OR cr.deleted_at IS NULL
-    );
-
 /* 技师基本信息视图 */
 DROP VIEW IF EXISTS v_coach_info;
 
@@ -107,45 +27,6 @@ WHERE
     cir.deleted_at IS NULL
     AND cu.deleted_at IS NULL;
 
-/* 技师资质认证记录视图 */
-DROP VIEW IF EXISTS v_coach_qual_record;
-
-CREATE VIEW v_coach_qual_record AS
-SELECT
-    cqr.id AS id /* 资质证书记录ID */,
-    cu.id AS coach_id /* 技师ID */,
-    cir.id AS info_record_id /* 技师信息记录ID */,
-    cqr.qual_type AS qual_type /* 资质类型 */,
-    cqr.qual_photo AS qual_photo /* 资质图片 */,
-    cir.state AS info_record_state /* 技师信息记录状态 */,
-    cu.state AS coach_state /* 技师状态 */,
-    cqr.state AS qualification_record_state /* 审核状态 */,
-    cir.nickname AS nickname /* 技师昵称 */,
-    cir.gender AS gender /* 技师性别 */,
-    cir.mobile AS mobile /* 技师手机号码 */,
-    cir.intention_city AS intention_city /* 技师期望城市 */,
-    cir.introduction AS introduction /* 技师个人简介 */,
-    cir.portrait_images AS avatar /* 头像图片 */,
-    cir.life_photos AS life_photos /* 生活照片数组 */,
-    cqr.business_license AS business_license /* 技师营业执照 */,
-    cqr.health_cert AS health_certificate /* 技师健康证 */,
-    cr.id_card_front_photo AS id_card_front_photo /* 技师身份证照片正面 */,
-    cr.id_card_back_photo AS id_card_back_photo /* 技师身份证照片反面 */,
-    cr.id_card_hand_photo AS id_card_hand_photo /* 技师身份证手持照片 */,
-    cqr.created_at AS created_at /* 申请时间 */,
-    cqr.auditor AS auditor /* 审核人 */,
-    cqr.audit_time AS audit_time /* 审核时间 */,
-    cqr.audit_remark AS audit_remark /* 审核备注 */
-FROM
-    coach_qual_records cqr
-    LEFT JOIN coach_users cu ON cu.id = cqr.coach_id /* 先关联技师用户表 */
-    LEFT JOIN coach_info_records cir ON cir.id = cu.info_record_id /* 再关联技师信息记录表 */
-    LEFT JOIN coach_real_records cr ON cr.coach_id = cqr.coach_id /* 最后关联实名认证记录表 */
-WHERE
-    cqr.deleted_at IS NULL
-    AND cu.deleted_at IS NULL
-    AND cir.deleted_at IS NULL;
-
 /* 技师实名认证记录视图 */
 DROP VIEW IF EXISTS v_coach_real_record;
 
@@ -155,7 +36,7 @@ SELECT
     cu.id AS coach_id /* 技师ID */,
     cir.id AS info_record_id /* 技师信息记录ID */,
     cir.nickname AS nickname /* 技师昵称 */,
-    cir.portrait_images AS avatar /* 头像图片 */,
+    cir.avatar AS avatar /* 头像图片 */,
     cir.gender AS gender /* 技师性别 */,
     cir.mobile AS mobile /* 技师手机号码 */,
     cir.intention_city AS intention_city /* 技师期望城市 */,
@@ -178,3 +59,42 @@ WHERE
     cr.deleted_at IS NULL
     AND cu.deleted_at IS NULL
     AND cir.deleted_at IS NULL;
+
+/* 技师资质认证记录视图 */
+DROP VIEW IF EXISTS v_coach_qual_record;
+
+CREATE VIEW v_coach_qual_record AS
+SELECT DISTINCT
+    cqr.id AS id /* 资质证书记录ID */,
+    cu.id AS coach_id /* 技师ID */,
+    cir.id AS info_record_id /* 技师信息记录ID */,
+    cir.nickname AS nickname /* 技师昵称 */,
+    cir.gender AS gender /* 技师性别 */,
+    cir.mobile AS mobile /* 技师手机号码 */,
+    cir.intention_city AS intention_city /* 技师期望城市 */,
+    cir.introduction AS introduction /* 技师个人简介 */,
+    cir.avatar AS avatar /* 头像图片 */,
+    cir.life_photos AS life_photos /* 生活照片数组 */,
+    cqr.qual_type AS qual_type /* 资质类型 */,
+    cqr.qual_photo AS qual_photo /* 资质图片 */,
+    cqr.business_license AS business_license /* 技师营业执照 */,
+    cqr.health_cert AS health_cert /* 技师健康证 */,
+    cr.id_card_front_photo AS id_card_front_photo /* 技师身份证照片正面 */,
+    cr.id_card_back_photo AS id_card_back_photo /* 技师身份证照片反面 */,
+    cr.id_card_hand_photo AS id_card_hand_photo /* 技师身份证手持照片 */,
+    cu.state AS coach_state /* 技师状态 */,
+    cqr.state AS qualification_record_state /* 审核状态 */,
+    cqr.created_at AS created_at /* 申请时间 */,
+    cqr.auditor AS auditor /* 审核人 */,
+    cqr.audit_time AS audit_time /* 审核时间 */,
+    cqr.audit_remark AS audit_remark /* 审核备注 */
+FROM
+    coach_qual_records cqr
+    LEFT JOIN coach_users cu ON cu.id = cqr.coach_id /* 先关联技师用户表 */
+    LEFT JOIN coach_info_records cir ON cir.id = cu.info_record_id /* 再关联技师信息记录表 */
+    LEFT JOIN coach_real_records cr ON cr.id = cu.real_auth_record_id /* 最后关联实名认证记录表 */
+WHERE
+    cqr.deleted_at IS NULL
+    AND cu.deleted_at IS NULL
+    AND cir.deleted_at IS NULL
+    AND cr.deleted_at IS NULL;

+ 7 - 0
routes/web.php

@@ -9,6 +9,7 @@ use App\Http\Controllers\UploadController;
 use App\Admin\Controllers\ShopInfoController;
 use App\Admin\Controllers\CoachUserController;
 use App\Admin\Controllers\MemberUserController;
+use App\Admin\Controllers\TechnicianController;
 
 
 Route::get('/', function () {
@@ -135,6 +136,9 @@ Route::group(
 
         // 修改技师实名认证信息
         Route::post('coach_real_records/update_info', [\App\Admin\Controllers\CoachRealRecordController::class, 'updateInfo']);
+
+        // 修改技师资质认证信息
+        Route::post('/technician/certification/update', [TechnicianController::class, 'updateCertification']);
     }
 );
 
@@ -251,5 +255,8 @@ Route::group([
 
         // 修改技师实名认证信息
         Route::post('coach_real_records/update_info', [\App\Admin\Controllers\CoachRealRecordController::class, 'updateInfo']);
+
+        // 修改技师资质认证信息
+        Route::post('technician/certification/update', [TechnicianController::class, 'updateCertification']);
     });
 });