Kaynağa Gözat

Merge branch 'v5.0.0dev' of https://gitee.com/ZhongBangKeJi/CRMEB into v5.0.0dev

From-wh 2 yıl önce
ebeveyn
işleme
63ecfbdd92
100 değiştirilmiş dosya ile 3881 ekleme ve 234 silme
  1. 1 0
      .gitignore
  2. 22 18
      crmeb/app/adminapi/AdminApiExceptionHandle.php
  3. 15 2
      crmeb/app/adminapi/controller/v1/setting/SystemCity.php
  4. 67 0
      crmeb/app/adminapi/controller/v1/setting/SystemCrud.php
  5. 11 1
      crmeb/app/adminapi/controller/v1/setting/SystemMenus.php
  6. 167 0
      crmeb/app/adminapi/controller/v1/setting/SystemRoute.php
  7. 156 0
      crmeb/app/adminapi/controller/v1/setting/SystemRouteCate.php
  8. 23 0
      crmeb/app/adminapi/controller/v1/system/SystemFile.php
  9. 14 4
      crmeb/app/adminapi/middleware/AdminAuthTokenMiddleware.php
  10. 1 1
      crmeb/app/adminapi/route/cms.php
  11. 5 5
      crmeb/app/adminapi/route/common.php
  12. 35 0
      crmeb/app/adminapi/route/crud.php
  13. 9 9
      crmeb/app/adminapi/route/file.php
  14. 4 3
      crmeb/app/adminapi/route/product.php
  15. 4 1
      crmeb/app/adminapi/route/route.php
  16. 2 0
      crmeb/app/adminapi/route/setting.php
  17. 25 0
      crmeb/app/adminapi/route/system.php
  18. 5 2
      crmeb/app/api/controller/v1/PublicController.php
  19. 16 5
      crmeb/app/api/middleware/AuthTokenMiddleware.php
  20. 3 0
      crmeb/app/api/route/v1.php
  21. 21 4
      crmeb/app/dao/BaseDao.php
  22. 12 1
      crmeb/app/dao/shipping/SystemCityDao.php
  23. 38 0
      crmeb/app/dao/system/SystemCrudDao.php
  24. 40 0
      crmeb/app/dao/system/SystemRouteCateDao.php
  25. 40 0
      crmeb/app/dao/system/SystemRouteDao.php
  26. 23 0
      crmeb/app/dao/system/log/SystemFileInfoDao.php
  27. 15 6
      crmeb/app/http/middleware/BaseMiddleware.php
  28. 3 3
      crmeb/app/kefuapi/middleware/KefuAuthTokenMiddleware.php
  29. 38 0
      crmeb/app/model/system/SystemCrud.php
  30. 89 0
      crmeb/app/model/system/SystemRoute.php
  31. 44 0
      crmeb/app/model/system/SystemRouteCate.php
  32. 28 0
      crmeb/app/model/system/log/SystemFileInfo.php
  33. 3 2
      crmeb/app/outapi/middleware/AuthTokenMiddleware.php
  34. 9 3
      crmeb/app/services/order/StoreCartServices.php
  35. 11 2
      crmeb/app/services/order/StoreOrderSplitServices.php
  36. 33 0
      crmeb/app/services/shipping/SystemCityServices.php
  37. 301 0
      crmeb/app/services/system/SystemCrudServices.php
  38. 114 0
      crmeb/app/services/system/SystemRouteCateServices.php
  39. 254 0
      crmeb/app/services/system/SystemRouteServices.php
  40. 1 1
      crmeb/app/services/system/lang/LangCodeServices.php
  41. 24 0
      crmeb/app/services/system/log/SystemFileInfoServices.php
  42. 40 2
      crmeb/app/services/system/log/SystemFileServices.php
  43. 1 1
      crmeb/app/services/user/UserServices.php
  44. 2 1
      crmeb/composer.json
  45. 0 3
      crmeb/config/console.php
  46. 20 0
      crmeb/crmeb/command/Crud.php
  47. 0 46
      crmeb/crmeb/command/Dao.php
  48. 36 0
      crmeb/crmeb/command/Npm.php
  49. 0 46
      crmeb/crmeb/command/Service.php
  50. 3 2
      crmeb/crmeb/command/Util.php
  51. 0 35
      crmeb/crmeb/command/stubs/service.stub
  52. 36 0
      crmeb/crmeb/exceptions/CrudException.php
  53. 145 0
      crmeb/crmeb/services/crud/Controller.php
  54. 49 0
      crmeb/crmeb/services/crud/Dao.php
  55. 438 0
      crmeb/crmeb/services/crud/Make.php
  56. 55 0
      crmeb/crmeb/services/crud/Model.php
  57. 112 0
      crmeb/crmeb/services/crud/Route.php
  58. 155 0
      crmeb/crmeb/services/crud/Service.php
  59. 50 0
      crmeb/crmeb/services/crud/Validate.php
  60. 145 0
      crmeb/crmeb/services/crud/ViewApi.php
  61. 112 0
      crmeb/crmeb/services/crud/ViewPages.php
  62. 122 0
      crmeb/crmeb/services/crud/ViewRouter.php
  63. 51 0
      crmeb/crmeb/services/crud/stubs/controller/CrudController.stub
  64. 9 0
      crmeb/crmeb/services/crud/stubs/controller/create.stub
  65. 18 0
      crmeb/crmeb/services/crud/stubs/controller/delete.stub
  66. 10 0
      crmeb/crmeb/services/crud/stubs/controller/edit.stub
  67. 9 0
      crmeb/crmeb/services/crud/stubs/controller/index.stub
  68. 15 0
      crmeb/crmeb/services/crud/stubs/controller/save.stub
  69. 20 0
      crmeb/crmeb/services/crud/stubs/controller/update.stub
  70. 41 0
      crmeb/crmeb/services/crud/stubs/dao/CrudDao.stub
  71. 43 0
      crmeb/crmeb/services/crud/stubs/model/CrudModel.stub
  72. 1 0
      crmeb/crmeb/services/crud/stubs/route/create.stub
  73. 1 0
      crmeb/crmeb/services/crud/stubs/route/delete.stub
  74. 1 0
      crmeb/crmeb/services/crud/stubs/route/edit.stub
  75. 1 0
      crmeb/crmeb/services/crud/stubs/route/index.stub
  76. 7 0
      crmeb/crmeb/services/crud/stubs/route/route.stub
  77. 1 0
      crmeb/crmeb/services/crud/stubs/route/save.stub
  78. 1 0
      crmeb/crmeb/services/crud/stubs/route/update.stub
  79. 13 0
      crmeb/crmeb/services/crud/stubs/service/CrudListIndex.stub
  80. 10 0
      crmeb/crmeb/services/crud/stubs/service/CrudSave.stub
  81. 44 0
      crmeb/crmeb/services/crud/stubs/service/CrudService.stub
  82. 11 0
      crmeb/crmeb/services/crud/stubs/service/CrudUpdate.stub
  83. 23 0
      crmeb/crmeb/services/crud/stubs/service/GetCrudForm.stub
  84. 52 0
      crmeb/crmeb/services/crud/stubs/validate/CrudValidate.stubs
  85. 3 25
      crmeb/crmeb/command/stubs/dao.stub
  86. 11 0
      crmeb/crmeb/services/crud/stubs/view/api/crudDeleteApi.stub
  87. 12 0
      crmeb/crmeb/services/crud/stubs/view/api/crudSaveApi.stub
  88. 12 0
      crmeb/crmeb/services/crud/stubs/view/api/crudUpdateApi.stub
  89. 10 0
      crmeb/crmeb/services/crud/stubs/view/api/getCrudCreateApi.stub
  90. 11 0
      crmeb/crmeb/services/crud/stubs/view/api/getCrudEditApi.stub
  91. 12 0
      crmeb/crmeb/services/crud/stubs/view/api/getCrudListApi.stub
  92. 137 0
      crmeb/crmeb/services/crud/stubs/view/pages/crud/index.stub
  93. 39 0
      crmeb/crmeb/services/crud/stubs/view/router/modules/crud.stub
  94. 1 0
      crmeb/public/admin/css.worker.js
  95. 1 0
      crmeb/public/admin/editor.worker.js
  96. BIN
      crmeb/public/admin/favicon.ico
  97. 1 0
      crmeb/public/admin/html.worker.js
  98. 1 0
      crmeb/public/admin/index.html
  99. 1 0
      crmeb/public/admin/json.worker.js
  100. 0 0
      crmeb/public/admin/system_static/css/app.cbd44cf8.css

+ 1 - 0
.gitignore

@@ -20,3 +20,4 @@
 /template/uni-app/node_modules/
 /template/uni-app/unpackage/
 /template/uni-app/.hbuilderx/
+crmeb/.idea/

+ 22 - 18
crmeb/app/adminapi/AdminApiExceptionHandle.php

@@ -45,26 +45,30 @@ class AdminApiExceptionHandle extends Handle
     public function report(Throwable $exception): void
     {
         if (!$this->isIgnoreReport($exception)) {
-            $data = [
-                'file' => $exception->getFile(),
-                'line' => $exception->getLine(),
-                'message' => $this->getMessage($exception),
-                'code' => $this->getCode($exception),
-            ];
+            try {
+                $data = [
+                    'file' => $exception->getFile(),
+                    'line' => $exception->getLine(),
+                    'message' => $this->getMessage($exception),
+                    'code' => $this->getCode($exception),
+                ];
 
-            //日志内容
-            $log = [
-                request()->adminId(),                                                                 //管理员ID
-                request()->ip(),                                                                      //客户ip
-                ceil(msectime() - (request()->time(true) * 1000)),                               //耗时(毫秒)
-                request()->rule()->getMethod(),                                                       //请求类型
-                str_replace("/", "", request()->rootUrl()),                             //应用
-                request()->baseUrl(),                                                                 //路由
-                json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),//请求参数
-                json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),             //报错数据
+                //日志内容
+                $log = [
+                    request()->adminId(),                                                                 //管理员ID
+                    request()->ip(),                                                                      //客户ip
+                    ceil(msectime() - (request()->time(true) * 1000)),                               //耗时(毫秒)
+                    request()->rule()->getMethod(),                                                       //请求类型
+                    str_replace("/", "", request()->rootUrl()),                             //应用
+                    request()->baseUrl(),                                                                 //路由
+                    json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),//请求参数
+                    json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),             //报错数据
 
-            ];
-            Log::write(implode("|", $log), "error");
+                ];
+                Log::write(implode("|", $log), "error");
+            } catch (\Throwable $e) {
+                Log::write($e->getMessage(), "error");
+            }
         }
     }
 

+ 15 - 2
crmeb/app/adminapi/controller/v1/setting/SystemCity.php

@@ -133,11 +133,24 @@ class SystemCity extends AuthController
      */
     public function clean_cache()
     {
-        $res = CacheService::delete('CITY_LIST');
-        if ($res) {
+        $res1 = CacheService::delete('CITY_LIST');
+        $res2 = CacheService::delete('CITY_FULL_LIST');
+        if ($res1 && $res2) {
             return app('json')->success(400185);
         } else {
             return app('json')->fail(400186);
         }
     }
+
+    /**
+     * 获取城市数据完整列表
+     * @return \think\Response
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/04/10
+     */
+    public function fullList()
+    {
+        return app('json')->success($this->services->fullList('parent_id,name as label,city_id as value'));
+    }
 }

+ 67 - 0
crmeb/app/adminapi/controller/v1/setting/SystemCrud.php

@@ -0,0 +1,67 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\adminapi\controller\v1\setting;
+
+
+use app\adminapi\controller\AuthController;
+use app\services\system\SystemCrudServices;
+use think\facade\App;
+
+/**
+ * Class SystemCrud
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/6
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemCrud extends AuthController
+{
+
+    /**
+     * SystemCrud constructor.
+     * @param App $app
+     * @param SystemCrudServices $services
+     */
+    public function __construct(App $app, SystemCrudServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    public function index()
+    {
+
+    }
+
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['pid', 0],
+            ['menuName', ''],
+            ['tableName', ''],
+            ['tableComment', ''],//表备注
+            ['tableField', []],//表字段
+            ['tableIndex', []],//索引
+            ['tableTime', 0],//表是否增加修改和添加时间
+            ['tableDelete', 0],//表是否增加伪删除
+            ['fromField', []],
+            ['columnField', []],
+            ['filePath', []],
+        ]);
+
+        $this->services->createCrud($data);
+    }
+
+
+}

+ 11 - 1
crmeb/app/adminapi/controller/v1/setting/SystemMenus.php

