Ver código fonte

feat(mex): 添加农贸市场库存初始化功能

- 新增库存初始化页面和表单
- 实现库存初始化逻辑,为已定价商品创建库存记录
- 添加管理员操作记录,标记为批量注入类型
- 优化工具页面布局,增加初始化库存按钮
- 调整商品回收逻辑,先扣除仓库账户物品再更新库存
AI Assistant 6 meses atrás
pai
commit
f373b5a73f

+ 84 - 2
app/Module/Mex/AdminControllers/MexAdminToolController.php

@@ -3,6 +3,7 @@
 namespace App\Module\Mex\AdminControllers;
 namespace App\Module\Mex\AdminControllers;
 
 
 use App\Module\Mex\Services\MexAdminService;
 use App\Module\Mex\Services\MexAdminService;
+use App\Module\Mex\Logic\MexAdminLogic;
 use Spatie\RouteAttributes\Attributes\Get;
 use Spatie\RouteAttributes\Attributes\Get;
 use Spatie\RouteAttributes\Attributes\Post;
 use Spatie\RouteAttributes\Attributes\Post;
 use UCore\DcatAdmin\AdminController;
 use UCore\DcatAdmin\AdminController;
@@ -64,6 +65,18 @@ class MexAdminToolController extends AdminController
             ->body($this->buildRecycleForm());
             ->body($this->buildRecycleForm());
     }
     }
 
 
+    /**
+     * 初始化库存页面
+     */
+    #[Get('mex-admin-tools/initialize', name: 'dcat.admin.mex-admin-tools.initialize')]
+    public function initialize(Content $content)
+    {
+        return $content
+            ->title('初始化库存')
+            ->description('为所有已定价的商品创建库存记录')
+            ->body($this->buildInitializeForm());
+    }
+
     /**
     /**
      * 处理物品注入
      * 处理物品注入
      */
      */
@@ -156,6 +169,28 @@ class MexAdminToolController extends AdminController
         }
         }
     }
     }
 
 
+    /**
+     * 处理初始化库存请求
+     */
+    #[Post('mex-admin-tools/initialize', name: 'dcat.admin.mex-admin-tools.initialize.store')]
+    public function storeInitialize(Request $request)
+    {
+        try {
+            $result = MexAdminLogic::initializeWarehouse(Admin::user()->id);
+
+            if ($result['success']) {
+                admin_success('初始化成功!', $result['message'] . ',共初始化了 ' . $result['initialized_count'] . ' 个商品的库存记录。');
+                return redirect()->route('dcat.admin.mex-admin-tools.initialize');
+            } else {
+                admin_error('初始化失败', $result['message']);
+                return back()->withInput();
+            }
+        } catch (\Exception $e) {
+            admin_error('初始化失败', $e->getMessage());
+            return back()->withInput();
+        }
+    }
+
     /**
     /**
      * 构建工具页面
      * 构建工具页面
      */
      */
@@ -163,7 +198,7 @@ class MexAdminToolController extends AdminController
     {
     {
         $card = new Card('农贸市场管理工具', '
         $card = new Card('农贸市场管理工具', '
             <div class="row">
             <div class="row">
-                <div class="col-md-6">
+                <div class="col-md-4">
                     <div class="card">
                     <div class="card">
                         <div class="card-body text-center">
                         <div class="card-body text-center">
                             <i class="fa fa-plus-circle fa-3x text-success mb-3"></i>
                             <i class="fa fa-plus-circle fa-3x text-success mb-3"></i>
@@ -175,7 +210,7 @@ class MexAdminToolController extends AdminController
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
-                <div class="col-md-6">
+                <div class="col-md-4">
                     <div class="card">
                     <div class="card">
                         <div class="card-body text-center">
                         <div class="card-body text-center">
                             <i class="fa fa-minus-circle fa-3x text-warning mb-3"></i>
                             <i class="fa fa-minus-circle fa-3x text-warning mb-3"></i>
@@ -187,6 +222,18 @@ class MexAdminToolController extends AdminController
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
+                <div class="col-md-4">
+                    <div class="card">
+                        <div class="card-body text-center">
+                            <i class="fa fa-database fa-3x text-info mb-3"></i>
+                            <h5>初始化库存</h5>
+                            <p class="text-muted">为已定价商品创建库存记录</p>
+                            <a href="' . route('dcat.admin.mex-admin-tools.initialize') . '" class="btn btn-info">
+                                <i class="fa fa-database"></i> 开始初始化
+                            </a>
+                        </div>
+                    </div>
+                </div>
             </div>
             </div>
             
             
             <div class="row mt-4">
             <div class="row mt-4">
@@ -287,4 +334,39 @@ class MexAdminToolController extends AdminController
 
 
         return $form;
         return $form;
     }
     }
+
+    /**
+     * 构建初始化库存表单
+     */
+    private function buildInitializeForm()
+    {
+        $form = new Form();
+
+        $form->action(route('dcat.admin.mex-admin-tools.initialize.store'));
+
+        $form->html('<div class="alert alert-info">
+            <h6><i class="fa fa-info-circle"></i> 初始化说明</h6>
+            <ul class="mb-0">
+                <li>此操作将为所有已启用定价的商品创建库存记录</li>
+                <li>初始库存数量为0,可通过注入操作增加库存</li>
+                <li>只有当库存表为空时才能执行初始化</li>
+                <li>初始化后可以正常进行注入、回收和用户交易</li>
+            </ul>
+        </div>');
+
+        $form->html('<div class="alert alert-warning">
+            <h6><i class="fa fa-exclamation-triangle"></i> 注意事项</h6>
+            <ul class="mb-0">
+                <li>初始化操作只能在库存表为空时执行</li>
+                <li>如果已有库存记录,将无法执行初始化</li>
+                <li>初始化完成后,所有已定价商品的库存都为0</li>
+                <li>操作不可撤销,请确认后再执行</li>
+            </ul>
+        </div>');
+
+        // 添加一个隐藏字段,确保表单可以提交
+        $form->hidden('action')->value('initialize');
+
+        return $form;
+    }
 }
 }

+ 2 - 13
app/Module/Mex/Logic/MexAccountLogic.php

@@ -76,19 +76,8 @@ class MexAccountLogic
                 return ['success' => false, 'message' => '扣除用户物品失败:' . ($consumeResult['message'] ?? '未知错误')];
                 return ['success' => false, 'message' => '扣除用户物品失败:' . ($consumeResult['message'] ?? '未知错误')];
             }
             }
 
 
