liaofei преди 2 години
родител
ревизия
2f2a075046

+ 53 - 15
crmeb/app/adminapi/controller/v1/setting/SystemCrud.php

@@ -67,14 +67,29 @@ class SystemCrud extends AuthController
             ['tableComment', ''],//表备注
             ['tableField', []],//表字段
             ['tableIndex', []],//索引
-            ['tableTime', 0],//表是否增加修改和添加时间
-            ['tableDelete', 0],//表是否增加伪删除
-            ['fromField', []],
-            ['columnField', []],
             ['filePath', []],
             ['isTable', 0],
         ]);
 
+        $fromField = $columnField = [];
+        foreach ($data['tableField'] as $item) {
+            if ($item['is_table']) {
+                $columnField[] = [
+                    'field' => $item['field'],
+                    'name' => $item['table_name'],
+                ];
+            }
+            if ($item['from_type']) {
+                $fromField[] = [
+                    'field' => $item['field'],
+                    'name' => $item['table_name'],
+                    'required' => $item['required'],
+                    'option' => $item['option'] ?? [],
+                ];
+            }
+        }
+        $data['fromField '] = $fromField;
+        $data['columnField '] = $columnField;
         if (!$data['tableName']) {
             return app('json')->fail('缺少表名');
         }
@@ -93,12 +108,9 @@ class SystemCrud extends AuthController
      */
     public function getFilePath()
     {
-        [$menuName, $tableName, $isTable, $fromField, $columnField] = $this->request->postMore([
-            ['menuName', ''],
+        [$tableName, $isTable] = $this->request->postMore([
             ['tableName', ''],
             ['isTable', 0],
-            ['fromField', []],
-            ['columnField', []],
         ], true);
 
         if (!$tableName) {
@@ -112,9 +124,9 @@ class SystemCrud extends AuthController
         $routeName = 'crud/' . Str::snake($tableName);
 
         $make = $this->services->makeFile($tableName, $routeName, false, [
-            'menuName' => $menuName,
-            'fromField' => $fromField,
-            'columnField' => $columnField,
+            'menuName' => '',
+            'fromField' => [],
+            'columnField' => [],
         ]);
 
         $makePath = [];
@@ -129,7 +141,17 @@ class SystemCrud extends AuthController
                 return app('json')->fail('表不存在');
             }
             foreach ($field as $item) {
-                $tableField[] = ['value' => $item['name'], 'all' => $item, 'comment' => $item['comment'], 'label' => $item['name']];
+                $tableField[] = [
+                    'field' => $item['name'],
+                    'file_type' => $item['type'],
+                    'default' => $item['default'],
+                    'limit' => $item['limit'],
+                    'comment' => $item['comment'],
+                    'required' => false,
+                    'is_table' => false,
+                    'table_name' => '',
+                    'from_type' => '',
+                ];
             }
         }
 
@@ -164,12 +186,28 @@ class SystemCrud extends AuthController
                 break;
             }
         }
-
+        $fromField = $columnField = [];
+        foreach ($info->tableField as $item) {
+            if ($item['is_table']) {
+                $columnField[] = [
+                    'field' => $item['field'],
+                    'name' => $item['table_name'],
+                ];
+            }
+            if ($item['from_type']) {
+                $fromField[] = [
+                    'field' => $item['field'],
+                    'name' => $item['table_name'],
+                    'required' => $item['required'],
+                    'option' => $item['option'] ?? [],
+                ];
+            }
+        }
         $make = $this->services->makeFile($info->table_name, $routeName, false, [
             'menuName' => $info->name,
             'key' => $key,
-            'fromField' => $info->field['fromField'] ?? [],
-            'columnField' => $info->field['columnField'] ?? [],
+            'fromField' => $fromField,
+            'columnField' => $columnField,
         ]);
 
         $data = [];

+ 60 - 31
crmeb/app/services/system/SystemCrudServices.php

@@ -87,33 +87,62 @@ class SystemCrudServices extends BaseServices
      */
     public function getTabelRule()
     {
+        $rule = [
+            'varchat' => 'string',
+            'int' => 'integer',
+            'biginteger' => 'bigint',
+        ];
         return [
             'types' => [
-                'string',
+                'varchar',
                 'char',
                 'text',
-                'integer',
-                'biginteger',
-                'float',
-                'decimal',
+                'longtext',
+                'tinytext',
+                'enum',
+                'blob',
+                'binary',
+                'varbinary',
+
                 'datetime',
                 'timestamp',
                 'time',
                 'date',
-                'blob',
-                'binary',
-                'varbinary',
+                'year',
+
                 'boolean',
-                'uuid',
-                // Geospatial data types
-                'geometry',
-                'point',
-                'linestring',
-                'polygon',
-            ]
+                'tinyint',
+                'int',
+                'decimal',
+                'float',
+
+                'json',
+
+                'addTimestamps',
+                'addSoftDelete',
+            ],
+            'rule' => $rule
         ];
     }
 
