Browse Source

feat:后端-店铺管理-审核

刘学玺 4 months ago
parent
commit
b4b26de0a4

+ 73 - 44
app/Admin/Controllers/ShopInfoController.php

@@ -3,6 +3,7 @@
 namespace App\Admin\Controllers;
 
 use App\Services\ShopInfoService;
+use Illuminate\Http\Request;
 use Slowlyo\OwlAdmin\Controllers\AdminController;
 
 /**
@@ -12,47 +13,75 @@ use Slowlyo\OwlAdmin\Controllers\AdminController;
  */
 class ShopInfoController extends AdminController
 {
-	protected string $serviceName = ShopInfoService::class;
-
-	public function list()
-	{
-		$crud = $this->baseCRUD()
-			->filterTogglable(false)
-			->headerToolbar([
-				$this->createButton('dialog'),
-				...$this->baseHeaderToolBar()
-			])
-			->columns([
-				amis()->TableColumn('id', 'ID')->sortable(),
-				amis()->TableColumn('auth_record_id', '店铺认证记录编号'),
-				amis()->TableColumn('salesperson_id', '业务员编号'),
-				amis()->TableColumn('state', '状态'),
-				amis()->TableColumn('created_at', admin_trans('admin.created_at'))->type('datetime')->sortable(),
-				amis()->TableColumn('updated_at', admin_trans('admin.updated_at'))->type('datetime')->sortable(),
-				$this->rowActions('dialog')
-			]);
-
-		return $this->baseList($crud);
-	}
-
-	public function form($isEdit = false)
-	{
-		return $this->baseForm()->body([
-			amis()->TextControl('auth_record_id', '店铺认证记录编号'),
-			amis()->TextControl('salesperson_id', '业务员编号'),
-			amis()->TextControl('state', '状态'),
-		]);
-	}
-
-	public function detail()
-	{
-		return $this->baseDetail()->body([
-			amis()->TextControl('id', 'ID')->static(),
-			amis()->TextControl('auth_record_id', '店铺认证记录编号')->static(),
-			amis()->TextControl('salesperson_id', '业务员编号')->static(),
-			amis()->TextControl('state', '状态')->static(),
-			amis()->TextControl('created_at', admin_trans('admin.created_at'))->static(),
-			amis()->TextControl('updated_at', admin_trans('admin.updated_at'))->static(),
-		]);
-	}
-}
+    protected string $serviceName = ShopInfoService::class;
+
+    public function list()
+    {
+        $crud = $this->baseCRUD()
+            ->filterTogglable(false)
+            ->headerToolbar([
+                $this->createButton('dialog'),
+                ...$this->baseHeaderToolBar(),
+            ])
+            ->columns([
+                amis()->TableColumn('id', 'ID')->sortable(),
+                amis()->TableColumn('auth_record_id', '店铺认证记录编号'),
+                amis()->TableColumn('salesperson_id', '业务员编号'),
+                amis()->TableColumn('state', '状态'),
+                amis()->TableColumn('created_at', admin_trans('admin.created_at'))->type('datetime')->sortable(),
+                amis()->TableColumn('updated_at', admin_trans('admin.updated_at'))->type('datetime')->sortable(),
+                $this->rowActions('dialog'),
+            ]);
+
+        return $this->baseList($crud);
+    }
+
+    public function form($isEdit = false)
+    {
+        return $this->baseForm()->body([
+            amis()->TextControl('auth_record_id', '店铺认证记录编号'),
+            amis()->TextControl('salesperson_id', '业务员编号'),
+            amis()->TextControl('state', '状态'),
+        ]);
+    }
+
+    public function detail()
+    {
+        return $this->baseDetail()->body([
+            amis()->TextControl('id', 'ID')->static(),
+            amis()->TextControl('auth_record_id', '店铺认证记录编号')->static(),
+            amis()->TextControl('salesperson_id', '业务员编号')->static(),
+            amis()->TextControl('state', '状态')->static(),
+            amis()->TextControl('created_at', admin_trans('admin.created_at'))->static(),
+            amis()->TextControl('updated_at', admin_trans('admin.updated_at'))->static(),
+        ]);
+    }
+
+    /**
+     * [店铺管理]审核店铺
+     *
+     * @description 审核店铺认证申请
+     *
+     * @header x-xsrf-token required CSRF令牌 Example: your_csrf_token
+     *
+     * @bodyParam shop_id integer required 店铺ID Example: 1
+     * @bodyParam action string required 审核操作(approve:通过,reject:拒绝) Example: approve
+     * @bodyParam reason string required 审核意见 Example: 资料齐全,符合要求
+     *
+     * @response {
+     *   "code": 200,
+     *   "message": "审核成功",
+     *   "data": null
+     * }
+     */
+    public function review(Request $request)
+    {
+        $validated = $request->validate([
+            'shop_id' => 'required|integer|exists:shop_info,id',
+            'action' => 'required|string|in:approve,reject',
+            'reason' => 'required|string|max:255',
+        ]);
+
+        return $this->service->reviewShop($validated);
+    }
+}

+ 14 - 14
app/Enums/ShopStatus.php

@@ -8,19 +8,19 @@ namespace App\Enums;
 enum ShopStatus: int
 {
     /**
-     * 店铺状态:待开业
+     * 店铺状态:待审核
      */
     case PENDING = 1;
 
     /**
-     * 店铺状态:营业中
+     * 店铺状态:正常
      */
-    case OPERATING = 2;
+    case ACTIVE = 2;
 
     /**
-     * 店铺状态:暂停营业
+     * 店铺状态:已拒绝
      */
-    case SUSPENDED = 3;
+    case REJECTED = 3;
 
     /**
      * 店铺状态:已关闭
@@ -35,9 +35,9 @@ enum ShopStatus: int
     public function label(): string
     {
         return match ($this) {
-            self::PENDING => '待开业',
-            self::OPERATING => '营业中',
-            self::SUSPENDED => '暂停营业',
+            self::PENDING => '待审核',
+            self::ACTIVE => '正常',
+            self::REJECTED => '已拒绝',
             self::CLOSED => '已关闭',
         };
     }
@@ -55,7 +55,7 @@ enum ShopStatus: int
     /**
      * 检查当前状态是否与指定状态相同
      *
-     * @param self $status 要比较的状态
+     * @param  self  $status  要比较的状态
      * @return bool 如果状态相同返回 true,否则返回 false
      */
     public function is(self $status): bool
@@ -66,15 +66,15 @@ enum ShopStatus: int
     /**
      * 根据整数值创建对应的状态枚举实例
      *
-     * @param int $value 状态值
+     * @param  int  $value  状态值
      * @return self|null 返回对应的状态枚举实例,如果值无效则返回 null
      */
     public static function fromValue(int $value): ?self
     {
         return match ($value) {
             self::PENDING->value => self::PENDING,
-            self::OPERATING->value => self::OPERATING,
-            self::SUSPENDED->value => self::SUSPENDED,
+            self::ACTIVE->value => self::ACTIVE,
+            self::REJECTED->value => self::REJECTED,
             self::CLOSED->value => self::CLOSED,
             default => null
         };
@@ -99,8 +99,8 @@ enum ShopStatus: int
     {
         return [
             self::PENDING->value => self::PENDING->label(),
-            self::OPERATING->value => self::OPERATING->label(),
-            self::SUSPENDED->value => self::SUSPENDED->label(),
+            self::ACTIVE->value => self::ACTIVE->label(),
+            self::REJECTED->value => self::REJECTED->label(),
             self::CLOSED->value => self::CLOSED->label(),
         ];
     }

+ 16 - 3
app/Models/ShopInfo.php

@@ -10,12 +10,13 @@ use Slowlyo\OwlAdmin\Models\BaseModel as Model;
  */
 class ShopInfo extends Model
 {
-	use SoftDeletes;
+    use SoftDeletes;
 
-	protected $table = 'shop_infos';
+    protected $table = 'shop_infos';
 
     /**
      * @Author FelixYin
+     *
      * @description 店铺所属会员
      */
     public function member()
@@ -25,6 +26,7 @@ class ShopInfo extends Model
 
     /**
      * @Author FelixYin
+     *
      * @description 店铺关联认证信息
      */
     public function auth()
@@ -34,6 +36,7 @@ class ShopInfo extends Model
 
     /**
      * @Author FelixYin
+     *
      * @description 店铺关联技师
      */
     public function coaches()
@@ -43,6 +46,7 @@ class ShopInfo extends Model
 
     /**
      * @Author FelixYin
+     *
      * @description 店铺关联服务
      */
     public function services()
@@ -52,10 +56,19 @@ class ShopInfo extends Model
 
     /**
      * @Author FelixYin
+     *
      * @description 店铺关联认证记录
      */
     public function authRecords()
     {
         return $this->hasMany('App\Models\ShopAuthRecord', 'shop_id', 'id');
     }
-}
+
+    /**
+     * 获取店铺认证记录
+     */
+    public function authRecord()
+    {
+        return $this->belongsTo(ShopAuthRecord::class, 'auth_record_id');
+    }
+}

+ 61 - 2
app/Services/ShopInfoService.php

@@ -2,7 +2,11 @@
 
 namespace App\Services;
 
+use App\Enums\ShopStatus;
 use App\Models\ShopInfo;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
 use Slowlyo\OwlAdmin\Services\AdminService;
 
 /**
@@ -13,5 +17,60 @@ use Slowlyo\OwlAdmin\Services\AdminService;
  */
 class ShopInfoService extends AdminService
 {
-	protected string $modelName = ShopInfo::class;
-}
+    protected string $modelName = ShopInfo::class;
+
+    /**
+     * 审核店铺
+     *
+     * @param  array  $data  包含 shop_id, action 和 reason
+     */
+    public function reviewShop(array $data): array
+    {
+        try {
+            DB::beginTransaction();
+
+            // 获取店铺信息
+            $shop = ShopInfo::with('authRecord')->findOrFail($data['shop_id']);
+
+            // 验证店铺当前状态
+            abort_if($shop->state !== ShopStatus::PENDING->value, 422, '店铺状态不允许审核');
+
+            // 验证认证记录是否存在
+            abort_if(! $shop->authRecord, 422, '店铺认证信息不存在');
+
+            // 更新店铺状态
+            $shop->state = $data['action'] === 'approve'
+                ? ShopStatus::ACTIVE->value
+                : ShopStatus::REJECTED->value;
+            $shop->save();
+
+            // 更新认证记录状态
+            $shop->authRecord->state = $data['action'] === 'approve'
+                ? ShopStatus::ACTIVE->value
+                : ShopStatus::REJECTED->value;
+            $shop->authRecord->audit_remark = $data['reason'];
+            $shop->authRecord->audit_time = now();
+            $shop->authRecord->auditor = Auth::id();
+            $shop->authRecord->save();
+
+            DB::commit();
+
+            return [
+                'code' => 200,
+                'message' => '审核成功',
+                'data' => null,
+            ];
+
+        } catch (\Exception $e) {
+            DB::rollBack();
+            Log::error('审核店铺失败', [
+                'shop_id' => $data['shop_id'],
+                'action' => $data['action'],
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString(),
+            ]);
+
+            throw $e;
+        }
+    }
+}

+ 1 - 0
routes/web.php

@@ -172,5 +172,6 @@ Route::group([
         Route::post('user/bad-behavior', [MemberUserController::class, 'recordBadBehavior']);
         Route::post('coach/block', [CoachUserController::class, 'blockCoach']);
         Route::post('coach/freeze-balance', [CoachUserController::class, 'freezeBalance']);
+        Route::post('shop/review', [ShopInfoController::class, 'review']);
     });
 });