-            // 3. 给仓库账户添加物品
-            $addResult = ItemService::addItem(self::WAREHOUSE_USER_ID, $itemId, $quantity, [
-                'reason' => 'mex_warehouse_buy',
-                'source_type'    => REWARD_SOURCE_TYPE::MEX_BUY,
-                'source_id'      => $orderId,
-                'order_id' => $orderId,
-                'remark' => "农贸市场仓库收购物品,订单ID:{$orderId}"
-            ]);
-
-            if (!$addResult['success']) {
-                DB::rollBack();
-                return ['success' => false, 'message' => '仓库添加物品失败:' . ($addResult['message'] ?? '未知错误')];
-            }
+            // 3. 仓库账户是虚拟账户,不实际存储物品,只更新统计数据
+            // 物品已从用户扣除,直接进入虚拟仓库统计
 
 
             // 4. 从仓库账户转出资金给用户
             // 4. 从仓库账户转出资金给用户
             $warehouseFundService = new FundService(self::WAREHOUSE_USER_ID, $availableAccountType->value);
             $warehouseFundService = new FundService(self::WAREHOUSE_USER_ID, $availableAccountType->value);

+ 107 - 2
app/Module/Mex/Logic/MexAdminLogic.php

@@ -5,8 +5,11 @@ namespace App\Module\Mex\Logic;
 use App\Module\Mex\Models\MexAdminOperation;
 use App\Module\Mex\Models\MexAdminOperation;
 use App\Module\Mex\Models\MexWarehouse;
 use App\Module\Mex\Models\MexWarehouse;
 use App\Module\Mex\Models\MexTransaction;
 use App\Module\Mex\Models\MexTransaction;
+use App\Module\Mex\Models\MexPriceConfig;
 use App\Module\Mex\Enums\AdminOperationType;
 use App\Module\Mex\Enums\AdminOperationType;
 use App\Module\Mex\Enums\TransactionType;
 use App\Module\Mex\Enums\TransactionType;