+    /**
+     * 改变数据库类型
+     * @param string $type
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/13
+     */
+    public function changeTabelRule(string $type)
+    {
+
+        if (!in_array($type, $this->getTabelRule()['type'])) {
+            throw new ValidateException('类型不在支持范围');
+        }
+
+        return $this->getTabelRule()['rule'][$type] ?? $type;
+    }
+
     /**
      * 获取表字段
      * @param string $tableName
@@ -140,6 +169,7 @@ class SystemCrudServices extends BaseServices
                 'unsigned' => (bool)stripos($item['COLUMN_TYPE'], 'unsigned'),
                 'autoIncrement' => stripos($item['EXTRA'], 'auto_increment') !== false,
                 'comment' => $item['COLUMN_COMMENT'],
+                'limit' => $item['CHARACTER_MAXIMUM_LENGTH'] ?: $item['NUMERIC_PRECISION'],
             ];
             $columns[$item['COLUMN_NAME']] = $column;
         }
@@ -199,7 +229,7 @@ class SystemCrudServices extends BaseServices
         if (!$column) {
             throw new ValidateException('请先创建' . $tableName . '表');
         }
-
+        //获取主键
         foreach ($column as $value) {
             if ($value['primaryKey']) {
                 $data['key'] = $value['name'];
@@ -209,7 +239,7 @@ class SystemCrudServices extends BaseServices
 
         $routeName = 'crud/' . Str::snake($tableName);
         $uniqueAuth = Str::snake($tableName) . '-crud-list-index';
-
+        //增加保存的绝对路径
         foreach ($filePath as $k => $i) {
             if (in_array($k, ['pages', 'router', 'api'])) {
                 $filePath[$k] = Make::adminTemplatePath() . $i;
@@ -300,13 +330,12 @@ class SystemCrudServices extends BaseServices
                 ];
             }
             app()->make(SystemMenusServices::class)->saveAll($menuData);
-
+            //生成文件
             $make = $this->makeFile($tableName, $routeName, true, $data, $filePath);
             $makePath = [];
             foreach ($make as $key => $item) {
                 $makePath[$key] = $item['path'];
             }
-
             //记录crud生成
             $res = $this->dao->save([
                 'pid' => $data['pid'],
@@ -334,7 +363,7 @@ class SystemCrudServices extends BaseServices
      */
     public function makeDatebase(string $tableName, string $tableComment, array $tableField = [])
     {
-        $migrator = app()->make(Migrator::class);
+        $migrator = app()->make(Migrator::class, [date('YmdHis')]);
         //创建表
         $table = $migrator->table($tableName, $tableComment);
         //创建字段
@@ -346,12 +375,16 @@ class SystemCrudServices extends BaseServices
             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 ($item['type'] === 'addSoftDelete') {
+                $table->addSoftDelete();
+            } else if ($item['type'] === 'addTimestamps') {
+                //创建修改和增加时间
+                $table->addTimestamps();
+            } else {
+                $option['comment'] = $item['comment'];
+                $table->addColumn($item['field'], $this->changeTabelRule($item['type']), $option);
+            }
         }
         //创建索引
         if (!empty($data['tableIndex'])) {
@@ -359,10 +392,6 @@ class SystemCrudServices extends BaseServices
                 $table->addIndex($item);
             }
         }
-        //创建伪删除
-        if (!empty($data['tableDelete'])) {
-            $table->addSoftDelete();
-        }
         //执行创建
         $table->create();
     }
@@ -385,7 +414,7 @@ class SystemCrudServices extends BaseServices
         $options['columnField'] = is_array($options['columnField']) ? $options['columnField'] : [];
         //生成模型
         $model = app()->make(Model::class);
