diff --git a/app/admin/controller/LocalController.php b/app/admin/controller/LocalController.php
new file mode 100644
index 000000000..6a592345d
--- /dev/null
+++ b/app/admin/controller/LocalController.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace app\admin\controller;
+
+use app\common\model\store_category\StoreCategory;
+use app\common\model\store_product\StoreProduct;
+use PhpOffice\PhpSpreadsheet\IOFactory;
+use support\Redis;
+
+class LocalController extends BaseAdminController
+{
+
+    public $notNeedLogin = ['index'];
+
+    public function index()
+    {
+        $file = $this->request->file('file');
+        $reader = IOFactory::createReader('Xlsx');
+        $spreadsheet = $reader->load($file->getRealPath());
+        $data = $spreadsheet->getActiveSheet()->toArray();
+        $updateCount = 0;
+        $finishCount = Redis::get('finishCount');
+        $finishCount = empty($finishCount) ? 0 : $finishCount;
+        if ($finishCount >= count($data)) {
+            echo '数据已更新完成';
+            return;
+        }
+        $max = $finishCount + 100;
+        foreach ($data as $k => $row) {
+            if ($k < (1 + $finishCount) || empty($row[0])) {
+                continue;
+            }
+            if ($k > $max) {
+                break;
+            }
+            $product = StoreProduct::where('id', $row[0])->field('id,store_name,top_cate_id,two_cate_id,cate_id')->findOrEmpty()->toArray();
+            if (empty($product)) {
+                continue;
+            }
+            $result = $this->updateProduct($product, $row);
+            if ($result) {
+                $updateCount++;
+            }
+        }
+        Redis::set('finishCount', 100 + $finishCount);
+        echo '更新成功:' . $updateCount . '条';
+    }
+
+    public function updateProduct($product, $row)
+    {
+        $topCateName = rtrim($row[1], '类');
+        $secondCateName = rtrim($row[2], '类');
+        $cateName = rtrim($row[3], '类');
+        $topCate = StoreCategory::where('name', $topCateName)->value('id');
+        $updateData = [];
+        if (!empty($topCate) && $topCate != $product['top_cate_id']) {
+            $updateData['top_cate_id'] = $topCate;
+        }
+        $secondCateId = StoreCategory::where('pid', $topCate)->where('name', $secondCateName)->value('id');
+        if (empty($secondCateId)) {
+            $secondCate = new StoreCategory();
+            $secondCate->name = $secondCateName;
+            $secondCate->pid = $topCate;
+            $secondCate->save();
+            $secondCateId = $secondCate->id;
+        }
+        if ($secondCateId != $product['two_cate_id']) {
+            $updateData['two_cate_id'] = $secondCateId;
+        }
+        $cateId = StoreCategory::where('pid', $secondCateId)->where('name', $cateName)->value('id');
+        if (empty($cateId)) {
+            $cate = new StoreCategory();
+            $cate->name = $cateName;
+            $cate->pid = $secondCateId;
+            $cate->save();
+            $cateId = $cate->id;
+        }
+        if ($cateId != $product['cate_id']) {
+            $updateData['cate_id'] = $cateId;
+        }
+        if (!empty($updateData)) {
+            StoreProduct::where('id', $row[0])->update($updateData);
+            echo '更新成功ID:' . $row[0] . PHP_EOL;
+            return true;
+        }
+        return false;
+    }
+
+}
\ No newline at end of file