Przeglądaj źródła

1.新增推送资产或资产文件夹功能2.所有公共资产库的增删改操作都增加了角色验证

lh 1 dzień temu
rodzic
commit
ff7e14af88
1 zmienionych plików z 121 dodań i 20 usunięć
  1. 121 20
      app/Services/Anime/AnimeService.php

+ 121 - 20
app/Services/Anime/AnimeService.php

@@ -5853,10 +5853,16 @@ class AnimeService
     public function createFolder($data) {
         $uid = Site::getUid();
         $cpid = Site::getCpid();
+        $role = Site::getRole();
         $parent_id = getProp($data, 'parent_id', 0);
         $folder_name = getProp($data, 'product_name', '新建文件夹');
         $is_public = getProp($data, 'is_public', 0); // 0=个人资产库 1=公共资产库
         
+        // 如果是公共库操作,需要admin权限
+        if ($is_public && $role !== 'admin') {
+            Utils::throwError('20003:只有管理员才能操作公共资产库');
+        }
+        
         // 根据is_public参数确定存储的user_id(公共库user_id=0,cpid保持不变)
         $store_uid = $is_public ? 0 : $uid;
         
@@ -5942,6 +5948,7 @@ class AnimeService
     public function renameFolder($data) {
         $uid = Site::getUid();
         $cpid = Site::getCpid();
+        $role = Site::getRole();
         $id = getProp($data, 'id');
         $new_name = getProp($data, 'product_name');
         $is_public = getProp($data, 'is_public', 0); // 0=个人资产库 1=公共资产库
@@ -5953,6 +5960,11 @@ class AnimeService
         // 根据is_public参数确定查询的user_id(公共库user_id=0,cpid保持不变)
         $query_uid = $is_public ? 0 : $uid;
         
+        // 如果是公共库操作,需要admin权限
+        if ($is_public && $role !== 'admin') {
+            Utils::throwError('20003:只有管理员才能操作公共资产库');
+        }
+        
         // 检查是否存在
         $item = DB::table('mp_products')
             ->where('id', $id)
@@ -5983,6 +5995,7 @@ class AnimeService
     public function moveProductOrFolder($data) {
         $uid = Site::getUid();
         $cpid = Site::getCpid();
+        $role = Site::getRole();
         $id = getProp($data, 'id');
         $target_parent_id = getProp($data, 'target_parent_id', 0);
         $is_public = getProp($data, 'is_public', 0); // 0=个人资产库 1=公共资产库
@@ -5994,6 +6007,11 @@ class AnimeService
         // 根据is_public参数确定查询的user_id(公共库user_id=0,cpid保持不变)
         $query_uid = $is_public ? 0 : $uid;
         
+        // 如果是公共库操作,需要admin权限
+        if ($is_public && $role !== 'admin') {
+            Utils::throwError('20003:只有管理员才能操作公共资产库');
+        }
+        
         // 检查要移动的项目
         $item = DB::table('mp_products')
             ->where('id', $id)
@@ -6202,8 +6220,14 @@ class AnimeService
     public function createProduct($data) {
         $uid = Site::getUid();
         $cpid = Site::getCpid();
+        $role = Site::getRole();
         $is_public = getProp($data, 'is_public', 0); // 0=个人资产库 1=公共资产库
         
+        // 如果是公共库操作,需要admin权限
+        if ($is_public && $role !== 'admin') {
+            Utils::throwError('20003:只有管理员才能操作公共资产库');
+        }
+        
         // 根据is_public参数确定存储的user_id(公共库user_id=0,cpid保持不变)
         $store_uid = $is_public ? 0 : $uid;
         
@@ -6286,6 +6310,7 @@ class AnimeService
     public function editProduct($data) {
         $uid = Site::getUid();
         $cpid = Site::getCpid();
+        $role = Site::getRole();
         $id = getProp($data, 'id');
         if (!$id) Utils::throwError('20003:ID不能为空');
         $versions = getProp($data, 'versions');
@@ -6294,6 +6319,11 @@ class AnimeService
         // 根据is_public参数确定查询的user_id(公共库user_id=0,cpid保持不变)
         $query_uid = $is_public ? 0 : $uid;
         
+        // 如果是公共库操作,需要admin权限
+        if ($is_public && $role !== 'admin') {
+            Utils::throwError('20003:只有管理员才能操作公共资产库');
+        }
+        
         // 检查是否存在且属于当前用户或公共库
         $role = DB::table('mp_products')
         ->where('id', $id)
@@ -6509,6 +6539,7 @@ class AnimeService
     public function deleteProduct($data) {
         $uid = Site::getUid();
         $cpid = Site::getCpid();
+        $role = Site::getRole();
         $id = getProp($data, 'id');
         if (!$id) Utils::throwError('20003:ID不能为空');
         $ids = explode(',', $id);
@@ -6517,6 +6548,11 @@ class AnimeService
         // 根据is_public参数确定查询的user_id(公共库user_id=0,cpid保持不变)
         $query_uid = $is_public ? 0 : $uid;
         
+        // 如果是公共库操作,需要admin权限
+        if ($is_public && $role !== 'admin') {
+            Utils::throwError('20003:只有管理员才能操作公共资产库');
+        }
+        
         // 检查是否存在且属于当前用户或公共库
         $role = DB::table('mp_products')
         ->whereIn('id', $ids)
@@ -6538,6 +6574,7 @@ class AnimeService
     public function generateThreeView($data) {
         $uid = Site::getUid();
         $cpid = Site::getCpid();
+        $role = Site::getRole();
         $id = getProp($data, 'id');
         if (!$id) Utils::throwError('20003:ID不能为空');
         $is_public = getProp($data, 'is_public', 0); // 0=个人资产库 1=公共资产库
@@ -6545,6 +6582,11 @@ class AnimeService
         // 根据is_public参数确定查询的user_id(公共库user_id=0,cpid保持不变)
         $query_uid = $is_public ? 0 : $uid;
         
+        // 如果是公共库操作,需要admin权限
+        if ($is_public && $role !== 'admin') {
+            Utils::throwError('20003:只有管理员才能操作公共资产库');
+        }
+        
         // 检查是否存在且属于当前用户或公共库
         $product = DB::table('mp_products')
         ->where('id', $id)
@@ -6712,31 +6754,24 @@ class AnimeService
 
     /**
      * 推送(复制)资产或文件夹到目标位置
-     * @param array $data 包含 product_id(要推送的资产或文件夹ID)、target_parent_id(目标父文件夹ID,0表示根目录)、is_public(目标是否为公共库)
+     * @param array $data 包含 product_id(要推送的资产或文件夹ID)、target_parent_id(目标父文件夹ID,0表示根目录)
      * @return array 返回推送结果
      */
     public function pushProductOrFolder($data) {
         $uid = Site::getUid();
         $cpid = Site::getCpid();
+        $role = Site::getRole();
         $product_id = getProp($data, 'product_id');
         $target_parent_id = getProp($data, 'target_parent_id', 0);
-        $source_is_public = getProp($data, 'source_is_public', 0); // 源是否为公共库
-        $target_is_public = getProp($data, 'target_is_public', 0); // 目标是否为公共库
         
         if (!$product_id) {
             Utils::throwError('20003:请选择要推送的项目');
         }
         
-        // 根据source_is_public确定源的user_id
-        $source_uid = $source_is_public ? 0 : $uid;
-        // 根据target_is_public确定目标的user_id
-        $target_uid = $target_is_public ? 0 : $uid;
-        
-        // 获取要推送的项目
+        // 查询源项目(只通过cpid查询,不限制user_id)
         $sourceItem = DB::table('mp_products')
             ->where('id', $product_id)
             ->where('cpid', $cpid)
-            ->where('user_id', $source_uid)
             ->where('is_deleted', 0)
             ->first();
         
@@ -6744,13 +6779,20 @@ class AnimeService
             Utils::throwError('20003:要推送的项目不存在');
         }
         
-        // 验证目标文件夹
+        // 通过user_id判断源是公共库还是个人库
+        $source_uid = $sourceItem->user_id;
+        $source_is_public = ($source_uid == 0) ? 1 : 0;
+        
+        // 验证目标文件夹并确定目标是公共库还是个人库
         $target_level = 0;
+        $target_uid = $uid; // 默认推送到个人库
+        $target_is_public = 0;
+        
         if ($target_parent_id > 0) {
+            // 查询目标文件夹(只通过cpid查询,不限制user_id)
             $targetParent = DB::table('mp_products')
                 ->where('id', $target_parent_id)
                 ->where('cpid', $cpid)
-                ->where('user_id', $target_uid)
                 ->where('type', 2)
                 ->where('is_deleted', 0)
                 ->first();
@@ -6764,9 +6806,29 @@ class AnimeService
                 Utils::throwError('20003:不能推送到不同类型的文件夹下');
             }
             
+            // 通过user_id判断目标是公共库还是个人库
             $target_level = $targetParent->level;
+            $target_uid = $targetParent->user_id;
+            $target_is_public = ($target_uid == 0) ? 1 : 0;
+        }
+        // 如果 target_parent_id = 0(推送到根目录),需要通过参数判断推送到个人库还是公共库
+        else {
+            $push_to_public = getProp($data, 'push_to_public');
+            if ($push_to_public === '') Utils::throwError('20003:请选择是否推送到公共库');
+            if ($push_to_public) {
+                $target_uid = 0;
+                $target_is_public = 1;
+            }
         }
         
+        // 如果目标是公共库,需要admin权限
+        if ($target_is_public && $role !== 'admin') {
+            Utils::throwError('20003:只有管理员才能推送到公共资产库');
+        }
+        
+        // 权限验证:验证是否符合允许的推送规则
+        $this->validatePushPermission($source_uid, $target_uid, $uid);
+        
         try {
             DB::beginTransaction();
             
@@ -6775,9 +6837,7 @@ class AnimeService
                 $newId = $this->copyProduct($sourceItem, $target_parent_id, $target_level + 1, $cpid, $target_uid);
                 DB::commit();
                 return [
-                    'success' => 1,
-                    'message' => '推送成功',
-                    'new_id' => $newId
+                    'product_id' => $newId,
                 ];
             }
             
@@ -6786,9 +6846,7 @@ class AnimeService
             
             DB::commit();
             return [
-                'success' => 1,
-                'message' => '推送成功',
-                'new_folder_id' => $newFolderId
+                'product_id' => $newFolderId,
             ];
             
         } catch (\Exception $e) {
@@ -6802,6 +6860,50 @@ class AnimeService
     }
     
     /**
+     * 验证推送权限
+     * 允许的推送规则:
+     * 1. 自己推送给自己的个人库(个人库 → 个人库,同一用户)
+     * 2. 公共库推送给自己的个人库(公共库 → 个人库)
+     * 3. 公共库推送给公共库(公共库 → 公共库)
+     * 
+     * @param int $source_uid 源的user_id
+     * @param int $target_uid 目标的user_id
+     * @param int $current_uid 当前用户ID
+     * @throws \Exception
+     */
+    private function validatePushPermission($source_uid, $target_uid, $current_uid) {
+        // 规则1:自己推送给自己的个人库(个人库 → 个人库,同一用户)
+        if ($source_uid == $current_uid && $target_uid == $current_uid) {
+            return; // 允许
+        }
+        
+        // 规则2:公共库推送给自己的个人库(公共库 → 个人库)
+        if ($source_uid == 0 && $target_uid == $current_uid) {
+            return; // 允许
+        }
+        
+        // 规则3:公共库推送给公共库(公共库 → 公共库)
+        if ($source_uid == 0 && $target_uid == 0) {
+            return; // 允许
+        }
+        
+        // 其他情况都不允许
+        if ($source_uid != 0 && $source_uid != $current_uid) {
+            // 源是别人的个人库
+            Utils::throwError('20003:无权限访问该资产');
+        } elseif ($source_uid == $current_uid && $target_uid == 0) {
+            // 个人库推送给公共库(不允许)
+            Utils::throwError('20003:不允许将个人资产推送到公共库');
+        } elseif ($source_uid != 0 && $target_uid != 0 && $source_uid != $target_uid) {
+            // 不同用户的个人库之间推送(不允许)
+            Utils::throwError('20003:不允许推送到其他用户的个人库');
+        } else {
+            // 其他未知情况
+            Utils::throwError('20003:不允许的推送操作');
+        }
+    }
+    
+    /**
      * 复制单个资产
      * @param object $sourceProduct 源资产对象
      * @param int $targetParentId 目标父文件夹ID
@@ -7009,8 +7111,7 @@ class AnimeService
                     $productTaskMap[$product->id] = $product->pic_task_id;
                 } else if($product->url && $product->pic_task_status == '生成成功') {
                     continue;
-                }
-                else {
+                } else {
                     // 有资产没有图片任务
                     $hasAllTasks = false;
                 }