-        [$modelContent, $modelPath, $usePath] = $model->setFilePathName($filePath['model'] ?? '')->isMake($isMake)->handle($tableName);
+        [$modelContent, $modelPath, $usePath] = $model->setFilePathName($filePath['model'] ?? '')->isMake($isMake)->handle($tableName, $options);
         //生成dao
         $dao = app()->make(Dao::class);
         [$daoContent, $daoPath, $usePath] = $dao->setFilePathName($filePath['dao'] ?? '')->isMake($isMake)->handle($tableName, [

+ 2 - 1
crmeb/config/console.php

@@ -19,6 +19,7 @@ return [
     'commands' => [
         'workerman' => \crmeb\command\Workerman::class,
         'timer' => \crmeb\command\Timer::class,
-        'util' => \crmeb\command\Util::class
+        'util' => \crmeb\command\Util::class,
+        'npm' => \crmeb\command\Npm::class
     ],
 ];

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

@@ -1,20 +0,0 @@
-<?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
-{
-
-}

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

@@ -14,12 +14,26 @@
 namespace crmeb\command;
 
 
+use crmeb\services\FileService;
+use crmeb\utils\Terminal;
 use think\console\Command;
 use think\console\input\Argument;
 use think\console\input\Option;
 
+/**
+ * Class Npm
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/13
+ * @package crmeb\command
+ */
 class Npm extends Command
 {
+    /**
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/13
+     */
     protected function configure()
     {
         $this->setName('npm')
@@ -29,8 +43,40 @@ class Npm extends Command
             ->setDescription('NPM打包工具');
     }
 
+    /**
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/13
+     */
     public function handle()
     {
+        $path = $this->input->getOption('path');
+        $build = $this->input->getOption('build');
+        $zip = $this->input->getOption('zip');
+        if (!$build) {
+            $build = public_path() . 'admin';
+        }
+
+        $terminal = new Terminal();
+        $terminal->setOutput($this->output);
+
+        $adminPath = $terminal->adminTemplatePath();
+
+        $adminPath = dirname($adminPath);
+        $dir = $adminPath . DS . 'node_modules';
+        if (!is_dir($dir)) {
+            $terminal->run('npm-install');
+        }
+
+        $terminal->run('npm-build');
+
+        if (!is_dir($adminPath . DS . 'dist')) {
+            $this->output->error('打包失败');
+            return;
+        }
+
+        FileService::copyDir($adminPath . 'dist', $build);
 
+        $this->output->info('执行成功');
     }
 }

+ 12 - 1
crmeb/crmeb/command/Util.php

@@ -3,6 +3,7 @@
 namespace crmeb\command;
 
 
+use app\services\system\SystemRouteServices;
 use crmeb\exceptions\AdminException;
 use think\console\Command;
 use think\console\Input;
@@ -17,9 +18,10 @@ class Util extends Command
     protected function configure()
     {
         $this->setName('util')
-            ->addArgument('type', Argument::REQUIRED, '类型replace')
+            ->addArgument('type', Argument::REQUIRED, '类型replace/route')
             ->addOption('h', null, Option::VALUE_REQUIRED, '替换成当前域名')
             ->addOption('u', null, Option::VALUE_REQUIRED, '替换的域名')
+            ->addOption('a', null, Option::VALUE_REQUIRED, '应用名')
             ->setDescription('工具类');
     }
 
@@ -39,6 +41,13 @@ class Util extends Command
                 }
                 $this->replaceSiteUrl($url, $host);
                 break;
+            case 'route':
+                $appName = $input->getOption('a');
+                if (!$appName) {
+                    return $output->error('缺少应用名称');
+                }
+                app()->make(SystemRouteServices::class)->syncRoute($appName);
+                break;
         }
 
         $output->info('执行成功');