@@ -222,7 +222,17 @@ class SystemMenus extends AuthController
     public function ruleList()
     {
         //获取所有的路由
-        $ruleList = Route::getRuleList();
+        $this->app = app();
+        $this->app->route->setTestMode(true);
+        $this->app->route->clear();
+        $path = $this->app->getRootPath() . 'app' . DS . 'adminapi' . DS . 'route' . DS;
+        $files = is_dir($path) ? scandir($path) : [];
+        foreach ($files as $file) {
+            if (strpos($file, '.php')) {
+                include $path . $file;
+            }
+        }
+        $ruleList = $this->app->route->getRuleList();
         $menuApiList = $this->services->getColumn(['auth_type' => 2, 'is_del' => 0], "concat(`api_url`,'_',lower(`methods`)) as rule");
         if ($menuApiList) $menuApiList = array_column($menuApiList, 'rule');
         $list = [];

+ 167 - 0
crmeb/app/adminapi/controller/v1/setting/SystemRoute.php

@@ -0,0 +1,167 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\adminapi\controller\v1\setting;
+
+
+use app\adminapi\controller\AuthController;
+use app\services\system\SystemRouteServices;
+use think\facade\App;
+
+/**
+ * Class SystemRoute
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/6
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemRoute extends AuthController
+{
+
+    /**
+     * SystemRoute constructor.
+     * @param App $app
+     * @param SystemRouteServices $services
+     */
+    public function __construct(App $app, SystemRouteServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 同步路由权限
+     * @param string $appName
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function syncRoute(string $appName = 'adminapi')
+    {
+        $this->services->syncRoute($appName);
+
+        return app('json')->success();
+    }
+
+    /**
+     * 列表数据
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['name_like', ''],
+            ['app_name', 'adminapi']
+        ]);
+
+        return app('json')->success($this->services->getList($where));
+    }
+
+    /**
+     * tree数据
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function tree()
+    {
+        $where = $this->request->getMore([
+            ['name_like', ''],
+            ['app_name', 'adminapi']
+        ]);
+
+        return app('json')->success($this->services->getTreeList($where));
+    }
+
+
+    /**
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function save($id = 0)
+    {
+        $data = $this->request->postMore([
+            ['cate_id', 0],
+            ['name', ''],
+            ['path', ''],
+            ['method', ''],
+            ['type', 0],
+            ['app_name', ''],
+            ['request', []],
+            ['response', []],
+            ['request_example', []],
+            ['response_example', []],
+            ['describe', ''],
+        ]);
+
+        if (!$data['name']) {
+            return app('json')->fail('请输入路由名称');
+        }
+        if (!$data['path']) {
+            return app('json')->fail('请输入路由路径');
+        }
+        if (!$data['method']) {
+            return app('json')->fail('请选择路由请求方式');
+        }
+        if (!$data['app_name']) {
+            return app('json')->fail('缺少应用名参数');
+        }
+        if ($id) {
+            $this->services->update($id, $data);
+        } else {
+            $data['add_time'] = date('Y-m-d H:i:s');
+            $this->services->save($data);
+        }
+
+        return app('json')->success($id ? '修改成功' : '添加成功');
+    }
+
+    /**
+     * @param $id
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function read($id)
+    {
+        return app('json')->success($this->services->getInfo((int)$id));
+    }
+
+    /**
+     * @param $id
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function delete($id)
+    {
+        if (!$id) {
+            return app('json')->fail('缺少参数');
+        }
+
+        $this->services->delete($id);
+
+        return app('json')->success('删除成功');
+    }
+
+
+}

+ 156 - 0
crmeb/app/adminapi/controller/v1/setting/SystemRouteCate.php

@@ -0,0 +1,156 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\adminapi\controller\v1\setting;
+
+
+use app\adminapi\controller\AuthController;
+use app\services\system\SystemRouteCateServices;
+use app\services\system\SystemRouteServices;
+use think\facade\App;
+use think\Request;
+
+/**
+ * Class SystemRouteCate
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/6
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemRouteCate extends AuthController
+{
+
+    /**
+     * SystemRouteCate constructor.
+     * @param App $app
+     * @param SystemRouteCateServices $services
+     */
+    public function __construct(App $app, SystemRouteCateServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function index()
+    {
+        return app('json')->success($this->services->getAllList());
+    }
+
+    /**
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function create()
+    {
+        return app('json')->success($this->services->getFrom(0, $this->request->get('app_name', 'adminapi')));
+    }
+
+    /**
+     * @param Request $request
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function save(Request $request)
+    {
+        $data = $request->postMore([
+            ['path', []],
+            ['name', ''],
+            ['sort', 0],
+            ['app_name', ''],
+        ]);
+
+        if (!$data['name']) {
+            return app('json')->fail('缺少分类名称');
+        }
+
+        $data['add_time'] = time();
+        $data['pid'] = $data['path'][count($data['path']) - 1] ?? 0;
+        $this->services->save($data);
+
+
+        return app('json')->success('保存成功');
+
+    }
+
+    /**
+     * @param $id
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->getFrom($id));
+    }
+
+    /**
+     * @param Request $request
+     * @param $id
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function update(Request $request, $id)
+    {
+        $data = $request->postMore([
+            ['path', []],
+            ['name', ''],
+            ['sort', 0],
+            ['app_name', ''],
+        ]);
+
+        if (!$data['name']) {
+            return app('json')->fail('缺少分类名称');
+        }
+
+        $data['pid'] = $data['path'][count($data['path']) - 1] ?? 0;
+        $this->services->update($id, $data);
+
+        return app('json')->success('修改成功');
+    }
+
+    /**
+     * @param SystemRouteServices $service
+     * @param $id
+     * @return \think\Response
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function delete(SystemRouteServices $service, $id)
+    {
+        if (!$id) {
+            return app('json')->fail('缺少参数');
+        }
+
+        if ($service->count(['cate_id' => $id])) {
+            return app('json')->fail('请先删除分类下的接口');
+        }
+
+        $this->services->delete($id);
+
+        return app('json')->success('删除成功');
+    }
+}

+ 23 - 0
crmeb/app/adminapi/controller/v1/system/SystemFile.php

@@ -72,6 +72,29 @@ class SystemFile extends AuthController
         return app('json')->success($this->services->opendir());
     }
 
+    //文件备注
+    public function fileMark()
+    {
+        [$path, $fileToken] = $this->request->postMore([
+            ['path', ''],
+            ['fileToken', ''],
+        ], true);
+        if ($path == '') return app('json')->fail(100100);
+        return app('json')->success($this->services->markForm($path, $fileToken));
+    }
+
+    //文件备注保存
+    public function fileMarkSave()
+    {
+        [$full_path, $mark] = $this->request->postMore([
+            ['full_path', ''],
+            ['mark', ''],
+        ], true);
+        if ($full_path == '') return app('json')->fail(100100);
+        $this->services->fileMarkSave($full_path, $mark);
+        return app('json')->success(100000);
+    }
+
     //读取文件
     public function openfile()
     {

+ 14 - 4
crmeb/app/adminapi/middleware/AdminAuthTokenMiddleware.php

@@ -25,21 +25,31 @@ use crmeb\services\CacheService;
  */
 class AdminAuthTokenMiddleware implements MiddlewareInterface
 {
+    /**
+     * @param Request $request
+     * @param \Closure $next
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/04/07
+     */
     public function handle(Request $request, \Closure $next)
     {
-        $authInfo = null;
         $token = trim(ltrim($request->header(Config::get('cookie.token_name', 'Authori-zation')), 'Bearer'));
         /** @var AdminAuthServices $service */
         $service = app()->make(AdminAuthServices::class);
         $adminInfo = $service->parseToken($token);
-        Request::macro('isAdminLogin', function () use (&$adminInfo) {
+        $request->macro('isAdminLogin', function () use (&$adminInfo) {
             return !is_null($adminInfo);
         });
-        Request::macro('adminId', function () use (&$adminInfo) {
+        $request->macro('adminId', function () use (&$adminInfo) {
             return $adminInfo['id'];
         });
 
-        Request::macro('adminInfo', function () use (&$adminInfo) {
+        $request->macro('adminInfo', function () use (&$adminInfo) {
             return $adminInfo;
         });
 

+ 1 - 1
crmeb/app/adminapi/route/cms.php

@@ -25,7 +25,7 @@ Route::group('cms', function () {
     //修改状态
     Route::put('category/set_status/:id/:status', 'v1.cms.ArticleCategory/set_status')->name('CategoryStatus')->option(['real_name' => '修改文章分类状态']);
     //分类列表
-    Route::get('category_list', 'v1.cms.ArticleCategory/categoryList')->name('categoryList')->option(['real_name' => '分类列表']);
+    Route::get('category_list', 'v1.cms.ArticleCategory/categoryList')->name('categoryList')->option(['real_name' => '分类列表', 'is_common' => true]);
     //分类树形列表
     Route::get('category_tree_list', 'v1.cms.ArticleCategory/getTreeList')->name('getTreeList')->option(['real_name' => '分类树形列表']);
 })->middleware([

+ 5 - 5
crmeb/app/adminapi/route/common.php

@@ -26,19 +26,19 @@ Route::group(function () {
     //
     Route::get('home/rank', 'Common/purchaseRanking')->option(['real_name' => '首页交易额排行']);
     // 消息提醒
-    Route::get('jnotice', 'Common/jnotice')->option(['real_name' => '消息提醒']);
+    Route::get('jnotice', 'Common/jnotice')->option(['real_name' => '消息提醒', 'is_common' => true]);
     //验证授权
     Route::get('check_auth', 'Common/auth')->option(['real_name' => '验证授权']);
     //申请授权
     Route::post('auth_apply', 'Common/auth_apply')->option(['real_name' => '申请授权']);
     //授权
-    Route::get('auth', 'Common/auth')->option(['real_name' => '授权信息']);
+    Route::get('auth', 'Common/auth')->option(['real_name' => '授权信息', 'is_common' => true]);
     //获取左侧菜单
-    Route::get('menus', 'v1.setting.SystemMenus/menus')->option(['real_name' => '左侧菜单']);
+    Route::get('menus', 'v1.setting.SystemMenus/menus')->option(['real_name' => '左侧菜单', 'is_common' => true]);
     //获取搜索菜单列表
-    Route::get('menusList', 'Common/menusList')->option(['real_name' => '搜索菜单列表']);
+    Route::get('menusList', 'Common/menusList')->option(['real_name' => '搜索菜单列表', 'is_common' => true]);
     //获取logo
-    Route::get('logo', 'Common/getLogo')->option(['real_name' => '获取logo']);
+    Route::get('logo', 'Common/getLogo')->option(['real_name' => '获取logo', 'is_common' => true]);
     //查询版权
     Route::get('copyright', 'Common/copyright')->option(['real_name' => '申请版权']);
     //保存版权

+ 35 - 0
crmeb/app/adminapi/route/crud.php

@@ -0,0 +1,35 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+use think\facade\Route;
+
+/**
+ * crud 自动加载路由
+ * 自动加载crud目录下的所有路由文件
+ */
+Route::group(function () {
+    $path = $this->app->getRootPath() . 'app' . DS . 'adminapi' . DS . 'route' . DS . 'crud';
+    if (is_dir($path)) {
+        $files = scandir($path);
+        foreach ($files as $file) {
+            if ($file != '.' && $file != '..') {
+                include $path . DS . $file;
+            }
+        }
+    }
+})->middleware([
+    \app\http\middleware\AllowOriginMiddleware::class,
+    \app\adminapi\middleware\AdminAuthTokenMiddleware::class,
+    \app\adminapi\middleware\AdminCheckRoleMiddleware::class,
+    \app\adminapi\middleware\AdminLogMiddleware::class
+]);

+ 9 - 9
crmeb/app/adminapi/route/file.php

@@ -15,23 +15,23 @@ use think\facade\Route;
  */
 Route::group('file', function () {
     //附件列表
-    Route::get('file', 'v1.file.SystemAttachment/index')->option(['real_name' => '图片附件列表']);
+    Route::get('file', 'v1.file.SystemAttachment/index')->option(['real_name' => '图片附件列表', 'is_common' => true]);
     //删除图片和数据记录
-    Route::post('file/delete', 'v1.file.SystemAttachment/delete')->option(['real_name' => '删除图片']);
+    Route::post('file/delete', 'v1.file.SystemAttachment/delete')->option(['real_name' => '删除图片', 'is_common' => true]);
     //移动图片分来表单
-    Route::get('file/move', 'v1.file.SystemAttachment/move')->option(['real_name' => '移动图片分类表单']);
+    Route::get('file/move', 'v1.file.SystemAttachment/move')->option(['real_name' => '移动图片分类表单', 'is_common' => true]);
     //移动图片分类
-    Route::put('file/do_move', 'v1.file.SystemAttachment/moveImageCate')->option(['real_name' => '移动图片分类']);
+    Route::put('file/do_move', 'v1.file.SystemAttachment/moveImageCate')->option(['real_name' => '移动图片分类', 'is_common' => true]);
     //修改图片名称
-    Route::put('file/update/:id', 'v1.file.SystemAttachment/update')->option(['real_name' => '修改图片名称']);
+    Route::put('file/update/:id', 'v1.file.SystemAttachment/update')->option(['real_name' => '修改图片名称', 'is_common' => true]);
     //上传图片
-    Route::post('upload/[:upload_type]', 'v1.file.SystemAttachment/upload')->option(['real_name' => '上传图片']);
+    Route::post('upload/[:upload_type]', 'v1.file.SystemAttachment/upload')->option(['real_name' => '上传图片', 'is_common' => true]);
     //附件分类管理资源路由
-    Route::resource('category', 'v1.file.SystemAttachmentCategory')->option(['real_name' => '附件分类管理']);
+    Route::resource('category', 'v1.file.SystemAttachmentCategory')->option(['real_name' => '附件分类管理', 'is_common' => true]);
     //获取上传类型
-    Route::get('upload_type', 'v1.file.SystemAttachment/uploadType')->option(['real_name' => '上传类型']);
+    Route::get('upload_type', 'v1.file.SystemAttachment/uploadType')->option(['real_name' => '上传类型', 'is_common' => true]);
     //分片上传本地视频
-    Route::post('video_upload', 'v1.file.SystemAttachment/videoUpload')->option(['real_name' => '分片上传本地视频']);
+    Route::post('video_upload', 'v1.file.SystemAttachment/videoUpload')->option(['real_name' => '分片上传本地视频', 'is_common' => true]);
 })->middleware([
     \app\http\middleware\AllowOriginMiddleware::class,
     \app\adminapi\middleware\AdminAuthTokenMiddleware::class,

+ 4 - 3
crmeb/app/adminapi/route/product.php

@@ -14,8 +14,9 @@ Route::group('product', function () {
 
     Route::get('category', 'v1.product.StoreCategory/index')->option(['real_name' => '商品分类列表']);
     //商品树形列表
-    Route::get('category/tree/:type', 'v1.product.StoreCategory/tree_list')->option(['real_name' => '商品分类树形列表']);
-    Route::get('category/cascader/:type', 'v1.product.StoreCategory/cascader_list')->option(['real_name' => '商品分类树形列表']);
+    Route::get('category/tree/:type', 'v1.product.StoreCategory/tree_list')->option(['real_name' => '商品分类树形列表', 'is_common' => true]);
+    //商品分类树形列表
+    Route::get('category/cascader/:type', 'v1.product.StoreCategory/cascader_list')->option(['real_name' => '商品分类树形列表', 'is_common' => true]);
     //商品分类新增表单
     Route::get('category/create', 'v1.product.StoreCategory/create')->option(['real_name' => '商品分类新增表单']);
     //商品分类新增
@@ -37,7 +38,7 @@ Route::group('product', function () {
     //1分钟保存一次数据
     Route::post('cache', 'v1.product.StoreProduct/saveCacheData')->option(['real_name' => '保存还未提交数据']);
     //获取所有商品列表
-    Route::get('product/list', 'v1.product.StoreProduct/search_list')->option(['real_name' => '获取所有商品列表']);
+    Route::get('product/list', 'v1.product.StoreProduct/search_list')->option(['real_name' => '获取所有商品列表', 'is_common' => true]);
     //获取商品规格
     Route::get('product/attrs/:id/:type', 'v1.product.StoreProduct/get_attrs')->option(['real_name' => '获取商品规格']);
     //商品列表头

+ 4 - 1
crmeb/app/adminapi/route/route.php

@@ -33,7 +33,10 @@ Route::group(function () {
     //一次验证
     Route::post('ajcheck', 'Login/ajcheck')->name('ajcheck')->option(['real_name' => '一次验证']);
     //获取客服数据
-    Route::get('get_workerman_url', 'PublicController/getWorkerManUrl')->option(['real_name' => '获取客服数据']);
+    Route::get('get_workerman_url', 'PublicController/getWorkerManUrl')->option([
+        'real_name' => '获取客服数据',
+        'is_common' => true,
+    ]);
     //测试
     Route::get('index', 'Test/index')->option(['real_name' => '测试地址']);
 })->middleware(AllowOriginMiddleware::class);

+ 2 - 0
crmeb/app/adminapi/route/setting.php

@@ -77,6 +77,8 @@ Route::group('setting', function () {
     Route::put('group_data/set_status/:id/:status', 'v1.setting.SystemGroupData/set_status')->option(['real_name' => '修改组合数据状态']);
     //数据配置保存
     Route::post('group_data/save_all', 'v1.setting.SystemGroupData/saveAll')->option(['real_name' => '提交数据配置']);
+    //获取城市数据完整列表
+    Route::get('city/full_list', 'v1.setting.SystemCity/fullList')->option(['real_name' => '获取城市数据完整列表']);
     //获取城市数据列表
     Route::get('city/list/:parent_id', 'v1.setting.SystemCity/index')->option(['real_name' => '获取城市数据列表']);
     //添加城市数据表单

+ 25 - 0
crmeb/app/adminapi/route/system.php

@@ -110,6 +110,27 @@ Route::group('system', function () {
     Route::delete('crontab/del/:id', 'v1.system.SystemCrontab/delTimer')->option(['real_name' => '删除定时任务']);
     //定时任务是否开启开关
     Route::get('crontab/set_open/:id/:is_open', 'v1.system.SystemCrontab/setTimerStatus')->option(['real_name' => '定时任务是否开启开关']);
+    //同步路由接口
+    Route::get('route/sync_route/[:appName]', 'v1.setting.SystemRoute/syncRoute')->option(['real_name' => '同步路由']);
+    //获取路由tree行数据
+    Route::get('route/tree', 'v1.setting.SystemRoute/tree')->option(['real_name' => '获取路由tree']);
+    //权限路由
+    Route::delete('route/:id', 'v1.setting.SystemRoute/delete')->option(['real_name' => '删除路由权限']);
+    //查看路由权限
+    Route::get('route/:id', 'v1.setting.SystemRoute/read')->option(['real_name' => '查看路由权限']);
+    //保存路由权限
+    Route::post('route/:id', 'v1.setting.SystemRoute/save')->option(['real_name' => '保存路由权限']);
+    //路由分类
+    Route::resource('route_cate', 'v1.setting.SystemRouteCate')->option([
+        'real_name' => [
+            'index' => '获取路由分类列表',
+            'create' => '获取创建路由分类表单',
+            'save' => '保存路由分类',
+            'edit' => '获取修改路由分类表单',
+            'update' => '修改路由分类',
+            'delete' => '删除路由分类'
+        ],
+    ]);
 
 })->middleware([
     \app\http\middleware\AllowOriginMiddleware::class,
@@ -134,6 +155,10 @@ Route::group('system', function () {
     Route::get('file/delFolder', 'v1.system.SystemFile/delFolder')->option(['real_name' => '删除文件夹']);
     //重命名文件
     Route::get('file/rename', 'v1.system.SystemFile/rename')->option(['real_name' => '重命名文件夹']);
+    //目录文件备注表单
+    Route::get('file/mark', 'v1.system.SystemFile/fileMark')->option(['real_name' => '目录文件备注表单']);
+    //目录文件备注保存
+    Route::post('file/mark/save', 'v1.system.SystemFile/fileMarkSave')->option(['real_name' => '目录文件备注保存']);
 })->middleware([
     \app\http\middleware\AllowOriginMiddleware::class,
     \app\adminapi\middleware\AdminAuthTokenMiddleware::class,

+ 5 - 2
crmeb/app/api/controller/v1/PublicController.php

@@ -670,7 +670,6 @@ class PublicController
         $data['site_name'] = sys_config('site_name');//网站名称
         $data['site_url'] = sys_config('site_url');//网站地址
         $data['wap_login_logo'] = sys_config('wap_login_logo');//移动端登录logo
-        $data['wap_login_logo'] = sys_config('wap_login_logo');//移动端登录logo
         $data['record_No'] = sys_config('record_No');//备案号
         $data['network_security'] = sys_config('network_security');//网安备案
         $data['store_self_mention'] = sys_config('store_self_mention');//是否开启到店自提
@@ -681,7 +680,11 @@ class PublicController
         $data['recharge_switch'] = sys_config('recharge_switch');//小程序充值开关
         $data['member_card_status'] = sys_config('member_card_status');//是否开启付费会员
         $data['member_price_status'] = sys_config('member_price_status');//商品会员折扣价展示启用
-
+        $data['ali_pay_status'] = sys_config('ali_pay_status') != '0';//支付宝是否启用
+        $data['wechat_pay_status'] = sys_config('pay_weixin_open') != '0';//微信是否启用
+        $data['yue_pay_status'] = sys_config('yue_pay_status') == 1 && sys_config('balance_func_status') != 0;//余额是否启用
+        $data['offline_pay_status'] = sys_config('offline_pay_status') == 1;//线下是否启用
+        $data['friend_pay_status'] = sys_config('friend_pay_status') == 1;//好友是否启用
         return app('json')->success($data);
     }
 }

+ 16 - 5
crmeb/app/api/middleware/AuthTokenMiddleware.php

@@ -16,7 +16,6 @@ use app\Request;
 use app\services\user\UserAuthServices;
 use crmeb\exceptions\AuthException;
 use crmeb\interfaces\MiddlewareInterface;
-use think\exception\DbException;
 
 /**
  * Class AuthTokenMiddleware
@@ -24,6 +23,18 @@ use think\exception\DbException;
  */
 class AuthTokenMiddleware implements MiddlewareInterface
 {
+    /**
+     * @param Request $request
+     * @param \Closure $next
+     * @param bool $force
+     * @return int|mixed|\think\Response
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/04/07
+     */
     public function handle(Request $request, \Closure $next, bool $force = true)
     {
         $authInfo = null;
@@ -39,20 +50,20 @@ class AuthTokenMiddleware implements MiddlewareInterface
         }
 
         if (!is_null($authInfo)) {
-            Request::macro('user', function (string $key = null) use (&$authInfo) {
+            $request->macro('user', function (string $key = null) use (&$authInfo) {
                 if ($key) {
                     return $authInfo['user'][$key] ?? '';
                 }
                 return $authInfo['user'];
             });
-            Request::macro('tokenData', function () use (&$authInfo) {
+            $request->macro('tokenData', function () use (&$authInfo) {
                 return $authInfo['tokenData'];
             });
         }
-        Request::macro('isLogin', function () use (&$authInfo) {
+        $request->macro('isLogin', function () use (&$authInfo) {
             return !is_null($authInfo);
         });
-        Request::macro('uid', function () use (&$authInfo) {
+        $request->macro('uid', function () use (&$authInfo) {
             return is_null($authInfo) ? 0 : (int)$authInfo['user']->uid;
         });
 

+ 3 - 0
crmeb/app/api/route/v1.php

@@ -47,6 +47,9 @@ Route::group(function () {
     //查询版权
     Route::get('copyright', 'v1.PublicController/copyright')->option(['real_name' => '申请版权']);
 
+    //商城基础配置汇总接口
+    Route::get('basic_config', 'v1.PublicController/getMallBasicConfig')->option(['real_name' => '商城基础配置汇总接口']);
+
 })->middleware(\app\http\middleware\AllowOriginMiddleware::class)->middleware(\app\api\middleware\StationOpenMiddleware::class);
 
 

+ 21 - 4
crmeb/app/dao/BaseDao.php

@@ -68,7 +68,7 @@ abstract class BaseDao
      * @throws \think\db\exception\DbException
      * @throws \think\db\exception\ModelNotFoundException
      */
-    public function selectList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', bool $search = false)
+    public function selectList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false)
     {
         if ($search) {
             $model = $this->search($where);
@@ -79,6 +79,8 @@ abstract class BaseDao
             $query->page($page, $limit);
         })->when($order !== '', function ($query) use ($order) {
             $query->order($order);
+        })->when($with, function ($query) use ($with) {
+            $query->with($with);
         })->select();
     }
 
@@ -193,14 +195,14 @@ abstract class BaseDao
 
     /**
      * 获取单个字段值
-     * @param array $where
+     * @param $where
      * @param string|null $field
      * @return mixed
      */
-    public function value(array $where, ?string $field = '')
+    public function value($where, ?string $field = '')
     {
         $pk = $this->getPk();
-        return $this->getModel()->where($where)->value($field ?: $pk);
+        return $this->search($this->setWhere($where))->value($field ?: $pk);
     }
 
     /**
@@ -247,6 +249,21 @@ abstract class BaseDao
         return $this->getModel()::update($data, $where);
     }
 
+    /**
+     * @param $where
+     * @return array|mixed
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    protected function setWhere($where, ?string $key = null)
+    {
+        if (!is_array($where)) {
+            $where = [is_null($key) ? $this->getPk() : $key => $where];
+        }
+        return $where;
+    }
+
     /**
      * 批量更新数据
      * @param array $ids

+ 12 - 1
crmeb/app/dao/shipping/SystemCityDao.php

@@ -39,7 +39,7 @@ class SystemCityDao extends BaseDao
      * @throws \think\db\exception\DbException
      * @throws \think\db\exception\ModelNotFoundException
      */
-    public function getCityList(array $where,string $field = '*')
+    public function getCityList(array $where, string $field = '*')
     {
         return $this->search($where)->field($field)->select()->toArray();
     }
@@ -87,4 +87,15 @@ class SystemCityDao extends BaseDao
     {
         return $this->getModel()->with('children')->where('parent_id', 0)->order('id asc')->select()->toArray();
     }
+
+    /**
+     * 获取城市数据完整列表
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/04/10
+     */
+    public function fullList($field = '*')
+    {
+        return $this->getModel()->order('id asc')->field($field)->select()->toArray();
+    }
 }

+ 38 - 0
crmeb/app/dao/system/SystemCrudDao.php

@@ -0,0 +1,38 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\dao\system;
+
+
+use app\dao\BaseDao;
+use app\model\system\SystemCrud;
+
+/**
+ * Class SystemCrudDao
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/6
+ * @package app\dao\system
+ */
+class SystemCrudDao extends BaseDao
+{
+
+    /**
+     * 获取当前模型
+     * @return string
+     */
+    protected function setModel(): string
+    {
+        return SystemCrud::class;
+    }
+}

+ 40 - 0
crmeb/app/dao/system/SystemRouteCateDao.php

@@ -0,0 +1,40 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\dao\system;
+
+
+use app\dao\BaseDao;
+use app\model\system\SystemRouteCate;
+
+/**
+ * Class SystemRouteCateDao
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/6
+ * @package app\dao\system
+ */
+class SystemRouteCateDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    protected function setModel(): string
+    {
+        return SystemRouteCate::class;
+    }
+}

+ 40 - 0
crmeb/app/dao/system/SystemRouteDao.php

@@ -0,0 +1,40 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\dao\system;
+
+
+use app\dao\BaseDao;
+use app\model\system\SystemRoute;
+
+/**
+ * Class SystemRouteDao
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/6
+ * @package app\dao\system
+ */
+class SystemRouteDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    protected function setModel(): string
+    {
+        return SystemRoute::class;
+    }
+}

+ 23 - 0
crmeb/app/dao/system/log/SystemFileInfoDao.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace app\dao\system\log;
+
+use app\dao\BaseDao;
+use app\model\system\log\SystemFileInfo;
+
+/**
+ * @author 吴汐
+ * @email 442384644@qq.com
+ * @date 2023/04/07
+ */
+class SystemFileInfoDao extends BaseDao
+{
+    /**
+     * 设置模型
+     * @return string
+     */
+    protected function setModel(): string
+    {
+        return SystemFileInfo::class;
+    }
+}

+ 15 - 6
crmeb/app/http/middleware/BaseMiddleware.php

@@ -21,16 +21,25 @@ use crmeb\interfaces\MiddlewareInterface;
  */
 class BaseMiddleware implements MiddlewareInterface
 {
+    /**
+     * @param Request $request
+     * @param \Closure $next
+     * @param bool $force
+     * @return mixed
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/04/07
+     */
     public function handle(Request $request, \Closure $next, bool $force = true)
     {
-        if (!Request::hasMacro('uid')) {
-            Request::macro('uid', function(){ return 0; });
+        if (!$request->hasMacro('uid')) {
+            $request->macro('uid', function(){ return 0; });
         }
-        if (!Request::hasMacro('adminId')) {
-            Request::macro('adminId', function(){ return 0; });
+        if (!$request->hasMacro('adminId')) {
+            $request->macro('adminId', function(){ return 0; });
         }
-        if (!Request::hasMacro('kefuId')) {
-            Request::macro('kefuId', function(){ return 0; });
+        if (!$request->hasMacro('kefuId')) {
+            $request->macro('kefuId', function(){ return 0; });
         }
 
         return $next($request);

+ 3 - 3
crmeb/app/kefuapi/middleware/KefuAuthTokenMiddleware.php

@@ -27,6 +27,7 @@ class KefuAuthTokenMiddleware implements MiddlewareInterface
     /**
      * @param Request $request
      * @param \Closure $next
+     * @return mixed
      * @throws \Psr\SimpleCache\InvalidArgumentException
      * @throws \think\db\exception\DataNotFoundException
      * @throws \think\db\exception\DbException
@@ -34,16 +35,15 @@ class KefuAuthTokenMiddleware implements MiddlewareInterface
      */
     public function handle(Request $request, \Closure $next)
     {
-        $authInfo = null;
         $token = trim(ltrim($request->header(Config::get('cookie.token_name', 'Authori-zation')), 'Bearer'));
         /** @var LoginServices $services */
         $services = app()->make(LoginServices::class);
         $kefuInfo = $services->parseToken($token);
-        Request::macro('kefuId', function () use (&$kefuInfo) {
+        $request->macro('kefuId', function () use (&$kefuInfo) {
             return (int)$kefuInfo['id'];
         });
 
-        Request::macro('kefuInfo', function () use (&$kefuInfo) {
+        $request->macro('kefuInfo', function () use (&$kefuInfo) {
             return $kefuInfo;
         });
 

+ 38 - 0
crmeb/app/model/system/SystemCrud.php

@@ -0,0 +1,38 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\model\system;
+
+
+use crmeb\basic\BaseModel;
+
+/**
+ * Class SystemCrud
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/6
+ * @package app\model\system
+ */
+class SystemCrud extends BaseModel
+{
+
+    /**
+     * @var string
+     */
+    protected $name = 'system_crud';
+
+    /**
+     * @var string
+     */
+    protected $pk = 'id';
+}

+ 89 - 0
crmeb/app/model/system/SystemRoute.php

@@ -0,0 +1,89 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\model\system;
+
+
+use crmeb\basic\BaseModel;
+use think\model\concern\SoftDelete;
+
+/**
+ * Class SystemRoute
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/6
+ * @package app\model\system
+ */
+class SystemRoute extends BaseModel
+{
+
+    use SoftDelete;
+
+    /**
+     * @var string
+     */
+    protected $name = 'system_route';
+
+    /**
+     * @var string
+     */
+    protected $key = 'id';
+
+    public function searchNameLikeAttr($query, $value)
+    {
+        if ('' !== $value) {
+            $query->where('name|path', 'LIKE', '%' . $value . '%');
+        }
+    }
+
+    public function setRequestAttr($value)
+    {
+        return json_encode($value);
+    }
+
+    public function getRequestAttr($value)
+    {
+        return json_decode($value, true);
+    }
+
+    public function setResponseAttr($value)
+    {
+        return json_encode($value);
+    }
+
+    public function getResponseAttr($value)
+    {
+        return json_decode($value, true);
+    }
+
+    public function setRequestExampleAttr($value)
+    {
+        return json_encode($value);
+    }
+
+    public function getRequestExampleAttr($value)
+    {
+        return json_decode($value, true);
+    }
+
+
+    public function setResponseExampleAttr($value)
+    {
+        return json_encode($value);
+    }
+
+    public function getResponseExampleAttr($value)
+    {
+        return json_decode($value, true);
+    }
+}

+ 44 - 0
crmeb/app/model/system/SystemRouteCate.php

@@ -0,0 +1,44 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\model\system;
+
+
+use crmeb\basic\BaseModel;
+
+class SystemRouteCate extends BaseModel
+{
+
+    /**
+     * @var string
+     */
+    protected $name = 'system_route_cate';
+
+    /**
+     * @var string
+     */
+    protected $pk = 'id';
+
+    protected $autoWriteTimestamp = false;
+
+    /**
+     * @return \think\model\relation\HasMany
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function children()
+    {
+        return $this->hasMany(SystemRoute::class, 'cate_id', 'id')->field(['id', 'cate_id', 'name', 'path', 'method'])->order('add_time desc');
+    }
+}

+ 28 - 0
crmeb/app/model/system/log/SystemFileInfo.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace app\model\system\log;
+
+use crmeb\basic\BaseModel;
+use crmeb\traits\ModelTrait;
+
+/**
+ * @author 吴汐
+ * @email 442384644@qq.com
+ * @date 2023/04/07
+ */
+class SystemFileInfo extends BaseModel
+{
+    use ModelTrait;
+
+    /**
+     * 数据表主键
+     * @var string
+     */
+    protected $pk = 'id';
+
+    /**
+     * 模型名称
+     * @var string
+     */
+    protected $name = 'system_file_info';
+}

+ 3 - 2
crmeb/app/outapi/middleware/AuthTokenMiddleware.php

@@ -28,6 +28,7 @@ class AuthTokenMiddleware implements MiddlewareInterface
     /**
      * @param Request $request
      * @param \Closure $next
+     * @return mixed
      * @throws \Psr\SimpleCache\InvalidArgumentException
      * @throws \think\db\exception\DataNotFoundException
      * @throws \think\db\exception\DbException
@@ -39,11 +40,11 @@ class AuthTokenMiddleware implements MiddlewareInterface
         /** @var OutAccountServices $services */
         $services = app()->make(OutAccountServices::class);
         $outInfo = $services->parseToken($token);
-        Request::macro('outId', function () use (&$outInfo) {
+        $request->macro('outId', function () use (&$outInfo) {
             return (int)$outInfo['id'];
         });
 
-        Request::macro('outInfo', function () use (&$outInfo) {
+        $request->macro('outInfo', function () use (&$outInfo) {
             return $outInfo;
         });
         /** @var OutInterfaceServices $outInterfaceServices */

+ 9 - 3
crmeb/app/services/order/StoreCartServices.php

@@ -16,6 +16,7 @@ use app\services\activity\advance\StoreAdvanceServices;
 use app\services\BaseServices;
 use app\dao\order\StoreCartDao;
 use app\services\activity\coupon\StoreCouponIssueServices;
+use app\services\product\shipping\ShippingTemplatesServices;
 use app\services\shipping\ShippingTemplatesNoDeliveryServices;
 use app\services\system\SystemUserLevelServices;
 use app\services\user\member\MemberCardServices;
@@ -584,9 +585,14 @@ class StoreCartServices extends BaseServices
                 foreach ($cartList as $item) {
                     $tempIds[] = $item['productInfo']['temp_id'];
                 }
-                /** @var ShippingTemplatesNoDeliveryServices $noDeliveryServices */
-                $noDeliveryServices = app()->make(ShippingTemplatesNoDeliveryServices::class);
-                $tempIds = $noDeliveryServices->isNoDelivery(array_unique($tempIds), $cityId);
+                $tempIds = array_unique($tempIds);
+                $shippingService = app()->make(\app\services\shipping\ShippingTemplatesServices::class);
+                $tempIds = $shippingService->getColumn([['id', 'in', $tempIds], ['no_delivery', '=', 1]], 'id');
+                if ($tempIds) {
+                    /** @var ShippingTemplatesNoDeliveryServices $noDeliveryServices */
+                    $noDeliveryServices = app()->make(ShippingTemplatesNoDeliveryServices::class);
+                    $tempIds = $noDeliveryServices->isNoDelivery(array_unique($tempIds), $cityId);
+                }
             }
         }
 

+ 11 - 2
crmeb/app/services/order/StoreOrderSplitServices.php

@@ -335,6 +335,7 @@ class StoreOrderSplitServices extends BaseServices
      * 部分发货重新计算订单商品:实际金额、优惠、积分等金额
      * @param int $cart_num
      * @param array $cart_info
+     * @param string $orderType
      * @return array
      */
     public function slpitComputeOrderCart(int $cart_num, array $cart_info, $orderType = 'new')
@@ -353,9 +354,17 @@ class StoreOrderSplitServices extends BaseServices
             if ($field == 'use_integral') $scale = 0;
             $new_cart_info[$field] = bcmul((string)$cart_num, bcdiv((string)$cart_info[$field], (string)$cart_info['cart_num'], 4), $scale);
             if ($orderType == 'new') {//拆出
-                $new_cart_info[$field] = bcmul((string)$cart_num, bcdiv((string)$cart_info[$field], (string)$cart_info['cart_num'], 4), $scale);
+                if ($field == 'sum_true_price') {
+                    $new_cart_info[$field] = round(bcmul((string)$cart_num, bcdiv((string)$cart_info[$field], (string)$cart_info['cart_num'], 4), 4), 2, PHP_ROUND_HALF_UP);
+                } else {
+                    $new_cart_info[$field] = bcmul((string)$cart_num, bcdiv((string)$cart_info[$field], (string)$cart_info['cart_num'], 4), $scale);
+                }
             } else {
-                $field_number = bcmul((string)bcsub((string)$cart_info['cart_num'], (string)$cart_num, 0), bcdiv((string)$cart_info[$field], (string)$cart_info['cart_num'], 4), $scale);
+                if ($field == 'sum_true_price') {
+                    $field_number = round(bcmul((string)bcsub((string)$cart_info['cart_num'], (string)$cart_num, 0), bcdiv((string)$cart_info[$field], (string)$cart_info['cart_num'], 4), 4), 2, PHP_ROUND_HALF_UP);
+                } else {
+                    $field_number = bcmul((string)bcsub((string)$cart_info['cart_num'], (string)$cart_num, 0), bcdiv((string)$cart_info[$field], (string)$cart_info['cart_num'], 4), $scale);
+                }
                 $new_cart_info[$field] = bcsub((string)$cart_info[$field], (string)$field_number, $scale);
             }
         }

+ 33 - 0
crmeb/app/services/shipping/SystemCityServices.php

@@ -152,4 +152,37 @@ class SystemCityServices extends BaseServices
         }, 0);
     }
 
+    /**
+     * 获取城市数据完整列表
+     * @return mixed
+     */
+    public function fullList($field = '*')
+    {
+        return CacheService::remember('CITY_FULL_LIST', function () use ($field) {
+            return $this->fullListTree($this->dao->fullList($field));
+        }, 0);
+    }
+
+    /**
+     * 格式化获取城市数据完整列表
+     * @param $data
+     * @param int $pid
+     * @param array $navList
+     * @return array|mixed
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/04/10
+     */
+    function fullListTree($data, $pid = 0, $navList = [])
+    {
+        foreach ($data as $k => $menu) {
+            if ($menu['parent_id'] == $pid) {
+                unset($menu['parent_id']);
+                unset($data[$k]);
+                $menu['children'] = $this->fullListTree($data, $menu['value']);
+                $navList[] = $menu;
+            }
+        }
+        return $navList;
+    }
 }

+ 301 - 0
crmeb/app/services/system/SystemCrudServices.php

@@ -0,0 +1,301 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\services\system;
+
+
+use app\dao\system\SystemCrudDao;
+use app\services\BaseServices;
+use crmeb\services\crud\Controller;
+use crmeb\services\crud\Dao;
+use crmeb\services\crud\Model;
+use crmeb\services\crud\Route;
+use crmeb\services\crud\Service;
+use crmeb\services\crud\Validate;
+use crmeb\services\crud\ViewApi;
+use crmeb\services\crud\ViewPages;
+use crmeb\services\crud\ViewRouter;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\migration\Migrator;
+use Phinx\Db\Adapter\MysqlAdapter;
+
+/**
+ * Class SystemCrudServices
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/6
+ * @package app\services\system
+ */
+class SystemCrudServices extends BaseServices
+{
+
+    /**
+     * SystemCrudServices constructor.
+     * @param SystemCrudDao $dao
+     */
+    public function __construct(SystemCrudDao $dao)
+    {
+        $this->dao = $dao;
+    }
+
+    public function getTabelRule()
+    {
+        $adapter = app()->make(MysqlAdapter::class);
+        return [
+            'types' => $adapter->getColumnTypes(),
+        ];
+    }
+
+    /**
+     * 获取表字段
+     * @param string $tableName
+     * @return mixed
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function getColumnNamesList(string $tableName)
+    {
+        $sql = 'SELECT * FROM `information_schema`.`columns` WHERE TABLE_SCHEMA = ? AND table_name = ? ORDER BY ORDINAL_POSITION';
+
+        $column = Db::query($sql, [config('database.connections.mysql.database'), $this->getTableName($tableName)]);
+
+        $columns = [];
+        foreach ($column as $item) {
+            $column = [
+                'name' => $item['COLUMN_NAME'],
+                'type' => $item['DATA_TYPE'],
+                'dataType' => stripos($item['COLUMN_TYPE'], '(') !== false ? substr_replace($item['COLUMN_TYPE'], '', stripos($item['COLUMN_TYPE'], ')') + 1) : $item['COLUMN_TYPE'],
+                'default' => $item['COLUMN_DEFAULT'],
+                'null' => $item['IS_NULLABLE'] == 'YES',
+                'primaryKey' => $item['COLUMN_KEY'] == 'PRI',
+                'unsigned' => (bool)stripos($item['COLUMN_TYPE'], 'unsigned'),
+                'autoIncrement' => stripos($item['EXTRA'], 'auto_increment') !== false,
+                'comment' => $item['COLUMN_COMMENT'],
+            ];
+            $columns[$item['COLUMN_NAME']] = $column;
+        }
+
+        return $columns;
+    }
+
+    public function createCrud(array $data)
+    {
+        $tableName = $data['tableName'];
+        $tableComment = $data['tableComment'];
+        $tableField = $data['tableField'];
+        $filePath = $data['filePath'];
+
+        //创建数据库
+        if ($tableField) {
+            $this->makeDatebase($tableName, $tableComment, $tableField);
+        }
+
+        //读取表结构
+        $column = $this->getColumnNamesList($tableName);
+        if (!$column) {
+            throw new ValidateException('请先创建' . $tableName . '表');
+        }
+
+        //TODO 没写完
+        $routeName = '';
+        $uniqueAuth = '';
+
+        $make = $this->makeFile($tableName, $routeName, true, $data, $filePath);
+        $makePath = [];
+        foreach ($make as $key => $item) {
+            $makePath[$key] = $item['path'];
+        }
+        //创建菜单
+        if (!$data['menuName']) {
+            $data['menuName'] = $tableName;
+        }
+        $data = [
+            'pid' => $data['pid'],
+            'menu_name' => $data['menuName'],
+            'menu_path' => '',
+            'auth_type' => 1,
+            'is_show' => 1,
+            'is_del' => 0,
+            'unique_auth' => $uniqueAuth,
+            'is_header' => $data['pid'] ? 0 : 1,
+        ];
+        $menuInfo = app()->make(SystemMenusServices::class)->save($data);
+        //写入路由权限
+        //TODO 没写完
+
+        //记录crud生成
+        $this->dao->save([
+            'pid' => $data['pid'],
+            'name' => $data['menuName'],
+            'table_name' => $tableName,
+            'field' => json_encode($data),
+            'make_path' => json_encode($makePath),
+            'add_time' => time()
+        ]);
+    }
+
+    /**
+     * 创建数据库
+     * @param string $tableName
+     * @param string $tableComment
+     * @param array $tableField
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function makeDatebase(string $tableName, string $tableComment, array $tableField = [])
+    {
+        $migrator = app()->make(Migrator::class);
+        //创建表
+        $table = $migrator->table($tableName, $tableComment);
+        //创建字段
+        foreach ($tableField as $item) {
+            $option = [];
+            if (!isset($item['limit'])) {
+                $option['limit'] = (int)$item['limit'];
+            }
+            if (!isset($item['default'])) {
+                $option['default'] = $item['default'];
+            }
+            $option['comment'] = $item['comment'];
+            $table->addColumn($item['field'], $item['type'], $option);
+        }
+        //创建修改和增加时间
+        if (!empty($data['tableTime'])) {
+            $table->addTimestamps();
+        }
+        //创建索引
+        if (!empty($data['tableIndex'])) {
+            foreach ($data['tableIndex'] as $item) {
+                $table->addIndex($item);
+            }
+        }
+        //创建伪删除
+        if (!empty($data['tableDelete'])) {
+            $table->addSoftDelete();
+        }
+        //执行创建
+        $table->create();
+    }
+
+    /**
+     * 创建文件返回文件路径和内容
+     * @param string $tableName
+     * @param string $routeName
+     * @param bool $isMake
+     * @param array $options
+     * @param array $filePath
+     * @return array[]
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function makeFile(string $tableName, string $routeName, bool $isMake = false, array $options = [], array $filePath = [])
+    {
+        //生成控制器
+        $controller = app()->make(Controller::class);
+        [$controllerContent, $controllerPath] = $controller->setFilePathName($filePath['controller'] ?? '')->isMake($isMake)->handle($tableName, '/');
+        //生成模型
+        $model = app()->make(Model::class);
+        [$modelContent, $modelPath] = $model->setFilePathName($filePath['model'] ?? '')->isMake($isMake)->handle($tableName, '/');
+        //生成dao
+        $dao = app()->make(Dao::class);
+        [$daoContent, $daoPath] = $dao->setFilePathName($filePath['dao'] ?? '')->isMake($isMake)->handle($tableName, '/');
+        //生成路由
+        $route = app()->make(Route::class);
+        [$routeContent, $routePath] = $route->setFilePathName($filePath['route'] ?? '')->isMake($isMake)->handle($tableName, '/', [
+            'menus' => $options['menuName'],
+            'route' => $routeName
+        ]);
+        //生成service
+        $service = app()->make(Service::class);
+        [$serviceContent, $servicePath] = $service->setFilePathName($filePath['service'] ?? '')->isMake($isMake)->handle($tableName, '/', [
+            'field' => $options['fromField']
+        ]);
+        //生成验证器
+        $validate = app()->make(Validate::class);
+        [$validateContent, $validatePath] = $validate->setFilePathName($filePath['validate'] ?? '')->isMake($isMake)->handle($tableName, '/');
+        //生成前台路由
+        $viewRouter = app()->make(ViewRouter::class);
+        [$routerContent, $routerPath] = $viewRouter->setFilePathName($filePath['router'] ?? '')->isMake($isMake)->handle($tableName, '/', [
+            'route' => $routeName,
+        ]);
+        //生成前台接口
+        $viewApi = app()->make(ViewApi::class);
+        [$apiContent, $apiPath] = $viewApi->setFilePathName($filePath['api'] ?? '')->isMake($isMake)->handle($tableName, '/', [
+            'route' => $routeName,
+        ]);
+        //生成前台页面
+        $viewPages = app()->make(ViewPages::class);
+        [$pagesContent, $pagesPath] = $viewPages->setFilePathName($filePath['pages'] ?? '')->isMake($isMake)->handle($tableName, '/', [
+            'field' => $options['columnField']
+        ]);
+
+        return [
+            'controller' => [
+                'path' => $controllerContent,
+                'content' => $controllerPath
+            ],
+            'model' => [
+                'path' => $modelPath,
+                'content' => $modelContent
+            ],
+            'dao' => [
+                'path' => $daoPath,
+                'content' => $daoContent
+            ],
+            'route' => [
+                'path' => $routePath,
+                'content' => $routeContent
+            ],
+            'service' => [
+                'path' => $servicePath,
+                'content' => $serviceContent
+            ],
+            'validate' => [
+                'path' => $validatePath,
+                'content' => $validateContent
+            ],
+            'router' => [
+                'path' => $routerPath,
+                'content' => $routerContent
+            ],
+            'api' => [
+                'path' => $apiPath,
+                'content' => $apiContent
+            ],
+            'pages' => [
+                'path' => $pagesPath,
+                'content' => $pagesContent
+            ],
+        ];
+    }
+
+    /**
+     * @param string $tableName
+     * @param bool $fullName
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function getTableName(string $tableName, bool $fullName = true)
+    {
+        $tablePrefix = config('database.connections.mysql.prefix');
+        $pattern = '/^' . $tablePrefix . '/i';
+        return ($fullName ? $tablePrefix : '') . (preg_replace($pattern, '', $tableName));
+    }
+
+}

+ 114 - 0
crmeb/app/services/system/SystemRouteCateServices.php

@@ -0,0 +1,114 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\services\system;
+
+
+use app\dao\system\SystemRouteCateDao;
+use app\services\BaseServices;
+use crmeb\services\FormBuilder;
+
+/**
+ * Class SystemRouteCateServices
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/6
+ * @package app\services\system
+ */
+class SystemRouteCateServices extends BaseServices
+{
+
+    /**
+     * SystemRouteCateServices constructor.
+     * @param SystemRouteCateDao $dao
+     */
+    public function __construct(SystemRouteCateDao $dao)
+    {
+        $this->dao = $dao;
+    }
+
+    public function getPathValue(array $path)
+    {
+        $pathAttr = explode('/', $path);
+        $pathData = [];
+        foreach ($pathAttr as $item) {
+            if (!$item) {
+                $pathData[] = $item;
+            }
+        }
+        return $pathAttr;
+    }
+
+    /**
+     * @param array $path
+     * @param int $id
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function setPathValue(array $path, int $id)
+    {
+        return ($path ? '/' . implode('/', $path) : '') . '/' . $id . '/';
+    }
+
+    /**
+     * @param string $appName
+     * @return array
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function getAllList(string $appName = 'outapi', string $field = '*')
+    {
+        $list = $this->dao->selectList(['app_name' => $appName], $field)->toArray();
+        return get_tree_children($list);
+    }
+
+    /**
+     * @param int $id
+     * @param string $appName
+     * @return array
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function getFrom(int $id = 0, string $appName = 'outapi')
+    {
+        $url = '/system/route_cate';
+        $cateInfo = [];
+        $path = [];
+        if ($id) {
+            $cateInfo = $this->dao->get($id);
+            $cateInfo = $cateInfo ? $cateInfo->toArray() : [];
+            $url .= '/' . $id;
+            $path = explode('/', $cateInfo['path']);
+            $newPath = [];
+            foreach ($path as $item) {
+                if ($item) {
+                    $newPath[] = $item;
+                }
+            }
+            $path = $newPath;
+        }
+        $options = $this->dao->selectList(['app_name' => $appName], 'name as label,id as value,id,pid')->toArray();
+        $rule = [
+            FormBuilder::cascader('path', '上级分类', $path)->data(get_tree_children($options)),
+            FormBuilder::input('name', '分类名称', $cateInfo['name'] ?? '')->required(),
+            FormBuilder::number('sort', '排序', (int)($cateInfo['sort'] ?? 0)),
+            FormBuilder::hidden('app_name', $appName)
+        ];
+
+        return create_form($id ? '修改分类' : '添加分类', $rule, $url, $id ? 'PUT' : 'POST');
+    }
+}

+ 254 - 0
crmeb/app/services/system/SystemRouteServices.php

@@ -0,0 +1,254 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace app\services\system;
+
+
+use app\dao\system\SystemRouteDao;
+use app\services\BaseServices;
+use crmeb\services\FormBuilder;
+use think\exception\ValidateException;
+use think\helper\Str;
+
+/**
+ * Class SystemRouteServices
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/6
+ * @package app\services\system
+ */
+class SystemRouteServices extends BaseServices
+{
+
+    /**
+     * SystemRouteServices constructor.
+     * @param SystemRouteDao $dao
+     */
+    public function __construct(SystemRouteDao $dao)
+    {
+        $this->dao = $dao;
+    }
+
+    /**
+     * @param array $where
+     * @return array
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function getList(array $where)
+    {
+        [$page, $limit] = $this->getPageValue();
+        $list = $this->dao->selectList($where, 'name,path,method', $page, $limit)->toArray();
+        $count = $this->dao->count($where);
+        return compact('list', 'count');
+    }
+
+    /**
+     * @param int $id
+     * @return array
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/10
+     */
+    public function getInfo(int $id)
+    {
+        $routeInfo = $this->dao->get($id);
+        if (!$routeInfo) {
+            throw new ValidateException('修改的路由不存在');
+        }
+
+        return $routeInfo->toArray();
+    }
+
+    /**
+     * 获取tree数据
+     * @param string $appName
+     * @return array
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function getTreeList(array $where, string $appName = 'adminapi')
+    {
+        $list = app()->make(SystemRouteCateServices::class)
+            ->selectList(['app_name' => $appName], '*', 0, 0, 'id asc,sort desc', [
+                'children' => function ($query) use ($where) {
+                    $query->where('app_name', $where['app_name'])
+                        ->when('' !== $where['name_like'], function ($q) use ($where) {
+                            $q->where('name|path', 'LIKE', '%' . $where['name_like'] . '%');
+                        });
+                }
+            ])
+            ->toArray();
+        return get_tree_children($list);
+    }
+
+    /**
+     * 获取某个应用下的所有路由权限
+     * @param string $app
+     * @return array
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function getRouteListAll(string $app = 'adminapi')
+    {
+        //获取所有的路由
+        $this->app = app();
+        $this->app->route->setTestMode(true);
+        $this->app->route->clear();
+        $path = $this->app->getRootPath() . 'app' . DS . $app . DS . 'route' . DS;
+        $files = is_dir($path) ? scandir($path) : [];
+        foreach ($files as $file) {
+            if (strpos($file, '.php')) {
+                include $path . $file;
+            }
+        }
+
+        $route = $this->app->route->getRuleList();
+        $action_arr = ['index', 'read', 'create', 'save', 'edit', 'update', 'delete'];
+
+        foreach ($route as &$item) {
+            $real_name = $item['option']['real_name'] ?? '';
+            if (is_array($real_name)) {
+                foreach ($action_arr as $action) {
+                    if (Str::contains($item['route'], $action)) {
+                        $real_name = $real_name[$action] ?? '';
+                    }
+                }
+            }
+            $item['option']['real_name'] = $real_name;
+        }
+
+        return $route;
+    }
+
+    /**
+     * 同步路由
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    public function syncRoute(string $app = 'adminapi')
+    {
+        $id = app()->make(SystemRouteCateServices::class)->value(['app_name' => $app, 'name' => '全部权限', 'pid' => 0], 'id');
+        if (!$id) {
+            $res = app()->make(SystemRouteCateServices::class)->save([
+                'app_name' => $app,
+                'name' => '全部权限',
+                'pid' => 0,
+                'add_time' => time(),
+            ]);
+            $id = $res->id;
+        }
+        $listAll = $this->getRouteListAll($app);
+        //保持新增的权限路由
+        $data = $this->dao->selectList(['app_name' => $app], 'path,method')->toArray();
+        $save = [];
+        foreach ($listAll as $item) {
+            if (!$this->diffRoute($data, $item['rule'], $item['method']) && strstr($item['rule'], '<MISS>') === false) {
+                $save[] = [
+                    'name' => $item['option']['real_name'] ?? $item['name'],
+                    'path' => $item['rule'],
+                    'cate_id' => $id,
+                    'app_name' => $app,
+                    'type' => isset($item['option']['is_common']) && $item['option']['is_common'] ? 1 : 0,
+                    'method' => $item['method'],
+                    'add_time' => date('Y-m-d H:i:s'),
+                ];
+            }
+        }
+
+        if ($save) {
+            $this->dao->saveAll($save);
+        }
+        //删除不存在的权限路由
+        $data = $this->dao->selectList(['app_name' => $app], 'path,method,id')->toArray();
+        $delete = [];
+        foreach ($data as $item) {
+            if (!$this->diffRoute($listAll, $item['path'], $item['method'], 'rule') && $item['path'] !== '<MISS>') {
+                $delete[] = $item['id'];
+            }
+        }
+        if ($delete) {
+            $this->dao->delete([['id', 'in', $delete]]);
+        }
+    }
+
+    /**
+     * 对比路由
+     * @param array $data
+     * @param string $path
+     * @param string $method
+     * @return bool
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/6
+     */
+    protected function diffRoute(array $data, string $path, string $method, string $key = 'path')
+    {
+        $res = false;
+        foreach ($data as $item) {
+            if (strtolower($item['method']) == strtolower($method) && strtolower($item[$key]) == strtolower($path)) {
+                $res = true;
+                break;
+            } else if ($method === '*' && strtolower($item[$key]) == strtolower($path)) {
+                $res = true;
+                break;
+            }
+        }
+        return $res;
+    }
+
+    /**
+     * 添加和修改路由
+     * @param int $id
+     * @return array
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function getFrom(int $id = 0, string $appName = 'adminapi')
+    {
+        $cateList = app()->make(SystemRouteCateServices::class)->getAllList($appName, 'name as label,path as value');
+
+        $url = '/system/route';
+        $routeInfo = [];
+        if ($id) {
+            $routeInfo = $this->dao->get($id);
+            $routeInfo = $routeInfo ? $routeInfo->toArray() : [];
+            $url .= '/' . $id;
+        }
+
+        $rule = [
+            FormBuilder::cascader('cate_id', '分类', $routeInfo['cate_id'] ?? 0)->data($cateList),
+            FormBuilder::input('name', '路由名称', $routeInfo['name'] ?? '')->required(),
+            FormBuilder::input('path', '路由路径', $routeInfo['path'] ?? '')->required(),
+            FormBuilder::select('method', '请求方式', $routeInfo['method'] ?? '')->options([
+                ['value' => 'POST', 'label' => 'POST'],
+                ['value' => 'GET', 'label' => 'GET'],
+                ['value' => 'DELETE', 'label' => 'DELETE'],
+                ['value' => 'PUT', 'label' => 'PUT'],
+                ['value' => '*', 'label' => '*'],
+            ])->required(),
+            FormBuilder::radio('type', '类型', $routeInfo['type'] ?? 0)->options([
+                ['value' => 0, 'lable' => '普通路由'],
+                ['value' => 1, 'lable' => '公共路由'],
+            ]),
+            FormBuilder::hidden('app_name', $appName),
+        ];
+
+        return create_form($id ? '修改路由' : '添加路由', $rule, $url, $id ? 'PUT' : 'POST');
+    }
+}

+ 1 - 1
crmeb/app/services/system/lang/LangCodeServices.php

@@ -29,7 +29,7 @@ class LangCodeServices extends BaseServices
     public function langCodeList(array $where = [])
     {
         [$page, $limit] = $this->getPageValue();
-        $list = $this->dao->selectList($where, '*', $page, $limit, 'id desc', true)->toArray();
+        $list = $this->dao->selectList($where, '*', $page, $limit, 'id desc', [], true)->toArray();
         /** @var LangTypeServices $langTypeServices */
         $langTypeServices = app()->make(LangTypeServices::class);
         $typeList = $langTypeServices->getColumn([['status', '=', 1], ['is_del', '=', 0]], 'language_name,file_name,id', 'id');

+ 24 - 0
crmeb/app/services/system/log/SystemFileInfoServices.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace app\services\system\log;
+
+use app\dao\system\log\SystemFileInfoDao;
+use app\services\BaseServices;
+
+/**
+ * @author 吴汐
+ * @email 442384644@qq.com
+ * @date 2023/04/07
+ */
+class SystemFileInfoServices extends BaseServices
+{
+    /**
+     * 构造方法
+     * SystemLogServices constructor.
+     * @param SystemFileInfoDao $dao
+     */
+    public function __construct(SystemFileInfoDao $dao)
+    {
+        $this->dao = $dao;
+    }
+}

+ 40 - 2
crmeb/app/services/system/log/SystemFileServices.php

@@ -19,9 +19,11 @@ use crmeb\exceptions\AdminException;
 use crmeb\exceptions\AuthException;
 use crmeb\services\CacheService;
 use crmeb\services\FileService as FileClass;
+use crmeb\services\FormBuilder as Form;
 use crmeb\utils\JwtAuth;
 use Firebase\JWT\ExpiredException;
 use think\facade\Log;
+use think\facade\Route as Url;
 
 /**
  * 文件校验
@@ -233,10 +235,10 @@ class SystemFileServices extends BaseServices
     //打开目录
     public function opendir()
     {
+        $markList = app()->make(SystemFileInfoServices::class)->getColumn([], 'mark', 'full_path');
         $fileAll = array('dir' => [], 'file' => []);
         //根目录
         $rootdir = $this->formatPath(app()->getRootPath());
-//        return $rootdir;
         //当前目录
         $request_dir = app('request')->param('dir');
         //防止查看站点以外的目录
@@ -285,6 +287,7 @@ class SystemFileServices extends BaseServices
             $navList[$key]['isDir'] = $value['isDir'];
             $navList[$key]['pathname'] = $value['pathname'];
             $navList[$key]['contextmenu'] = true;
+            $list[$key]['mark'] = $markList[str_replace(root_path(), '/', $value['pathname'])] ?? '';
         }
         return compact('dir', 'list', 'navList');
     }
@@ -426,11 +429,46 @@ class SystemFileServices extends BaseServices
             $path = rtrim($path, DS);
             if ($name) $path = $path . DS . $name;
             $uname = php_uname('s');
-//            $search = '/';
             if (strstr($uname, 'Windows') !== false)
                 $path = ltrim(str_replace('\\', '\\\\', $path), '.');
 
         }
         return $path;
     }
+
+    /**
+     * 文件备注表单
+     * @param $path
+     * @param $fileToken
+     * @return array
+     * @throws \FormBuilder\Exception\FormBuilderException
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/04/10
+     */
+    public function markForm($path, $fileToken)
+    {
+        $full_path = str_replace(root_path(), '/', $path);
+        $mark = app()->make(SystemFileInfoServices::class)->value(['full_path' => str_replace(root_path(), '/', $path)], 'mark');
+        $f = [];
+        $f[] = Form::hidden('full_path', $full_path);
+        $f[] = Form::input('mark', '文件备注', $mark);
+        return create_form('文件备注', $f, Url::buildUrl('/system/file/mark/save?fileToken=' . $fileToken . '&type=mark'), 'POST');
+    }
+
+    /**
+     * 保存文件备注
+     * @param $full_path
+     * @param $mark
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/04/10
+     */
+    public function fileMarkSave($full_path, $mark)
+    {
+        $res = app()->make(SystemFileInfoServices::class)->update(['full_path' => $full_path], ['mark' => $mark]);
+        if (!$res) {
+            throw new AdminException(100006);
+        }
+    }
 }

+ 1 - 1
crmeb/app/services/user/UserServices.php

@@ -1482,7 +1482,7 @@ class UserServices extends BaseServices
         $userMoney = app()->make(UserMoneyServices::class);
 
         $user['recharge'] = $userMoney->sum([
-            ['uid', '=', $uid], ['pm', '=', 1], ['type', 'in', ['recharge', 'system_add', 'extract']]
+            ['uid', '=', $uid], ['pm', '=', 1], ['type', 'in', ['recharge', 'system_add', 'extract', 'register_system_add']]
         ], 'number');
         $user['orderStatusSum'] = bcsub((string)$user['recharge'], (string)$user['now_money'], 2);
         $user['extractTotalPrice'] = $userExtract->getExtractSum(['uid' => $uid, 'status' => 1]);//累计提现

+ 2 - 1
crmeb/composer.json

@@ -48,7 +48,8 @@
         "alibabacloud/dysmsapi-20170525": "2.0.16",
         "fastknife/ajcaptcha": "^1.1",
         "volcengine/volc-sdk-php": "^1.0",
-        "workerman/crontab": "^1.0"
+        "workerman/crontab": "^1.0",
+        "topthink/think-migration": "^3.0"
     },
     "autoload": {
         "psr-4": {

+ 0 - 3
crmeb/config/console.php

@@ -19,9 +19,6 @@ return [
     'commands' => [
         'workerman' => \crmeb\command\Workerman::class,
         'timer' => \crmeb\command\Timer::class,
-        'make:business' => \crmeb\command\Business::class,
-        'make:dao' => \crmeb\command\Dao::class,
-        'make:service' => \crmeb\command\Service::class,
         'util' => \crmeb\command\Util::class
     ],
 ];

+ 20 - 0
crmeb/crmeb/command/Crud.php

@@ -0,0 +1,20 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\command\crud;
+
+
+class Crud
+{
+
+}

+ 0 - 46
crmeb/crmeb/command/Dao.php

@@ -1,46 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
-// +----------------------------------------------------------------------
-// | Author: CRMEB Team <admin@crmeb.com>
-// +----------------------------------------------------------------------
-namespace crmeb\command;
-
-use think\console\command\Make;
-
-/**
- * Class Business
- * @package crmeb\command
- */
-class Dao extends Make
-{
-    protected $type = "Dao";
-
-    protected function configure()
-    {
-        parent::configure();
-        $this->setName('make:dao')
-            ->setDescription('Create a new service class');
-    }
-
-    protected function getStub(): string
-    {
-        return __DIR__ . DIRECTORY_SEPARATOR. 'stubs' . DIRECTORY_SEPARATOR . 'dao.stub';
-    }
-
-    protected function getNamespace(string $app): string
-    {
-        return parent::getNamespace($app) . '\\dao';
-    }
-
-    protected function getPathName(string $name): string
-    {
-        $name = str_replace('app\\', '', $name);
-
-        return $this->app->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . 'Dao.php';
-    }
-}

+ 36 - 0
crmeb/crmeb/command/Npm.php

@@ -0,0 +1,36 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\command;
+
+
+use think\console\Command;
+use think\console\input\Argument;
+use think\console\input\Option;
+
+class Npm extends Command
+{
+    protected function configure()
+    {
+        $this->setName('npm')
+            ->addOption('path', 'dp', Option::VALUE_OPTIONAL, '默认路径')
+            ->addOption('build', 'bu', Option::VALUE_OPTIONAL, '打包存放路径')
+            ->addOption('zip', 'z', Option::VALUE_NONE, '打包成zip')
+            ->setDescription('NPM打包工具');
+    }
+
+    public function handle()
+    {
+
+    }
+}

+ 0 - 46
crmeb/crmeb/command/Service.php

@@ -1,46 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
-// +----------------------------------------------------------------------
-// | Author: CRMEB Team <admin@crmeb.com>
-// +----------------------------------------------------------------------
-namespace crmeb\command;
-
-use think\console\command\Make;
-
-/**
- * Class Business
- * @package crmeb\command
- */
-class Service extends Make
-{
-    protected $type = "Dao";
-
-    protected function configure()
-    {
-        parent::configure();
-        $this->setName('make:service')
-            ->setDescription('Create a new service class');
-    }
-
-    protected function getStub(): string
-    {
-        return __DIR__ . DIRECTORY_SEPARATOR. 'stubs' . DIRECTORY_SEPARATOR . 'service.stub';
-    }
-
-    protected function getNamespace(string $app): string
-    {
-        return parent::getNamespace($app) . '\\services';
-    }
-
-    protected function getPathName(string $name): string
-    {
-        $name = str_replace('app\\', '', $name);
-
-        return $this->app->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . 'Services.php';
-    }
-}

+ 3 - 2
crmeb/crmeb/command/Util.php

@@ -37,7 +37,7 @@ class Util extends Command
                 if (!$url) {
                     return $output->error('缺少替换的域名');
                 }
-                $this->replaceSiteUrl($host, $url);
+                $this->replaceSiteUrl($url, $host);
                 break;
         }
 
@@ -62,9 +62,10 @@ class Util extends Command
             "UPDATE `{$prefix}article_content` SET `content` = replace(`content` ,'{$siteUrl}','{$url}')",
             "UPDATE `{$prefix}store_category` SET `pic` = replace(`pic` ,'{$siteUrl}','{$url}')",
             "UPDATE `{$prefix}system_group_data` SET `value` = replace(value ,'{$siteUrlJosn}','{$valueJosn}')",
-            "UPDATE `{$prefix}eb_diy` SET `value` = replace(value ,'{$siteUrlJosn}','{$valueJosn}')",
+            "UPDATE `{$prefix}diy` SET `value` = replace(value ,'{$siteUrlJosn}','{$valueJosn}')",
             "UPDATE `{$prefix}store_product_description` SET `description`= replace(description,'{$siteUrl}','{$url}')"
         ];
+
         return Db::transaction(function () use ($sql) {
             try {
                 foreach ($sql as $item) {

+ 0 - 35
crmeb/crmeb/command/stubs/service.stub

@@ -1,35 +0,0 @@
-<?php
-// +----------------------------------------------------------------------
-// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
-// +----------------------------------------------------------------------
-// | Author: CRMEB Team <admin@crmeb.com>
-// +----------------------------------------------------------------------
-declare (strict_types = 1);
-
-namespace {%namespace%};
-
-use app\services\BaseServices;
-use app\dao\***\{%className%}Dao;
-
-/**
- *
- * Class {%className%}Services
- * @package {%namespace%}
- */
-class {%className%}Services extends BaseServices
-{
-
-    /**
-     * {%className%}Services constructor.
-     * @param {%className%}Dao $dao
-     */
-    public function __construct({%className%}Dao $dao)
-    {
-        $this->dao = $dao;
-    }
-
-}

+ 36 - 0
crmeb/crmeb/exceptions/CrudException.php

@@ -0,0 +1,36 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\exceptions;
+
+
+class CrudException extends \RuntimeException
+{
+    public function __construct($message = "", $replace = [], $code = 0, \Throwable $previous = null)
+    {
+        if (is_array($message)) {
+            $errInfo = $message;
+            $message = $errInfo[1] ?? '未知错误';
+            if ($code === 0) {
+                $code = $errInfo[0] ?? 400;
+            }
+        }
+
+        if (is_numeric($message)) {
+            $code = $message;
+            $message = getLang($message, $replace);
+        }
+
+        parent::__construct($message, $code, $previous);
+    }
+}

+ 145 - 0
crmeb/crmeb/services/crud/Controller.php

@@ -0,0 +1,145 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\services\crud;
+
+
+use think\helper\Str;
+
+/**
+ * 创建Controller
+ * Class Controller
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/3/13
+ * @package crmeb\servives\crud
+ */
+class Controller extends Make
+{
+
+    /**
+     * @var string
+     */
+    protected $name = 'controller';
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function setBaseDir(): string
+    {
+        return 'app' . DS . 'adminapi' . DS . 'controller' . DS . 'crud';
+    }
+
+    /**
+     * @return mixed|void
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    public function handle(string $name, string $path, array $options = [])
+    {
+        $contentPhp = '';
+        $var = ["{%date%}"];
+        $fieldPhp = [$this->value['date']];
+
+        $action = $options['action'] ?? [];
+        $field = $options['field'] ?? [];
+
+        if (!$action) {
+            $action = ['index', 'create', 'save', 'edit', 'update', 'delete'];
+        }
+
+        if ($field) {
+            $fieldStr = '';
+            foreach ($field as $k) {
+                $fieldStr .= "['$k',''],\n";
+            }
+            $fieldPhp[] = $fieldStr;
+        }
+
+        $res = false;
+        foreach ($action as $item) {
+            if (in_array($item, ['save', 'update'])) {
+                $res = true;
+            }
+            [$class, $stub] = $this->getStubContent($name, $item);
+            $contentPhp .= $stub . "\r\n";
+        }
+
+        if ($res) {
+            $var[] = '{%field-php%}';
+        }
+
+        if ($var && $fieldPhp) {
+            $contentPhp = str_replace($var, $fieldPhp, $contentPhp);
+        }
+
+        [$className, $contentController] = $this->getStubContent($name, 'controller');
+
+        $this->value['nameCamel'] = Str::studly($name);
+        $this->value['name'] = $className;
+        $this->value['path'] = $this->getfolderPath($path);
+        $this->value['content-php'] = $contentPhp;
+
+        $contentStr = str_replace($this->var, $this->value, $contentController);
+
+        $filePath = $this->getFilePathName($path, $this->value['nameCamel']);
+
+        return [$this->makeFile($filePath, $contentStr), $filePath];
+    }
+
+    /**
+     * 返回模板路径
+     * @param string $type
+     * @return mixed|string|string[]
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function getStub(string $type = '')
+    {
+        $controllerPath = __DIR__ . DS . 'stubs' . DS . 'controller' . DS;
+
+        $stubs = [
+            'index' => $controllerPath . 'index.stub',
+            'create' => $controllerPath . 'create.stub',
+            'save' => $controllerPath . 'save.stub',
+            'edit' => $controllerPath . 'edit.stub',
+            'update' => $controllerPath . 'update.stub',
+            'delete' => $controllerPath . 'delete.stub',
+            'controller' => $controllerPath . 'CrudController.stub',
+        ];
+
+        return $type ? $stubs[$type] : $stubs;
+    }
+
+    /**
+     * @param string $path
+     * @param string $name
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function getFilePathName(string $path, string $name): string
+    {
+        $path = str_replace(['app\\', 'app/'], '', $path);
+
+        $path = ltrim(str_replace('\\', '/', $path), '/');
+
+        return $this->getBasePath($path) . $name . '.' . $this->fileMime;
+    }
+}

+ 49 - 0
crmeb/crmeb/services/crud/Dao.php

@@ -0,0 +1,49 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace crmeb\services\crud;
+
+
+/**
+ * Class Business
+ * @package crmeb\services
+ */
+class Dao extends Make
+{
+    /**
+     * 当前命令名称
+     * @var string
+     */
+    protected $name = "dao";
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function setBaseDir(): string
+    {
+        return 'app' . DS . 'dao' . DS . 'crud';
+    }
+
+    /**
+     * 模板文件
+     * @param string $type
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function getStub(string $type = '')
+    {
+        return __DIR__ . DS . 'stubs' . DS . 'dao' . DS . 'CrudDao.stub';
+    }
+}

+ 438 - 0
crmeb/crmeb/services/crud/Make.php

@@ -0,0 +1,438 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\services\crud;
+
+use crmeb\exceptions\CrudException;
+use think\App;
+use think\helper\Str;
+
+/**
+ * 创建crud基类
+ * Class Make
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/3/13
+ * @package crmeb\services\crud
+ */
+abstract class Make
+{
+
+    /**
+     * 名称
+     * @var string
+     */
+    protected $name = '';
+
+    /**
+     * 文件类型
+     * @var string
+     */
+    protected $fileMime = 'php';
+
+    /**
+     * 文件全部路径
+     * @var string
+     */
+    protected $filePathName = null;
+
+    /**
+     * @var string
+     */
+    protected $fileBasePath;
+
+    /**
+     * 变量名称
+     * @var array
+     */
+    protected $var = [];
+
+    /**
+     * 内容
+     * @var array
+     */
+    protected $value = [];
+
+    /**
+     * @var bool
+     */
+    protected $isMake = true;
+
+    /**
+     * 后台前端模板根路径
+     * @var string
+     */
+    protected $adminTemplatePath;
+
+    /**
+     * 默认保存路径
+     * @var string
+     */
+    protected $basePath;
+
+    /**
+     * 默认文件夹
+     * @var string
+     */
+    protected $baseDir;
+
+    /**
+     * @var
+     */
+    protected $app;
+
+
+    /**
+     * Make constructor.
+     * @param App $app
+     */
+    public function __construct(App $app)
+    {
+        $this->app = $app;
+        $this->adminTemplatePath = dirname($this->app->getRootPath()) . DS . 'template' . DS . 'admin' . DS . 'src' . DS;
+        $this->basePath = $this->app->getRootPath();
+        $this->baseDir = $this->setBaseDir();
+        $this->var = $this->authDrawVar();
+        $this->value = $this->drawValueKeys();
+        $this->setDefaultValue();
+    }
+
+    /**
+     * 设置默认保存目录
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function setBaseDir(): string
+    {
+        return 'crud';
+    }
+
+    /**
+     * 获取保存文件的目录
+     * @param string $path
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function getBasePath(string $path = '')
+    {
+        //替换成本地路径格式
+        $path = str_replace('/', DS, $path);
+        $pathAttr = explode(DS, $path);
+        $basePathAttr = explode(DS, $this->baseDir);
+        //替换掉和基础目录相同的
+        if (count($pathAttr) > 1) {
+            $newsPath = array_merge(array_diff($basePathAttr, $pathAttr))[0] ?? '';
+            if ($newsPath !== 'crud') {
+                $path = $newsPath;
+            } else {
+                $this->baseDir = '';
+            }
+        }
+        //多个斜杠的替换成一个
+        $this->fileBasePath = str_replace(DS . DS, DS, $this->basePath . ($this->baseDir ? $this->baseDir . DS : '') . ($path ? $path . DS : ''));
+
+        return $this->fileBasePath;
+    }
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function getFileBasePath()
+    {
+        return $this->fileBasePath;
+    }
+
+    /**
+     * 设置文件保存就路径名称
+     * @param string $filePathName
+     * @return $this
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/7
+     */
+    public function setFilePathName(string $filePathName = '')
+    {
+        if ($filePathName) {
+            $this->filePathName = $filePathName;
+        }
+        return $this;
+    }
+
+    /**
+     * 生成tab
+     * @param int $num
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/29
+     */
+    public function tab(int $num = 1): string
+    {
+        return str_pad('', 4 * $num);
+    }
+
+    /**
+     * 是否生成文件
+     * @param bool $isMake
+     * @return $this
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/3
+     */
+    public function isMake(bool $isMake = true)
+    {
+        $this->isMake = $isMake;
+        return $this;
+    }
+
+    /**
+     * 执行创建
+     * @return mixed|void
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    public function handle(string $name, string $path, array $options = [])
+    {
+
+        [$nameData, $content] = $this->getStubContent($name);
+
+        $this->value['name'] = $nameData;
+        if (isset($this->value['nameCamel']) && !$this->value['nameCamel']) {
+            $this->value['nameCamel'] = Str::studly($name);
+        }
+        if (isset($this->value['path'])) {
+            $this->value['path'] = $this->getfolderPath($path);
+        }
+
+        $contentStr = str_replace($this->var, $this->value, $content);
+
+        $filePath = $this->getFilePathName($path, $this->value['nameCamel']);
+
+        return [$this->makeFile($filePath, $contentStr), $filePath];
+    }
+
+    /**
+     * 模板文件配置
+     * @param string $type
+     * @return mixed
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    abstract protected function getStub(string $type = '');
+
+    /**
+     * 自动获取模板变量
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/29
+     */
+    protected function authDrawVar(): array
+    {
+        $content = file_get_contents($this->getStub());
+        $pattern = '/\{\%+[a-zA-Z0-9_-]+\%\}/';
+        preg_match_all($pattern, $content, $var);
+        $varData = $var[0] ?? [];
+        $varData = array_unique($varData);
+        return $varData;
+    }
+
+    /**
+     * 提取value key
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/29
+     */
+    protected function drawValueKeys(): array
+    {
+        $data = [];
+        foreach ($this->var as $value) {
+            $data[str_replace(['{%', '%}'], '', $value)] = '';
+        }
+        return $data;
+    }
+
+    /**
+     * 设置默认值
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function setDefaultValue()
+    {
+        if (isset($this->value['year'])) {
+            $this->value['year'] = date('Y');
+        }
+        if (isset($this->value['time'])) {
+            $this->value['time'] = date('Y/m/d H:i:s');
+        }
+        if (isset($this->value['date'])) {
+            $this->value['date'] = date('Y/m/d');
+        }
+    }
+
+    /**
+     * 提取模板文件
+     * @param string $name
+     * @return array
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function getStubContent(string $name, string $type = '')
+    {
+        $stub = file_get_contents($this->getStub($type));
+
+        $namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');
+
+        $class = str_replace($namespace . '\\', '', $name);
+
+        return [$class, $stub];
+    }
+
+    /**
+     * 获取文件路径
+     * @param string $path
+     * @param string $name
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function getFilePathName(string $path, string $name): string
+    {
+        $path = ltrim(str_replace('\\', '/', $path), '/');
+
+        return $this->getBasePath($path) . $name . ucwords($this->name) . '.' . $this->fileMime;
+    }
+
+    /**
+     * @param string $path
+     * @return mixed|string|null
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function getfolderPath(string $path)
+    {
+        $path = ltrim(str_replace('\\', '/', $path), '/');
+        $pathArr = explode('/', $path);
+        $count = count($pathArr);
+        $res = $pathArr[$count - 1] ?? null;
+        if ($pathArr && $res && $res == $this->name) {
+            return '';
+        } else {
+            return '\\' . $res;
+        }
+    }
+
+    /**
+     * 获取保存文件路径
+     * @param string $name
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function getPathName(string $name): string
+    {
+        $name = str_replace('app\\', '', $name);
+
+        return $this->app->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . '.php';
+    }
+
+    /**
+     * 获取类名
+     * @param string $name
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function getClassName(string $name): string
+    {
+        if (strpos($name, '\\') !== false) {
+            return $name;
+        }
+
+        if (strpos($name, '@')) {
+            [$app, $name] = explode('@', $name);
+        } else {
+            $app = '';
+        }
+
+        if (strpos($name, '/') !== false) {
+            $name = str_replace('/', '\\', $name);
+        }
+
+        return $this->getNamespace($app) . '\\' . $name;
+    }
+
+    /**
+     * 获取命名空间名
+     * @param string $app
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function getNamespace(string $app): string
+    {
+        return 'app' . ($app ? '\\' . $app : '');
+    }
+
+    /**
+     * 执行创建文件
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function makeFile(string $pathname, string $content)
+    {
+
+        $pathname = $this->filePathName ?: $pathname;
+
+        if (is_file($pathname)) {
+            throw new CrudException($this->name . ':' . $pathname . ' already exists!');
+        }
+
+        $content = str_replace('', '', $content);
+
+        if ($this->isMake) {
+
+            try {
+                if (!is_dir(dirname($pathname))) {
+                    mkdir(dirname($pathname), 0755, true);
+                }
+            } catch (\Throwable $e) {
+                throw new CrudException('CRUD创建目录报错,无法创建:' . dirname($pathname));
+            }
+
+            try {
+                file_put_contents($pathname, $content);
+            } catch (\Throwable $e) {
+                throw new CrudException('CRUD生成文件报错,无法写入:' . $pathname);
+            }
+        }
+
+        return $content;
+    }
+}

+ 55 - 0
crmeb/crmeb/services/crud/Model.php

@@ -0,0 +1,55 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\services\crud;
+
+
+/**
+ * Class Model
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/3/13
+ * @package crmeb\command\crud
+ */
+class Model extends Make
+{
+    /**
+     * 当前命令名称
+     * @var string
+     */
+    protected $name = "model";
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function setBaseDir(): string
+    {
+        return 'app' . DS . 'model' . DS . 'crud';
+    }
+
+    /**
+     * 模板文件
+     * @param string $type
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function getStub(string $type = '')
+    {
+        return __DIR__ . DS . 'stubs' . DS . 'model' . DS . 'CrudModel.stub';
+    }
+}

+ 112 - 0
crmeb/crmeb/services/crud/Route.php

@@ -0,0 +1,112 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\services\crud;
+
+
+use crmeb\exceptions\CrudException;
+
+class Route extends Make
+{
+    /**
+     * @var string
+     */
+    protected $name = 'route';
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function setBaseDir(): string
+    {
+        return 'app' . DS . 'adminapi' . DS . 'route' . DS . 'crud';
+    }
+
+    /**
+     * @param string $name
+     * @param string $path
+     * @param array $options
+     * @return mixed|void
+     */
+    public function handle(string $name, string $path, array $options = [])
+    {
+        $action = $options['action'] ?? [];
+        $route = $options['route'] ?? '';
+        $controller = $options['controller'] ?? '';
+        $menus = $options['menus'] ?? '';
+        if (!$route) {
+            throw new CrudException('缺少路由名称');
+        }
+        if (!$action) {
+            $action = ['index', 'create', 'save', 'edit', 'update', 'delete'];
+        }
+
+        $var = [
+            '{%route%}',
+            '{%controller%}',
+            '{%menus%}',
+        ];
+
+        $value = [
+            $route,
+            $controller ? '.' . $controller : '',
+            $menus
+        ];
+
+        $routeContent = "";
+        foreach ($action as $item) {
+            $routeContent .= $this->getStub($item) . "\r\n";
+        }
+
+        if ($var && $value) {
+            $routeContent = str_replace($var, $value, $routeContent);
+        }
+
+        $content = $this->getStub();
+
+        $this->value['content-php'] = $routeContent;
+
+        $contentStr = str_replace($this->var, $this->value, $content);
+
+        $filePath = $this->getFilePathName($path, $this->value['nameCamel']);
+
+        return [$this->makeFile($filePath, $contentStr), $filePath];
+    }
+
+    /**
+     * 设置模板
+     * @param string $type
+     * @return mixed|string|string[]
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/14
+     */
+    protected function getStub(string $type = 'route')
+    {
+        $routePath = __DIR__ . DS . 'stubs' . DS . 'route' . DS;
+
+        $stubs = [
+            'index' => $routePath . 'index.stub',
+            'create' => $routePath . 'create.stub',
+            'save' => $routePath . 'save.stub',
+            'edit' => $routePath . 'edit.stub',
+            'update' => $routePath . 'update.stub',
+            'delete' => $routePath . 'delete.stub',
+            'route' => $routePath . 'route.stub',
+        ];
+
+        return $type ? $stubs[$type] : $stubs;
+    }
+}

+ 155 - 0
crmeb/crmeb/services/crud/Service.php

@@ -0,0 +1,155 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace crmeb\services\crud;
+
+use think\helper\Str;
+
+/**
+ * Class Business
+ * @package crmeb\services
+ */
+class Service extends Make
+{
+    /**
+     * @var string
+     */
+    protected $name = "services";
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function setBaseDir(): string
+    {
+        return 'app' . DS . 'services' . DS . 'crud';
+    }
+
+    /**
+     * @param string $name
+     * @param string $path
+     * @param array $options
+     * @return mixed|void
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/23
+     */
+    public function handle(string $name, string $path, array $options = [])
+    {
+
+        $this->value['use-php'] = $this->getDaoClassName($name, $path);
+
+        $action = $options['action'] ?? [];
+        $field = $options['field'] ?? [];
+
+        if (!$action) {
+            $action = ['index', 'form', 'save', 'update'];
+        }
+
+        $contentAction = '';
+        foreach ($action as $item) {
+            [$class, $stub] = $this->getStubContent($name, $item);
+            $contentAction .= $stub . "\n";
+        }
+
+        //生成form表单
+        if (in_array('save', $action) || in_array('update', $action)) {
+            $var = ['{%date%}', '{%route%}', '{%form-php%}', '{%menus%}'];
+            $value = [$this->value['date'], Str::snake($options['route'] ?? $name)];
+            $from = [];
+            foreach ($field as $item) {
+                $from[] = $this->tab(2) . '$rule[] = FormBuilder::' . $item['type'] . '("' . $item['field'] . '","' . $item['name'] . '",$info["' . $item['field'] . '"] ?? "")' . $this->getOptionContent($item['option'] ?? []) . (!empty($item['required']) ? '->required()' : '') . ';';
+            }
+            if ($from) {
+                $this->value['use-php'] .= "\n" . 'use crmeb\services\FormBuilder;';
+                $value[] = implode("\n", $from);
+            }
+            $value[] = $options['menus'] ?? $name;
+
+            if ($value && $var) {
+                $contentAction = str_replace($var, $value, $contentAction);
+            }
+        }
+
+        //生成service
+        [$className, $content] = $this->getStubContent($name, $this->name);
+
+        $this->value['nameCamel'] = Str::studly($name);
+        $this->value['name'] = $className;
+        $this->value['path'] = $this->getfolderPath($path);
+        $this->value['content-php'] = $contentAction;
+
+        $contentStr = str_replace($this->var, $this->value, $content);
+
+        $filePath = $this->getFilePathName($path, $this->value['nameCamel']);
+
+        return [$this->makeFile($filePath, $contentStr), $filePath];
+    }
+
+    /**
+     * @param array $option
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/23
+     */
+    protected function getOptionContent(array $option = [])
+    {
+        $php = '';
+        if ($option) {
+            $res = var_export($option, true);
+
+            $strOption = str_replace(['array', '(', ')'], ['', '[', ']'], $res);
+            $php = '->options(' . $strOption . ')';
+        }
+
+        return $php;
+    }
+
+    /**
+     * @param string $name
+     * @param string $path
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/23
+     */
+    protected function getDaoClassName(string $name, string $path)
+    {
+        $path = str_replace(['app\\services', 'app/services'], '', $path);
+        $path = ltrim(str_replace('\\', '/', $path), '/');
+        return 'use app\dao\\' . ($path ? $path . '\\' : '') . Str::studly($name) . 'Dao;';
+    }
+
+
+    /**
+     * @param string $type
+     * @return mixed|string|string[]
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/3/13
+     */
+    protected function getStub(string $type = 'services')
+    {
+        $servicePath = __DIR__ . DS . 'stubs' . DS . 'service' . DS;
+
+        $stubs = [
+            'index' => $servicePath . 'CrudListIndex.stub',
+            'form' => $servicePath . 'GetCrudForm.stub',
+            'save' => $servicePath . 'CrudSave.stub',
+            'update' => $servicePath . 'CrudUpdate.stub',
+            'services' => $servicePath . 'CrudService.stub',
+        ];
+
+        return $type ? $stubs[$type] : $stubs;
+    }
+}

+ 50 - 0
crmeb/crmeb/services/crud/Validate.php

@@ -0,0 +1,50 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\services\crud;
+
+/**
+ * Class Validate
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/3/29
+ * @package crmeb\services\crud
+ */
+class Validate extends Make
+{
+    /**
+     * @var string
+     */
+    protected $name = 'validate';
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function setBaseDir(): string
+    {
+        return 'app' . DS . 'adminapi' . DS . 'validate' . DS . 'crud';
+    }
+
+    /**
+     * 模板文件配置
+     * @param string $type
+     * @return mixed
+     */
+    protected function getStub(string $type = '')
+    {
+        return __DIR__ . DS . 'stubs' . DS . 'validate' . DS . 'CrudValidate.stub';
+    }
+}

+ 145 - 0
crmeb/crmeb/services/crud/ViewApi.php

@@ -0,0 +1,145 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\services\crud;
+
+use crmeb\exceptions\CrudException;
+use think\App;
+use think\helper\Str;
+
+/**
+ * Class ViewApi
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/1
+ * @package crmeb\services\crud
+ */
+class ViewApi extends Make
+{
+
+    /**
+     * @var string
+     */
+    protected $name = 'api';
+
+    /**
+     * @var string
+     */
+    protected $fileMime = 'js';
+
+    /**
+     * ViewApi constructor.
+     * @param App $app
+     */
+    public function __construct(App $app)
+    {
+        parent::__construct($app);
+        $this->basePath = $this->adminTemplatePath;
+    }
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function setBaseDir(): string
+    {
+        return 'api' . DS . 'crud';
+    }
+
+    /**
+     * @param string $name
+     * @param string $path
+     * @param array $options
+     * @return array
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    public function handle(string $name, string $path, array $options = [])
+    {
+
+        $action = $options['action'] ?? [];
+        if (!$action) {
+            $action = ['index', 'create', 'save', 'edit', 'update'];
+        }
+        $route = $options['route'] ?? '';
+        if (!$route) {
+            throw new CrudException('缺少路由名称');
+        }
+
+        $contentJs = '';
+
+        foreach ($action as $item) {
+            $contentJs .= file_get_contents($this->getStub($item)) . "\n";
+        }
+
+        $nameCamel = Str::studly($name);
+
+        if ($contentJs) {
+            $var = ['{%name%}', '{%route%}', '{%nameCamel%}'];
+            $value = [$name, $route, $nameCamel];
+            $contentJs = str_replace($var, $value, $contentJs);
+        }
+
+        $this->value['content-js'] = $contentJs;
+
+        //生成api
+        [$className, $content] = $this->getStubContent($name, $this->name);
+
+        $contentStr = str_replace($this->var, $this->value, $content);
+        $filePath = $this->getFilePathName($path, Str::camel($name));
+
+        $content = $this->makeFile($filePath, $contentStr);
+
+        return [$content, $filePath];
+    }
+
+    /**
+     * @param string $path
+     * @param string $name
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function getFilePathName(string $path, string $name): string
+    {
+        $path = ltrim(str_replace('\\', '/', $path), '/');
+
+        return $this->getBasePath($path) . $name . '.' . $this->fileMime;
+    }
+
+    /**
+     * 模板文件配置
+     * @param string $type
+     * @return mixed
+     */
+    protected function getStub(string $type = 'api')
+    {
+        $servicePath = __DIR__ . DS . 'stubs' . DS . 'view' . DS . 'api' . DS;
+
+        $stubs = [
+            'index' => $servicePath . 'getCrudListApi.stub',
+            'create' => $servicePath . 'crudUpdateApi.stub',
+            'save' => $servicePath . 'crudSaveApi.stub',
+            'edit' => $servicePath . 'getCrudEditApi.stub',
+            'update' => $servicePath . 'CrudUpdateApi.stub',
+            'api' => $servicePath . 'crud.stub',
+        ];
+
+        return $type ? $stubs[$type] : $stubs;
+    }
+
+}

+ 112 - 0
crmeb/crmeb/services/crud/ViewPages.php

@@ -0,0 +1,112 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\services\crud;
+
+use think\App;
+use think\helper\Str;
+
+/**
+ * Class ViewPages
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/1
+ * @package crmeb\services\crud
+ */
+class ViewPages extends Make
+{
+
+    /**
+     * @var string
+     */
+    protected $name = 'pages';
+
+    /**
+     * @var string
+     */
+    protected $fileMime = 'vue';
+
+    /**
+     * ViewPages constructor.
+     * @param App $app
+     */
+    public function __construct(App $app)
+    {
+        parent::__construct($app);
+        $this->basePath = $this->adminTemplatePath;
+    }
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function setBaseDir(): string
+    {
+        return 'pages' . DS . 'crud';
+    }
+
+    /**
+     * @param string $name
+     * @param string $path
+     * @param array $options
+     * @return false|mixed|void
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/3
+     */
+    public function handle(string $name, string $path, array $options = [])
+    {
+        $field = $options['field'] ?? [];
+
+        $columnStr = [];
+        foreach ($field as $item) {
+            $columnStr[] = "{\n\"title:\"{$item['name']},\n\"key:\"{$item['field']}\n}";
+        }
+        $this->value['auth'] = Str::snake($name);
+        $this->value['content-vue'] = "\n" . implode(',', $columnStr);
+        $this->value['pathApiJs'] = $options['pathApiJs'] ?? '';
+        $this->value['nameCamel'] = Str::snake($name, '-');
+
+        return parent::handle($name, $path, $options);
+    }
+
+    /**
+     * @param string $path
+     * @param string $name
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function getFilePathName(string $path, string $name): string
+    {
+        $path = ltrim(str_replace('\\', '/', $path), '/');
+        return $this->getBasePath($path) . $name . '.' . $this->fileMime;
+    }
+
+    /**
+     * @param string $type
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/1
+     */
+    protected function getStub(string $type = '')
+    {
+        return __DIR__ . DS . 'stubs' . DS . 'view' .
+            DS . 'pages' . DS . 'crud' .
+            DS . 'index.stub';
+    }
+}

+ 122 - 0
crmeb/crmeb/services/crud/ViewRouter.php

@@ -0,0 +1,122 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+namespace crmeb\services\crud;
+
+use crmeb\exceptions\CrudException;
+use think\App;
+use think\helper\Str;
+
+/**
+ * Class ViewRouter
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/1
+ * @package crmeb\services\crud
+ */
+class ViewRouter extends Make
+{
+    /**
+     * @var string
+     */
+    protected $name = 'router';
+
+    /**
+     * @var string
+     */
+    protected $fileMime = 'js';
+
+    /**
+     * ViewRouter constructor.
+     * @param App $app
+     */
+    public function __construct(App $app)
+    {
+        parent::__construct($app);
+        $this->basePath = $this->adminTemplatePath;
+    }
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    protected function setBaseDir(): string
+    {
+        return 'router' . DS . 'modules' . DS . 'crud';
+    }
+
+    /**
+     * @param string $name
+     * @param string $path
+     * @param array $options
+     * @return false|mixed|void
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/4
+     */
+    public function handle(string $name, string $path, array $options = [])
+    {
+        [$nameData, $content] = $this->getStubContent($name);
+
+        $menus = $options['menus'] ?? $name;
+        $route = $options['route'] ?? Str::snake($name);
+        $pagePath = $options['pagePath'] ?? Str::camel($name);
+        if (!$route) {
+            throw new CrudException('缺少路由名称');
+        }
+
+        $this->value['menus'] = $menus;
+        $this->value['name'] = $nameData;
+        $this->value['route'] = $route;
+        $this->value['pagePath'] = $pagePath;
+        if (isset($this->value['path'])) {
+            $this->value['path'] = $this->getfolderPath($path);
+        }
+
+        $contentStr = str_replace($this->var, $this->value, $content);
+
+        $filePath = $this->getFilePathName($path, Str::camel($name));
+
+        $makeContent = $this->makeFile($filePath, $contentStr);
+
+        return [$makeContent, $filePath];
+    }
+
+    /**
+     * @param string $path
+     * @param string $name
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/3
+     */
+    protected function getFilePathName(string $path, string $name): string
+    {
+        $path = ltrim(str_replace('\\', '/', $path), '/');
+        return $this->getBasePath($path) . $name . '.' . $this->fileMime;
+    }
+
+    /**
+     * @param string $type
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/1
+     */
+    protected function getStub(string $type = '')
+    {
+        return __DIR__ . DS . 'stubs' . DS . 'view' . DS . 'router' . DS . 'modules' . DS . 'crud.stub';
+    }
+}

+ 51 - 0
crmeb/crmeb/services/crud/stubs/controller/CrudController.stub

@@ -0,0 +1,51 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~{%year%} https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+/**
+ * @author crud自动生成代码
+ * @date {%time%}
+ */
+
+namespace app\adminapi\controller\v1{%path%};
+
+use app\adminapi\controller\AuthController;
+use think\facade\App;
+
+/**
+ * Class {%nameCamel%}
+ * @date {%date%}
+ * @package app\adminapi\controller\v1{%path%}
+ */
+class {%nameCamel%} extends AuthController
+{
+
+    /**
+     * @var {%nameCamel%}Service
+     */
+    protected $service;
+
+    /**
+     * {%nameCamel%}Controller constructor.
+     * @param App $app
+     * @param {%nameCamel%}Service $service
+     */
+    public function __construct(App $app, {%nameCamel%}Service $service)
+    {
+        parent::__construct($app);
+        $this->service = $service;
+    }
+
+
+    {%content-php%}
+
+}

+ 9 - 0
crmeb/crmeb/services/crud/stubs/controller/create.stub

@@ -0,0 +1,9 @@
+    /**
+     * 创建
+     * @return \think\Response
+     * @date {%date%}
+     */
+    public function create()
+    {
+        return app('json')->success($this->service->getCrudForm());
+    }

+ 18 - 0
crmeb/crmeb/services/crud/stubs/controller/delete.stub

@@ -0,0 +1,18 @@
+    /**
+     * 删除
+     * @param $id
+     * @return \think\Response
+     * @date {%date%}
+     */
+    public function delete($id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+
+        if ($this->service->delete($id)) {
+            return app('json')->success(100002);
+        } else {
+            return app('json')->success(100008);
+        }
+    }

+ 10 - 0
crmeb/crmeb/services/crud/stubs/controller/edit.stub

@@ -0,0 +1,10 @@
+    /**
+     * 编辑获取数据
+     * @param $id
+     * @return \think\Response
+     * @date {%date%}
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->service->getCrudForm($id));
+    }

+ 9 - 0
crmeb/crmeb/services/crud/stubs/controller/index.stub

@@ -0,0 +1,9 @@
+    /**
+     * 列表
+     * @date {%date%}
+     * @return \think\Response
+     */
+    public function index()
+    {
+        return app('json')->success($this->service->getCrudListIndex());
+    }

+ 15 - 0
crmeb/crmeb/services/crud/stubs/controller/save.stub

@@ -0,0 +1,15 @@
+    /**
+     * 保存
+     * @return \think\Response
+     * @date {%date%}
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            {%field-php%}
+        ]);
+
+        $this->service->crudSave($data);
+
+        return app('json')->success(100021);
+    }

+ 20 - 0
crmeb/crmeb/services/crud/stubs/controller/update.stub

@@ -0,0 +1,20 @@
+    /**
+     * 修改
+     * @param $id
+     * @return \think\Response
+     * @date {%date%}
+     */
+    public function update($id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+
+        $data = $this->request->postMore([
+            {%field-php%}
+        ]);
+
+        $this->service->crudUpdate((int)$id, $data);
+
+        return app('json')->success(100001);
+    }

+ 41 - 0
crmeb/crmeb/services/crud/stubs/dao/CrudDao.stub

@@ -0,0 +1,41 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~{%year%} https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+/**
+ * @author crud自动生成代码
+ * @date {%time%}
+ */
+
+namespace app\dao{%path%};
+
+
+use app\dao\BaseDao;
+
+/**
+ * Class {%nameCamel%}Dao
+ * @date {%date%}
+ * @package app\dao{%path%}
+ */
+class {%nameCamel%}Dao extends BaseDao
+{
+
+    /**
+     * 设置模型
+     * @return string
+     * @date {%date%}
+     */
+    protected function setModel(): string
+    {
+        return {%nameCamel%}Model::class;
+    }
+}

+ 43 - 0
crmeb/crmeb/services/crud/stubs/model/CrudModel.stub

@@ -0,0 +1,43 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~{%year%} https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+/**
+ * @author crud自动生成代码
+ * @date {%time%}
+ */
+
+namespace app\model{%path%};
+
+
+use crmeb\basic\BaseModel;
+
+/**
+ * Class {%nameCamel%}
+ * @date {%date%}
+ * @package app\model{%path%}
+ */
+class {%nameCamel%} extends BaseModel
+{
+
+    /**
+     * 表名
+     * @var string
+     */
+    protected $name = '{%name%}';
+
+    /**
+     * @var string
+     */
+    protected $key = '{%key%}';
+
+}

+ 1 - 0
crmeb/crmeb/services/crud/stubs/route/create.stub

@@ -0,0 +1 @@
+Route::get('{%route%}/create', 'v1.{%route%}{%controller%}/create')->name('{%menus%}获取创建表单接口');

+ 1 - 0
crmeb/crmeb/services/crud/stubs/route/delete.stub

@@ -0,0 +1 @@
+Route::delete('{%route%}/:id', 'v1.{%route%}{%controller%}/delete')->name('{%menus%}删除数据接口');

+ 1 - 0
crmeb/crmeb/services/crud/stubs/route/edit.stub

@@ -0,0 +1 @@
+Route::get('{%route%}/:id/edit', 'v1.{%route%}{%controller%}/edit')->name('{%menus%}获取修改表单接口');

+ 1 - 0
crmeb/crmeb/services/crud/stubs/route/index.stub

@@ -0,0 +1 @@
+Route::get('{%route%}', 'v1.{%route%}{%controller%}/index')->name('{%menus%}列表接口');

+ 7 - 0
crmeb/crmeb/services/crud/stubs/route/route.stub

@@ -0,0 +1,7 @@
+<?php
+
+
+use think\facade\Route;
+
+{%content-php%}
+

+ 1 - 0
crmeb/crmeb/services/crud/stubs/route/save.stub

@@ -0,0 +1 @@
+Route::post('{%route%}', 'v1.{%route%}{%controller%}/save')->name('{%menus%}保存数据接口');

+ 1 - 0
crmeb/crmeb/services/crud/stubs/route/update.stub

@@ -0,0 +1 @@
+Route::put('{%route%}/:id', 'v1.{%route%}{%controller%}/update')->name('{%menus%}修改数据接口');

+ 13 - 0
crmeb/crmeb/services/crud/stubs/service/CrudListIndex.stub

@@ -0,0 +1,13 @@
+    /**
+     * 主页数据接口
+     * @param array $where
+     * @return array
+     * @date {%date%}
+     */
+    public function getCrudListIndex(array $where = [])
+    {
+        [$page, $limit] = $this->getPageValue();
+        $model = $this->dao->selectModel($where, '*', $page, $limit);
+
+        return ['count' => $model->count(), 'list' => $model->select()->toArray()];
+    }

+ 10 - 0
crmeb/crmeb/services/crud/stubs/service/CrudSave.stub

@@ -0,0 +1,10 @@
+    /**
+     * 新增
+     * @date {%date%}
+     * @param array $data
+     * @return mixed
+     */
+    public function crudSave(array $data)
+    {
+        return $this->dao->save($data);
+    }

+ 44 - 0
crmeb/crmeb/services/crud/stubs/service/CrudService.stub

@@ -0,0 +1,44 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~{%year%} https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+/**
+ * @author crud自动生成代码
+ * @date {%time%}
+ */
+
+namespace app\services{%path%};
+
+use app\services\BaseServices;
+use think\exception\ValidateException;
+{%use-php%}
+
+/**
+ * Class CrudService
+ * @date {%date%}
+ * @package app\services{%path%}
+ */
+class {%nameCamel%}Service extends BaseServices
+{
+
+    /**
+     * {%nameCamel%}Service constructor.
+     * @param {%nameCamel%}Dao $dao
+     */
+    public function __construct({%nameCamel%}Dao $dao)
+    {
+        $this->dao = $dao;
+    }
+
+    {%content-php%}
+
+}

+ 11 - 0
crmeb/crmeb/services/crud/stubs/service/CrudUpdate.stub

@@ -0,0 +1,11 @@
+    /**
+     * 修改
+     * @date {%date%}
+     * @param int $id
+     * @param array $data
+     * @return \crmeb\basic\BaseModel
+     */
+    public function crudUpdate(int $id, array $data)
+    {
+        return $this->dao->update($id, $data);
+    }

+ 23 - 0
crmeb/crmeb/services/crud/stubs/service/GetCrudForm.stub

@@ -0,0 +1,23 @@
+    /**
+     * 编辑和获取表单
+     * @date {%date%}
+     * @param int $id
+     * @return array
+     */
+    public function getCrudForm(int $id = 0)
+    {
+        $url = '/{%route%}';
+        $info = [];
+        if ($id) {
+            $info = $this->dao->get($id);
+            if (!$info) {
+                throw new ValidateException(100026);
+            }
+            $url .= '/' . $id;
+        }
+        $rule = [];
+
+{%form-php%}
+
+        return create_form('{%menus%}', $rule, $url, $id ? 'PUT' : 'POST');
+    }

+ 52 - 0
crmeb/crmeb/services/crud/stubs/validate/CrudValidate.stubs

@@ -0,0 +1,52 @@
+<?php
+/**
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~{%year%} https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+
+/**
+ * @author crud自动生成代码
+ * @date {%time%}
+ */
+
+namespace app\adminapi\validate{%path%};
+
+
+use think\Validate;
+
+/**
+ * Class CrudValidate
+ * @date {%date%}
+ * @package app\adminapi\validate{%path%}
+ */
+class {%nameCamel%}Validate extends Validate
+{
+
+    /**
+     * @var array
+     */
+    protected $rule = [
+
+    ];
+
+    /**
+     * @var array
+     */
+    protected $message = [
+
+    ];
+
+    /**
+     * @var array
+     */
+    protected $scene = [
+
+    ];
+}

+ 3 - 25
crmeb/crmeb/command/stubs/dao.stub

@@ -1,35 +1,13 @@
-<?php
 // +----------------------------------------------------------------------
 // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// | Copyright (c) 2016~{%year%} https://www.crmeb.com All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
 // +----------------------------------------------------------------------
 // | Author: CRMEB Team <admin@crmeb.com>
 // +----------------------------------------------------------------------
-declare (strict_types = 1);
 
-namespace {%namespace%};
+import request from '@/libs/request';
 
-use app\dao\BaseDao;
-use app\model\***\{%className%};
-
-/**
- *
- * Class {%className%}Dao
- * @package {%namespace%}
- */
-class {%className%}Dao extends BaseDao
-{
-
-    /**
-     * 设置模型
-     * @return string
-     */
-    protected function setModel(): string
-    {
-        return {%className%}::class;
-    }
-
-}
+{%content-js%}

+ 11 - 0
crmeb/crmeb/services/crud/stubs/view/api/crudDeleteApi.stub

@@ -0,0 +1,11 @@
+/**
+ * 删除数据
+ * @param id
+ * @return {*}
+ */
+export function {%name%}DeleteApi(id) {
+    return request({
+        url: `{%route%}/${id}`,
+        method: 'delete'
+    });
+}

+ 12 - 0
crmeb/crmeb/services/crud/stubs/view/api/crudSaveApi.stub

@@ -0,0 +1,12 @@
+/**
+ * 添加数据
+ * @param data
+ * @return {*}
+ */
+export function {%name%}SaveApi(data) {
+    return request({
+        url: '{%route%}',
+        method: 'post',
+        data
+    });
+}

+ 12 - 0
crmeb/crmeb/services/crud/stubs/view/api/crudUpdateApi.stub

@@ -0,0 +1,12 @@
+/**
+ * 修改数据
+ * @param id
+ * @return {*}
+ */
+export function {%name%}UpdateApi(id, data) {
+    return request({
+        url: `{%route%}/${id}`,
+        method: 'put',
+        data
+    });
+}

+ 10 - 0
crmeb/crmeb/services/crud/stubs/view/api/getCrudCreateApi.stub

@@ -0,0 +1,10 @@
+/**
+ * 获取添加表单数据
+ * @return {*}
+ */
+export function get{%nameCamel%}CreateApi() {
+    return request({
+        url: '{%route%}/create',
+        method: 'get',
+    });
+}

+ 11 - 0
crmeb/crmeb/services/crud/stubs/view/api/getCrudEditApi.stub

@@ -0,0 +1,11 @@
+/**
+ * 获取编辑表单数据
+ * @param id
+ * @return {*}
+ */
+export function get{%nameCamel%}EditApi(id) {
+    return request({
+        url: `{%route%}/${id}`,
+        method: 'get'
+    });
+}

+ 12 - 0
crmeb/crmeb/services/crud/stubs/view/api/getCrudListApi.stub

@@ -0,0 +1,12 @@
+/**
+ * 获取列表数据
+ * @param params
+ * @return {*}
+ */
+export function get{%nameCamel%}ListApi(params) {
+    return request({
+        url: '{%route%}',
+        method: 'get',
+        params,
+    });
+}

+ 137 - 0
crmeb/crmeb/services/crud/stubs/view/pages/crud/index.stub

@@ -0,0 +1,137 @@
+<template>
+  <div>
+    <Card :bordered="false" dis-hover class="ivu-mt">
+      <Row type="flex">
+        <Col v-bind="grid">
+          <Button v-auth="['{%auth%}']" type="primary" icon="md-add" @click="add">添加{%menus%}</Button>
+        </Col>
+      </Row>
+      <Table
+          :columns="columns"
+          :data="dataList"
+          ref="table"
+          class="mt25"
+          :loading="loading"
+          highlight-row
+          no-userFrom-text="暂无数据"
+          no-filtered-userFrom-text="暂无筛选结果"
+      >
+        <template slot-scope="{ row, index }" slot="icons">
+          <div class="tabBox_img" v-viewer>
+            <img v-lazy="row.icon" />
+          </div>
+        </template>
+        <template slot-scope="{ row, index }" slot="action">
+          <a @click="edit(row.id)">修改</a>
+          <Divider type="vertical" />
+          <a @click="del(row, '删除{%menus%}', index)">删除</a>
+        </template>
+      </Table>
+      <div class="acea-row row-right page">
+        <Page :total="total" show-elevator show-total @on-change="pageChange" :page-size="from.limit" />
+      </div>
+    </Card>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex';
+import { {%name%}SaveApi, {%name%}DeleteApi, {%name%}UpdateApi, get{%nameCamel%}CreateApi, get{%nameCamel%}EditApi, get{%nameCamel%}ListApi} from '@/api/{%pathApiJs%}';
+export default {
+  name: 'user_group',
+  data() {
+    return {
+      grid: {
+        xl: 7,
+        lg: 7,
+        md: 12,
+        sm: 24,
+        xs: 24,
+      },
+      loading: false,
+      columns: [
+        {
+          title: 'ID',
+          key: 'id',
+          width: 80,
+        },{%content-vue%}
+        {
+          title: '操作',
+          slot: 'action',
+          fixed: 'right',
+          minWidth: 120,
+        },
+      ],
+      from: {
+        page: 1,
+        limit: 15,
+      },
+      dataList: [],
+      total: 0,
+    };
+  },
+  computed: {
+    ...mapState('media', ['isMobile']),
+    labelWidth() {
+      return this.isMobile ? undefined : 75;
+    },
+    labelPosition() {
+      return this.isMobile ? 'top' : 'left';
+    },
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    // 添加
+    add() {
+      this.$modalForm(get{%nameCamel%}CreateApi()).then(() => this.getList());
+    },
+    //列表
+    getList() {
+      this.loading = true;
+      get{%nameCamel%}ListApi(this.from)
+          .then(async (res) => {
+            let data = res.data;
+            this.dataList = data.list;
+            this.total = data.count;
+            this.loading = false;
+          })
+          .catch((res) => {
+            this.loading = false;
+            this.$Message.error(res.msg);
+          });
+    },
+    //分页
+    pageChange(index) {
+      this.from.page = index;
+      this.getList();
+    },
+    // 修改
+    edit(id) {
+      this.$modalForm(get{%nameCamel%}EditApi(id)).then(() => this.getList());
+    },
+    // 删除
+    del(row, tit, num) {
+      let delfromData = {
+        title: tit,
+        num: num,
+        url: `{%route%}/${row.id}`,
+        method: 'DELETE',
+        ids: '',
+      };
+      this.$modalSure(delfromData)
+          .then((res) => {
+            this.$Message.success(res.msg);
+            this.groupLists.splice(num, 1);
+            this.getList();
+          })
+          .catch((res) => {
+            this.$Message.error(res.msg);
+          });
+    },
+  },
+};
+</script>
+
+<style scoped lang="stylus"></style>

+ 39 - 0
crmeb/crmeb/services/crud/stubs/view/router/modules/crud.stub

@@ -0,0 +1,39 @@
+// +---------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +---------------------------------------------------------------------
+// | Copyright (c) 2016~{%year%} https://www.crmeb.com All rights reserved.
+// +---------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +---------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +---------------------------------------------------------------------
+
+import BasicLayout from '@/components/main';
+import setting from '@/setting'
+
+let routePre = setting.routePre
+
+const meta = {
+    auth: true,
+}
+
+const pre = '{%name%}_'
+
+export default {
+    path: `${routePre}/{%route%}`,
+    name: '{%name%}',
+    header: '{%nameHeader%}',
+    meta,
+    component: BasicLayout,
+    children: [
+        {
+            path: 'list',
+            name: `${pre}list`,
+            meta: {
+                auth: ['{%name%}-list-index'],
+                title: '{%menus%}',
+            },
+            component: () => import('@/pages/{%pagePath%}/index'),
+        },
+    ],
+}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
crmeb/public/admin/css.worker.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
crmeb/public/admin/editor.worker.js


BIN
crmeb/public/admin/favicon.ico


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
crmeb/public/admin/html.worker.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
crmeb/public/admin/index.html


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
crmeb/public/admin/json.worker.js


+ 0 - 0
crmeb/public/admin/system_static/css/app.cbd44cf8.css


Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor