diff --git a/app/admin/controller/Category.php b/app/admin/controller/Category.php new file mode 100644 index 00000000..f652e730 --- /dev/null +++ b/app/admin/controller/Category.php @@ -0,0 +1,88 @@ + +// +---------------------------------------------------------------------- +declare (strict_types=1); + +namespace app\admin\controller; + +use think\response\Json; +use app\store\model\Category as CategoryModel; + +/** + * 商品分类 + * Class Category + * @package app\store\controller\goods + */ +class Category extends Controller +{ + /** + * 商品分类列表 + * @return Json + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function list(): Json + { + $model = new CategoryModel; + $list = $model->getList(['store_id' =>0]); + return $this->renderSuccess(compact('list')); + } + + /** + * 删除商品分类 + * @param int $categoryId + * @return Json + */ + public function delete(int $categoryId): Json + { + // 分类详情 + $model = CategoryModel::detail($categoryId); + if (!$model->remove()) { + return $this->renderError($model->getError() ?: '删除失败'); + } + return $this->renderSuccess('删除成功'); + } + + /** + * 添加商品分类 + * @return Json + */ + public function add(): Json + { + // 新增记录 + $model = new CategoryModel; + $params = $this->postForm(); + $params['store_id'] = 0; + if ($model->add($params)) { + return $this->renderSuccess('添加成功'); + } + return $this->renderError($model->getError() ?: '添加失败'); + } + + /** + * 编辑商品分类 + * @param int $categoryId + * @return Json + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function edit(int $categoryId): Json + { + // 分类详情 + $model = CategoryModel::detail($categoryId, ['image']); + // 更新记录 + if ($model->edit($this->postForm())) { + return $this->renderSuccess('更新成功'); + } + return $this->renderError($model->getError() ?: '更新失败'); + } +} diff --git a/app/admin/controller/goods/Import.php b/app/admin/controller/goods/Import.php new file mode 100644 index 00000000..c338b42f --- /dev/null +++ b/app/admin/controller/goods/Import.php @@ -0,0 +1,71 @@ + +// +---------------------------------------------------------------------- +declare (strict_types=1); + +namespace app\admin\controller\goods; + +use think\response\Json; +use app\admin\controller\Controller; +use app\store\model\goods\Import as ImportModel; +use cores\exception\BaseException; + +/** + * 商品批量导入管理 + * Class Import + * @package app\store\controller\goods + */ +class Import extends Controller +{ + /** + * 获取列表记录 + * @return Json + * @throws \think\db\exception\DbException + */ + public function list(): Json + { + $params = $this->request->param(); + $params['store_id'] = 0; + $model = new ImportModel; + $list = $model->getList($params); + return $this->renderSuccess(compact('list')); + } + + /** + * 执行批量导入 + * @return Json + * @throws BaseException + * @throws \PhpOffice\PhpSpreadsheet\Exception + * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception + */ + public function batch(): Json + { + // 新增记录 + $model = new ImportModel; + if ($model->adminBatch($this->postData())) { + return $this->renderSuccess('已添加到导入任务中,请在历史导入记录中查看结果'); + } + return $this->renderError($model->getError() ?: '操作失败'); + } + + /** + * 删除记录 + * @param int $id + * @return Json + */ + public function delete(int $id): Json + { + $model = ImportModel::detail($id); + if (!$model->setDelete()) { + return $this->renderError($model->getError() ?: '删除失败'); + } + return $this->renderSuccess('删除成功'); + } +} diff --git a/app/api/service/Goods.php b/app/api/service/Goods.php index 00753a70..8746e856 100644 --- a/app/api/service/Goods.php +++ b/app/api/service/Goods.php @@ -137,8 +137,10 @@ class Goods extends GoodsService return []; } $list = $goodsList->toArray(); - - $list['data'] = $this->formatGoodsList($goodsList); + // echo "
";
+        // print_r($list);
+        // exit()
+        $list['data'] = $this->newFormatGoodsList($list['data']);
         return $list;
 
     }
@@ -317,6 +319,46 @@ class Goods extends GoodsService
         }
         return $price;
     }
+    /**
+     * 格式化商品列表
+     * @param $goodsList
+     * @return array
+     */
+    private function newFormatGoodsList($goodsList): array
+    {
+       
+        $data = [];
+        foreach ($goodsList as $goods) {
+            $temp = [
+                'goods_id' => $goods['goods_id'],
+                'goods_name' => $goods['goods_name'],
+                'selling_point' => $goods['selling_point'],
+                'goods_image' => $goods['goods_image'],
+                'goods_price_min' => $goods['goods_price_min'],//商品价格
+                'goods_price_max' => $goods['goods_price_max'],
+                'line_price_min' => $goods['goods_price_min'],//划线价格等于市场价
+                'line_price_max' => $goods['line_price_max'],
+                'goods_sales' => $goods['goods_sales'],
+                'remaizhishu' => $goods['remaizhishu'],
+            ];
+            
+            if (UserService::isLogin()) {
+                $catService = new \app\store\model\GoodsCategoryRel();
+                $catIds = $catService->where(['goods_id' => $goods['goods_id']])->column('category_id');
+                //价格判断
+                if (UserService::isstore()) {
+                    $temp['goods_price_min'] = $goods['cost_price_min'];
+                } elseif (UserService::isPlusMember()) {
+                   $temp['goods_price_min'] = \app\common\model\PriceSet::membershipPrice($goods['goods_price_min'], $goods['cost_price_min'], $catIds);
+                } elseif (UserService::isDealerMember()) {
+                    $priceArr = \app\common\model\PriceSet::distributionPrice($goods['goods_price_min'], $goods['cost_price_min'], $catIds);
+                    $temp['goods_price_min'] = $priceArr['goods_price_min_dealer'];
+                }
+            }
+            $data[] = $temp;
+        }
+        return $data;
+    }
     /**
      * 格式化商品列表
      * @param $goodsList
diff --git a/app/common/model/Category.php b/app/common/model/Category.php
index cefeeff2..bd49e997 100644
--- a/app/common/model/Category.php
+++ b/app/common/model/Category.php
@@ -94,6 +94,7 @@ class Category extends BaseModel
         if (isset($param['is_in_store']) && $param['is_in_store'] != "") {
             $filter[] = ['is_in_store', '=', $params['is_in_store'] ?? 0];
         }
+        isset($params['store_id']) && $params['store_id'] > -1 && $filter[] = ['store_id', '=', (int)$params['store_id']];
 
         // 查询列表数据
         return $this->with(['image'])
diff --git a/app/job/controller/goods/AdminImport.php b/app/job/controller/goods/AdminImport.php
new file mode 100644
index 00000000..8a77bd0f
--- /dev/null
+++ b/app/job/controller/goods/AdminImport.php
@@ -0,0 +1,49 @@
+
+// +----------------------------------------------------------------------
+declare (strict_types=1);
+
+namespace app\job\controller\goods;
+
+use app\job\service\goods\AdminImport as GoodsAdminImportService;
+use cores\BaseJob;
+use cores\traits\QueueTrait;
+use cores\exception\BaseException;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+
+/**
+ * 队列任务:商品批量导入
+ * Class Import
+ * @package app\job\controller
+ */
+class AdminImport extends BaseJob
+{
+    use QueueTrait;
+
+    /**
+     * 消费队列任务:商品导入
+     * @param array $data 参数 [index队列顺序;totalCount商品总数量;list商品列表;storeId商城ID]
+     * @return bool 返回结果
+     * @throws BaseException
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     */
+    public function handle(array $data): bool
+    {
+        $time = date('H:i:s');
+        echo "\n  ---- Import ----  {$time} ----   \n";
+
+        $service = new GoodsAdminImportService;
+        return $service->batch($data['list'], $data['recordId'], $data['storeId']);
+    }
+}
\ No newline at end of file
diff --git a/app/job/service/goods/AdminImport.php b/app/job/service/goods/AdminImport.php
new file mode 100644
index 00000000..67806a23
--- /dev/null
+++ b/app/job/service/goods/AdminImport.php
@@ -0,0 +1,358 @@
+
+// +----------------------------------------------------------------------
+declare (strict_types=1);
+
+namespace app\job\service\goods;
+
+use app\common\library\helper;
+use app\common\service\BaseService;
+use app\common\model\Spec as SpecModel;
+use app\common\model\Goods as GoodsModel;
+use app\common\model\Category as CategoryModel;
+use app\common\model\GoodsSku as GoodsSkuModel;
+use app\common\model\Delivery as DeliveryModel;
+use app\common\model\UploadFile as UploadFileModel;
+use app\common\model\GoodsImage as GoodsImageModel;
+use app\common\model\goods\Import as GoodsImportModel;
+use app\common\model\GoodsSpecRel as GoodsSpecRelModel;
+use app\common\model\goods\Service as GoodsServiceModel;
+use app\common\model\goods\ServiceRel as GoodsServiceRelModel;
+use app\common\model\GoodsCategoryRel as GoodsCategoryRelModel;
+use app\common\enum\goods\Status as GoodsStatusEnum;
+use app\common\enum\goods\GoodsType as GoodsTypeEnum;
+use app\common\enum\goods\SpecType as GoodsSpecTypeEnum;
+use app\common\enum\goods\ImportStatus as GoodsImportStatusEnum;
+use app\common\enum\goods\DeductStockType as DeductStockTypeEnum;
+use app\common\validate\goods\Import as GoodsImportValidate;
+use cores\exception\BaseException;
+
+/**
+ * 服务类:商品批量导入
+ * Class Import
+ * @package app\job\service\goods
+ */
+class AdminImport extends BaseService
+{
+    /**
+     * 错误日志记录
+     * @var array
+     */
+    private array $errorLog = [];
+
+    /**
+     * 导入成功的数量
+     * @var int
+     */
+    private int $successCount = 0;
+
+    /**
+     * 商品主信息字段映射
+     * @var string[]
+     */
+    private array $mapGoods = [
+        'goods_name' => 'B',
+        'goods_no' => 'C',
+        'categoryIds' => 'D',
+        'imagesIds' => 'E',
+        'delivery_id' => 'F',
+        'status' => 'G',
+        'sort' => 'N',
+        'deduct_stock_type' => 'O',
+        'sales_initial' => 'P',
+        'serviceIds' => 'Q',
+        'is_points_gift' => 'R',
+        'is_points_discount' => 'S',
+        'is_enable_grade' => 'T',
+    ];
+
+    /**
+     * 商品SKU字段映射
+     * @var string[]
+     */
+    private array $mapSku = [
+        'specText' => 'H',
+        'goods_price' => 'I',
+        'line_price' => 'J',
+        'stock_num' => 'K',
+        'goods_weight' => 'L',
+        'goods_sku_no' => 'M',
+    ];
+
+    /**
+     * 批量导入商品
+     * @param array $list
+     * @param int $recordId
+     * @param int $storeId
+     * @return bool
+     * @throws BaseException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function batch(array $list, int $recordId, int $storeId): bool
+    {
+        foreach ($list as $item) {
+            // 生成商品数据(用于写入数据库)
+            $data = $this->createData($item, $storeId);
+            // 数据验证
+            if (!$this->validateGoodsData($data, $storeId)) {
+                $this->errorLog[] = ['goodsSn' => $item['A'], 'message' => $this->getError()];
+                continue;
+            }
+            // 事务处理:添加商品
+            $model = new GoodsModel();
+            $model->transaction(function () use ($model, $data, $storeId) {
+                // 添加商品
+                $model->save($data);
+                // 新增商品与分类关联
+                GoodsCategoryRelModel::increased((int)$model['goods_id'], $data['categoryIds'], $storeId);
+                // 新增商品与图片关联
+                GoodsImageModel::increased((int)$model['goods_id'], $data['imagesIds'], $storeId);
+                // 新增商品与规格关联
+                GoodsSpecRelModel::increased((int)$model['goods_id'], $data['newSpecList'], $storeId);
+                // 新增商品sku信息
+                GoodsSkuModel::add((int)$model['goods_id'], $data['spec_type'], $data['newSkuList'], $storeId);
+                // 新增服务与承诺关联
+                GoodsServiceRelModel::increased((int)$model['goods_id'], $data['serviceIds'], $storeId);
+            });
+            // 记录导入成功
+            $this->successCount++;
+        }
+        // 更新导入记录
+        $this->updateRecord($recordId, \count($list));
+        return true;
+    }
+
+    /**
+     * 更新导入记录
+     * @param int $recordId 商品导入记录ID
+     * @param int $currentCount 当前任务导入的商品总量
+     * @return void
+     */
+    private function updateRecord(int $recordId, int $currentCount)
+    {
+        // 获取导入记录
+        $model = GoodsImportModel::detail($recordId);
+        // 计算导入失败的数量
+        $failCount = $currentCount - $this->successCount;
+        // 更新导入记录
+        $model->save([
+            'success_count' => $model['success_count'] + $this->successCount,
+            'fail_count' => $model['fail_count'] + $failCount,
+            'fail_log' => array_merge($model['fail_log'], $this->errorLog),
+        ]);
+        // 判断是否为最后一次队列
+        if ($model['total_count'] <= ($model['success_count'] + $model['fail_count'])) {
+            $model->save(['end_time' => \time(), 'status' => GoodsImportStatusEnum::COMPLETED]);
+        }
+    }
+
+    /**
+     * 商品数据验证
+     * @param array $data
+     * @param int $storeId
+     * @return bool
+     */
+    private function validateGoodsData(array $data, int $storeId): bool
+    {
+        // 验证商品信息:商品名称、分类ID集、图片ID集、运费模板ID
+        $validate = new GoodsImportValidate;
+        if (!$validate->scene('goods')->check($data)) {
+            $this->setError($validate->getError());
+            return false;
+        }
+        // 验证SKU信息:商品价格、库存数量、商品重量
+        $skuList = $data['spec_type'] == GoodsSpecTypeEnum::MULTI ? $data['newSkuList'] : [$data['newSkuList']];
+        foreach ($skuList as $item) {
+            $validate = new GoodsImportValidate;
+            if (!$validate->scene('skuInfo')->check($item)) {
+                $this->setError($validate->getError());
+                return false;
+            }
+        }
+        // 验证运费模板ID是否存在
+        if (!DeliveryModel::checkDeliveryId((int)$data['delivery_id'], $storeId)) {
+            $this->setError('运费模板ID不存在');
+            return false;
+        }
+        if ($data['spec_type'] == GoodsSpecTypeEnum::MULTI) {
+            // 判断用户填写的SKU数量是否正确
+            $shouldSkuTotal = SpecModel::calcSkuListTotal($data['specData']['specList']);
+            $originalSkuTotal = \count($data['specData']['skuList']);
+            if ($shouldSkuTotal !== $originalSkuTotal) {
+                $this->setError('商品SKU数量不正确');
+                return false;
+            }
+            // 判断商品SKU是否存在重复规格
+            $goodsSkuIdArr = helper::getArrayColumn($data['newSkuList'], 'goods_sku_id');
+            if (count($data['newSkuList']) != count(array_unique($goodsSkuIdArr))) {
+                $this->setError('商品SKU存在重复的规格值');
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 生成商品数据(用于写入数据库)
+     * @param array $original
+     * @param int $storeId
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    private function createData(array $original, int $storeId): array
+    {
+        // 商品规格
+        $specType = isset($original['skuList']) ? GoodsSpecTypeEnum::MULTI : GoodsSpecTypeEnum::SINGLE;
+        // 整理商品数据
+        $data = [
+            'goods_type' => GoodsTypeEnum::PHYSICAL,
+            'goods_name' => $original[$this->mapGoods['goods_name']],
+            'goods_no' => $original[$this->mapGoods['goods_no']],
+            'spec_type' => $specType,
+            'delivery_id' => $original[$this->mapGoods['delivery_id']],
+            'sort' => $original[$this->mapGoods['sort']],
+            'sales_initial' => $original[$this->mapGoods['sales_initial']],
+            'deduct_stock_type' => $original[$this->mapGoods['deduct_stock_type']] === '付款减库存' ? DeductStockTypeEnum::PAYMENT
+                : DeductStockTypeEnum::CREATE,
+            'is_points_gift' => $original[$this->mapGoods['is_points_gift']] === '关闭' ? 0 : 1,
+            'is_points_discount' => $original[$this->mapGoods['is_points_discount']] === '关闭' ? 0 : 1,
+            'is_enable_grade' => $original[$this->mapGoods['is_enable_grade']] === '关闭' ? 0 : 1,
+            'status' => $original['G'] === '下架' ? GoodsStatusEnum::OFF_SALE : GoodsStatusEnum::ON_SALE,
+            'categoryIds' => $this->ids2array($original[$this->mapGoods['categoryIds']]),
+            'imagesIds' => $this->ids2array($original[$this->mapGoods['imagesIds']]),
+            'serviceIds' => $this->ids2array($original[$this->mapGoods['serviceIds']]),
+            // 下面是默认数据, 没有会报错
+            'content' => '',
+            'alone_grade_equity' => [],
+            'newSpecList' => [],
+            'newSkuList' => [],
+            'store_id' => $storeId,
+        ];
+        // 规格和sku数据处理
+        if ($data['spec_type'] === GoodsSpecTypeEnum::MULTI) {
+            $specList = $this->createSpecList($original['skuList']);
+            $data['specData']['specList'] = $specList;
+            $data['specData']['skuList'] = $this->createSkuList($original['skuList'], $specList);
+            // 生成多规格数据 (携带id)
+            $data['newSpecList'] = SpecModel::getNewSpecList($data['specData']['specList'], $storeId);
+            // 生成skuList (携带goods_sku_id)
+            $data['newSkuList'] = GoodsSkuModel::getNewSkuList($data['newSpecList'], $data['specData']['skuList']);
+        } elseif ($data['spec_type'] === GoodsSpecTypeEnum::SINGLE) {
+            // 生成skuItem
+            $data['newSkuList'] = [
+                'goods_price' => $original[$this->mapSku['goods_price']],
+                'line_price' => $original[$this->mapSku['line_price']],
+                'stock_num' => $original[$this->mapSku['stock_num']],
+                'goods_weight' => $original[$this->mapSku['goods_weight']],
+                // 'goods_sku_no' => $original[$this->mapSku['goods_sku_no']],
+            ];
+        }
+        // 整理商品的价格和库存总量
+        if ($data['spec_type'] === GoodsSpecTypeEnum::MULTI) {
+            $data['stock_total'] = GoodsSkuModel::getStockTotal($data['specData']['skuList']);
+            [$data['goods_price_min'], $data['goods_price_max']] = GoodsSkuModel::getGoodsPrices($data['specData']['skuList']);
+            [$data['line_price_min'], $data['line_price_max']] = GoodsSkuModel::getLinePrices($data['specData']['skuList']);
+        } elseif ($data['spec_type'] === GoodsSpecTypeEnum::SINGLE) {
+            $data['goods_price_min'] = $data['goods_price_max'] = $original[$this->mapSku['goods_price']];
+            $data['line_price_min'] = $data['line_price_max'] = $original[$this->mapSku['line_price']];
+            $data['stock_total'] = $original[$this->mapSku['stock_num']];
+        }
+        // 过滤不存在的ID集数据
+        $data['categoryIds'] = CategoryModel::filterCategoryIds($data['categoryIds'], $storeId);
+        $data['imagesIds'] = UploadFileModel::filteFileIds($data['imagesIds'], $storeId);
+        $data['serviceIds'] = GoodsServiceModel::filterServiceIds($data['serviceIds'], $storeId);
+        return $data;
+    }
+
+    /**
+     * ID集字符串转换成数组
+     * @param string $value
+     * @return array|false|string[]
+     */
+    private function ids2array(string $value)
+    {
+        return !empty($value) ? \explode(',', $value) : [];
+    }
+
+    /**
+     * 创建标准的商品SKU数据
+     * @param array $originalSkuList
+     * @param array $specList
+     * @return array
+     */
+    private function createSkuList(array $originalSkuList, array $specList): array
+    {
+        $data = [];
+        foreach ($originalSkuList as $item) {
+            // 设置skuKeys数据
+            foreach ($item['specNames'] as $spec) {
+                $specGroup = helper::arraySearch($specList, 'spec_name', $spec[0]);
+                $specValue = helper::arraySearch($specGroup['valueList'], 'spec_value', $spec[1]);
+                $item['skuKeys'][] = [
+                    'groupKey' => $specGroup['key'],
+                    'valueKey' => $specValue['key']
+                ];
+            }
+            // 整理SKU数据
+            $data[] = [
+                'image_id' => 0,
+                'goods_price' => $item[$this->mapSku['goods_price']],
+                'line_price' => $item[$this->mapSku['line_price']],
+                'stock_num' => $item[$this->mapSku['stock_num']],
+                'goods_weight' => $item[$this->mapSku['goods_weight']],
+                'goods_sku_no' => $item[$this->mapSku['goods_sku_no']],
+                'skuKeys' => $item['skuKeys'],
+            ];
+        }
+        return $data;
+    }
+
+    /**
+     * 创建标准的商品规格数据(树状)
+     * @param array $originalSkuList
+     * @return array
+     */
+    private function createSpecList(array &$originalSkuList): array
+    {
+        // 生成规格数据
+        $data = [];
+        foreach ($originalSkuList as &$item) {
+            $tempArr1 = \explode(',', $item['H']);  // ['颜色:白色', '尺码:小']
+            foreach ($tempArr1 as $val) {
+                $tempArr2 = \explode(':', $val);  // ['颜色','白色']
+                $data[$tempArr2[0]][$tempArr2[1]] = 1;
+                $item['specNames'][] = $tempArr2;
+            }
+        }
+        // 整理为specList格式
+        $specList = [];
+        foreach ($data as $specName => $specValues) {
+            $groupKey = \count($specList);
+            $valueList = [];
+            foreach ($specValues as $specValue => $key) {
+                $valueList[] = [
+                    'key' => \count($valueList),
+                    'groupKey' => $groupKey,
+                    'spec_value' => $specValue,
+                ];
+            }
+            $specList[] = [
+                'key' => $groupKey,
+                'spec_name' => $specName,
+                'valueList' => $valueList,
+            ];
+        }
+        return $specList;
+    }
+}
\ No newline at end of file
diff --git a/app/store/model/Category.php b/app/store/model/Category.php
index 99ab22a2..908a4997 100644
--- a/app/store/model/Category.php
+++ b/app/store/model/Category.php
@@ -28,7 +28,7 @@ class Category extends CategoryModel
      */
     public function add($data): bool
     {
-        $data['store_id'] = self::$storeId;
+        $data['store_id'] = $data['store_id'] ?? self::$storeId;
         return $this->save($data);
     }
 
diff --git a/app/store/model/goods/Import.php b/app/store/model/goods/Import.php
index e855c62d..259de050 100644
--- a/app/store/model/goods/Import.php
+++ b/app/store/model/goods/Import.php
@@ -15,7 +15,7 @@ namespace app\store\model\goods;
 use think\Paginator;
 use think\db\exception\DbException;
 use PhpOffice\PhpSpreadsheet\Exception;
-use app\job\controller\goods\Import as GoodsImportJob;
+use app\job\controller\goods\AdminImport as GoodsAdminImportJob;
 use app\common\enum\goods\ImportStatus as GoodsImportStatusEnum;
 use app\common\library\FileLocal;
 use app\common\library\helper;
@@ -56,8 +56,87 @@ class Import extends ImportModel
         // 检索查询条件
         $filter = [];
         $params['status'] > -1 && $filter[] = ['status', '=', (int)$params['status']];
+        isset($params['store_id']) && $params['store_id'] > -1 && $filter[] = ['store_id', '=', (int)$params['store_id']];
         return $filter;
     }
+    /**
+     * 执行批量导入
+     * @param array $form
+     * @return bool
+     * @throws BaseException
+     * @throws Exception
+     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
+     */
+    public function adminBatch(array $form): bool
+    {
+        // 读取excel文件内容
+        $execlData = $this->readExecl();
+        // 验证导入的商品数量是否合法
+        $this->checkLimit($execlData);
+        // 格式化导入的商品列表数据
+        $goodsList = $this->adminFormatGoodsList($execlData);
+        // echo "
";
+        // print_r($goodsList);
+        // exit();
+        //总后台的店铺id设置为0
+        self::$storeId = 0;
+        // 新增商品导入记录
+        $recordId = $this->addRecord(\count($goodsList));
+        // 调度计划任务
+        $this->adminDispatchJob($goodsList, $recordId);
+        return true;
+    }
+    /**
+     * 调度队列服务执行商品导入
+     * @param array $goodsList 商品列表
+     * @param int $recordId 商品导入记录ID
+     * @return void
+     */
+    private function adminDispatchJob(array $goodsList, int $recordId)
+    {
+        // 分批每次导入20条
+        $limit = 20;
+        // 根据商品总数量计算需要的队列任务数量
+        $jobCount = \count($goodsList) / $limit;
+        // 逐次发布队列任务
+        for ($i = 0; $i < $jobCount; $i++) {
+            $data = array_slice($goodsList, $i * $limit, $limit);
+            GoodsAdminImportJob::dispatch([
+                'list' => $data,
+                'recordId' => $recordId,
+                'storeId' => self::$storeId,
+            ]);
+        }
+    }
+    /**
+     * 格式化导入的商品列表数据
+     * @param array $execlData
+     * @return array
+     */
+    private function adminFormatGoodsList(array $execlData): array
+    {
+        $goodsList = [];
+        foreach ($execlData as $row) {
+            // 不存在商品序号的记录视为空行跳过
+            if (!is_numeric($row['A'])) {
+                continue;
+            }
+            // SKU信息
+            $skuInfo = helper::pick($row, ['G', 'H', 'I', 'J', 'K', 'L', 'M', 'N']);
+            // 商品数据里不存在相同序号, 代表是第一次记录
+            if (!isset($goodsList[$row['A']])) {
+                $goodsList[$row['A']] = $row;
+                // 存在规格值组合则商品是多规格
+                if (!empty($row['H'])) {
+                    $goodsList[$row['A']]['skuList'] = [$skuInfo];
+                }
+            } elseif (isset($goodsList[$row['A']]['skuList'])) {
+                // 否则代表是多规格商品的SKU
+                $goodsList[$row['A']]['skuList'][] = $skuInfo;
+            }
+        }
+        return array_values($goodsList);
+    }
 
     /**
      * 执行批量导入
@@ -121,7 +200,7 @@ class Import extends ImportModel
         ]);
         return (int)$this['id'];
     }
-
+    
     /**
      * 格式化导入的商品列表数据
      * @param array $execlData