@@ -47,7 +56,9 @@ class Util extends Command
     protected function replaceSiteUrl(string $url, string $siteUrl)
     {
         $siteUrlJosn = str_replace('http://', 'http:\\\/\\\/', $siteUrl);
+        $siteUrlJosn = str_replace('https://', 'https:\\\/\\\/', $siteUrlJosn);
         $valueJosn = str_replace('http://', 'http:\\\/\\\/', $url);
+        $valueJosn = str_replace('https://', 'https:\\\/\\\/', $valueJosn);
         $prefix = Config::get('database.connections.' . Config::get('database.default') . '.prefix');
         $sql = [
             "UPDATE `{$prefix}system_attachment` SET `att_dir` = replace(att_dir ,'{$siteUrl}','{$url}'),`satt_dir` = replace(satt_dir ,'{$siteUrl}','{$url}')",

+ 208 - 0
crmeb/crmeb/utils/Terminal.php

@@ -0,0 +1,208 @@
+<?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\utils;
+
+use think\Response;
+use think\console\Output;
+
+/**
+ * 执行命令
+ * Class Terminal
+ * @author 等风来
+ * @email 136327134@qq.com
+ * @date 2023/4/13
+ * @package crmeb\utils
+ */
+class Terminal
+{
+    /**
+     * 命令
+     * @var \string[][]
+     */
+    protected $command = [
+        'npm-build' => [
+            'run_root' => '',
+            'command' => 'npm run build',
+        ],
+        'npm-install' => [
+            'run_root' => '',
+            'command' => 'npm run install',
+        ],
+    ];
+
+    /**
+     * 执行内容保存地址
+     * @var string
+     */
+    protected $outputFile;
+
+    /**
+     * 执行状态
+     * @var integer
+     */
+    protected $procStatus;
+
+    /**
+     * 响应内容
+     * @var string
+     */
+    protected $outputContent;
+
+    /**
+     * @var
+     */
+    protected $output;
+
+    /**
+     * Terminal constructor.
+     */
+    public function __construct()
+    {
+        $this->command['npm-build']['run_root'] = str_replace('DS', DS, config('app.admin_template_path'));
+        $this->command['npm-install']['run_root'] = str_replace('DS', DS, config('app.admin_template_path'));
+
+        $outputDir = root_path() . 'runtime' . DIRECTORY_SEPARATOR . 'terminal';
+        $this->outputFile = $outputDir . DIRECTORY_SEPARATOR . 'exec.log';
+        if (!is_dir($outputDir)) {
+            mkdir($outputDir, 0755, true);
+        }
+        file_put_contents($this->outputFile, '');
+    }
+
+    /**
+     * @param Output $output
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/13
+     */
+    public function setOutput(Output $output)
+    {
+        $this->output = $output;
+    }
+
+    /**
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/13
+     */
+    public function adminTemplatePath()
+    {
+        return $this->command['npm-install']['run_root'];
+    }
+
+    /**
+     * 执行
+     * @param string $name
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/13
+     */
+    public function run(string $name)
+    {
+        if (!function_exists('proc_open')) {
+            throw new \RuntimeException('缺少proc_open函数无法运行');
+        }
+
+        if (!isset($this->command[$name])) {
+            throw new \RuntimeException('运行的命令不存在');
+        }
+
+        $command = $this->command[$name];
+
+        $descriptorspec = [0 => ['pipe', 'r'], 1 => ['file', $this->outputFile, 'w'], 2 => ['file', $this->outputFile, 'w']];
+        $process = proc_open($command['command'], $descriptorspec, $pipes, $command['run_root'], null, ['suppress_errors' => true]);
+        if (is_resource($process)) {
+            while ($this->getProcStatus($process)) {
+                $contents = file_get_contents($this->outputFile);
+                if (strlen($contents) && $this->outputContent != $contents) {
+                    $newOutput = str_replace($this->outputContent, '', $contents);
+                    if (preg_match('/\r\n|\r|\n/', $newOutput)) {
+                        $this->echoOutputFlag($newOutput);
+                        $this->outputContent = $contents;
+                    }
+                }
+                usleep(500000);
+            }
+            foreach ($pipes as $pipe) {
+                fclose($pipe);
+            }
+            proc_close($process);
+        }
+
+        return $this->output('run success');
+    }
+
+    /**
+     * 判断状态
+     * @param $process
+     * @return bool
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/13
+     */
+    public function getProcStatus($process): bool
+    {
+        $status = proc_get_status($process);
+        if ($status['running']) {
+            $this->procStatus = 1;
+            return true;
+        } elseif ($this->procStatus === 1) {
+            $this->procStatus = 0;
+            $this->output('exit: ' . $status['exitcode']);
+            if ($status['exitcode'] === 0) {
+                $this->echoOutputFlag('success');
+            } else {
+                $this->echoOutputFlag('error');
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 直接输入响应
+     * @param string $message
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/13
+     */
+    protected function echoOutputFlag(string $message)
+    {
+        if ($this->output && $this->output instanceof Output) {
+            $this->output->info($message);
+        } else {
+            echo $this->output($message);
+            @ob_flush();
+        }
+    }
+
+    /**
+     * 返回响应内容
+     * @param string $data
+     * @return string
+     * @author 等风来
+     * @email 136327134@qq.com
+     * @date 2023/4/13
+     */
+    private function output($data)
+    {
+        $data = [
+            'data' => $data,
+        ];
+        return Response::create($data, 'json')->getContent();
+    }
+}