+use App\Module\GameItems\Services\ItemService;
+use App\Module\Game\Enums\REWARD_SOURCE_TYPE;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\DB;
 
 
 /**
 /**
@@ -64,7 +67,19 @@ class MexAdminLogic
 
 
                 $beforeQuantity = $warehouse->quantity;
                 $beforeQuantity = $warehouse->quantity;
 
 
-                // 更新仓库库存(注入操作相当于系统买入)
+                // 1. 给仓库账户添加真实物品(确保用户可以买到)
+                $addItemResult = ItemService::addItem(self::WAREHOUSE_USER_ID, $itemId, $quantity, [
+                    'reason' => 'mex_admin_inject',
+                    'source_type' => REWARD_SOURCE_TYPE::ADMIN_GRANT->value,
+                    'source_id' => $adminUserId,
+                    'remark' => "管理员注入物品到农贸市场,管理员ID:{$adminUserId}"
+                ]);
+
+                if (!$addItemResult['success']) {
+                    throw new \Exception('给仓库账户添加物品失败:' . ($addItemResult['message'] ?? '未知错误'));
+                }
+
+                // 2. 更新仓库库存统计(注入操作相当于系统买入)
                 $warehouse->quantity += $quantity;
                 $warehouse->quantity += $quantity;
                 $warehouse->total_buy_quantity += $quantity;
                 $warehouse->total_buy_quantity += $quantity;
                 $warehouse->total_buy_amount = bcadd($warehouse->total_buy_amount, $totalAmount, 5);
                 $warehouse->total_buy_amount = bcadd($warehouse->total_buy_amount, $totalAmount, 5);
@@ -150,7 +165,18 @@ class MexAdminLogic
 
 
                 $beforeQuantity = $warehouse->quantity;
                 $beforeQuantity = $warehouse->quantity;
 
 
-                // 更新仓库库存(回收操作相当于系统卖出)
+                // 1. 从仓库账户扣除真实物品
+                $consumeItemResult = ItemService::consumeItem(self::WAREHOUSE_USER_ID, $itemId, null, $quantity, [
+                    'reason' => 'mex_admin_recycle',
+                    'source_id' => $adminUserId,
+                    'remark' => "管理员从农贸市场回收物品,管理员ID:{$adminUserId}"
+                ]);
+
+                if (!$consumeItemResult['success']) {
+                    throw new \Exception('从仓库账户扣除物品失败:' . ($consumeItemResult['message'] ?? '未知错误'));
+                }
+
+                // 2. 更新仓库库存统计(回收操作相当于系统卖出)
                 $warehouse->quantity -= $quantity;
                 $warehouse->quantity -= $quantity;
                 $warehouse->total_sell_quantity += $quantity;
                 $warehouse->total_sell_quantity += $quantity;
                 $warehouse->total_sell_amount = bcadd($warehouse->total_sell_amount, $totalAmount, 5);
                 $warehouse->total_sell_amount = bcadd($warehouse->total_sell_amount, $totalAmount, 5);
@@ -302,4 +328,83 @@ class MexAdminLogic
             'end_date' => now(),
             'end_date' => now(),
         ];
         ];
     }
     }
+
+    /**
+     * 初始化库存
+     * 为所有已启用定价的商品创建库存记录(库存为0)
+     *
+     * @param int $adminUserId 管理员用户ID
+     * @return array 初始化结果
+     */
+    public static function initializeWarehouse(int $adminUserId): array
+    {
+        try {
+            return DB::transaction(function () use ($adminUserId) {
+                // 1. 检查是否已有库存记录
+                $existingWarehouseCount = MexWarehouse::count();
+                if ($existingWarehouseCount > 0) {
+                    return [
+                        'success' => false,
+                        'message' => '库存表不为空,无法初始化。当前已有 ' . $existingWarehouseCount . ' 条库存记录。'
+                    ];
+                }
+
+                // 2. 获取所有已启用的定价配置
+                $priceConfigs = MexPriceConfig::where('is_enabled', true)->get();
+                if ($priceConfigs->isEmpty()) {
+                    return [
+                        'success' => false,
+                        'message' => '没有找到已启用的定价配置,无法初始化库存。'
+                    ];
+                }
+
+                $initializedItems = [];
+                $now = now();
+
+                // 3. 为每个已定价的商品创建库存记录
+                foreach ($priceConfigs as $priceConfig) {
+                    $warehouse = MexWarehouse::create([
+                        'item_id' => $priceConfig->item_id,
+                        'quantity' => 0,
+                        'total_buy_amount' => '0.00000',
+                        'total_sell_amount' => '0.00000',
+                        'total_buy_quantity' => 0,
+                        'total_sell_quantity' => 0,
+                        'last_transaction_at' => $now,
+                    ]);
+
+                    $initializedItems[] = [
+                        'item_id' => $priceConfig->item_id,
+                        'min_price' => $priceConfig->min_price,
+                        'max_price' => $priceConfig->max_price,
+                        'warehouse_id' => $warehouse->id,
+                    ];
+                }
+
+                // 4. 创建管理员操作记录
+                $operation = MexAdminOperation::create([
+                    'admin_user_id' => $adminUserId,
+                    'operation_type' => AdminOperationType::INJECT, // 使用注入类型记录初始化操作
+                    'item_id' => 0, // 特殊标记:0表示批量初始化
+                    'quantity' => count($initializedItems),
+                    'price' => '0.00000',
+                    'total_amount' => '0.00000',
+                    'before_warehouse_quantity' => 0,
+                    'after_warehouse_quantity' => 0,
+                    'transaction_id' => null,
+                    'remark' => "初始化农贸市场库存,为 " . count($initializedItems) . " 个商品创建库存记录",
+                ]);
+
+                return [
+                    'success' => true,
+                    'message' => '库存初始化成功',
+                    'operation_id' => $operation->id,
+                    'initialized_count' => count($initializedItems),
+                    'initialized_items' => $initializedItems,
+                ];
+            });
+        } catch (\Exception $e) {
+            return ['success' => false, 'message' => '库存初始化失败:' . $e->getMessage()];
+        }
+    }
 }
 }