|  | @@ -0,0 +1,155 @@
 | 
	
		
			
				|  |  | +<?php
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +declare(strict_types=1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +namespace app\common\utils;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// 引入框架内置类
 | 
	
		
			
				|  |  | +use think\facade\Db;
 | 
	
		
			
				|  |  | +use think\facade\Config;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * 模型 utils
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * @version      0.0.1
 | 
	
		
			
				|  |  | + * @author      by huwhois
 | 
	
		
			
				|  |  | + * @time        2022/08/10
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +class ModelUtils
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    protected $namespace;
 | 
	
		
			
				|  |  | +    protected $class;
 | 
	
		
			
				|  |  | +    protected $tableName;
 | 
	
		
			
				|  |  | +    protected $databaseName;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    protected function getPathName(string $name): string
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        $name = substr($name, 4);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return app()->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . '.php';
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    protected function getStub(): string
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'model.stub';
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 获取表的主键
 | 
	
		
			
				|  |  | +     * @return string
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    protected function getPrimarykey()
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        $sql = "SELECT COLUMN_NAME AS pk FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_NAME = '" . $this->tableName . "' AND table_schema = '.$this->databaseName.' AND CONSTRAINT_NAME = 'PRIMARY'";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $res = Db::query($sql);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $pk = empty($res) ? '' : $res[0]['pk'];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return $pk;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 获取表的所有字段信息
 | 
	
		
			
				|  |  | +     * @return array
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    protected function getColumns(string $tableName = '', string $database = '')
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        $sql = "SELECT column_name,column_comment,data_type FROM information_schema.COLUMNS WHERE TABLE_NAME = '" . $this->tableName . "' AND table_schema = '" . $this->databaseName . "'";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // echo $sql . "\n";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $res = Db::query($sql);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $columns = empty($res) ? [] : $res;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return $columns;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 构建Class文件
 | 
	
		
			
				|  |  | +     * @return string
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    protected function buildClass()
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        $stub = file_get_contents($this->getStub());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $primarykey = "";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $pk = $this->getPrimarykey();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if ($pk != "" && $pk != "id") {
 | 
	
		
			
				|  |  | +            $primarykey = 'protected $pk = "' . $pk . '";';
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $schemas = '';
 | 
	
		
			
				|  |  | +        $autoWriteTimestamp = '';
 | 
	
		
			
				|  |  | +        $create_time = false;
 | 
	
		
			
				|  |  | +        $update_time = false;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $columns = $this->getColumns();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        foreach ($columns as $column) {
 | 
	
		
			
				|  |  | +            $schemas .= "\n" . '        "' . $column['column_name'] . '" => "' . $column['data_type'] . '",  // ' . $column['column_comment'];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if ($column['column_name'] == 'create_time') {
 | 
	
		
			
				|  |  | +                $create_time = true;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if ($column['column_name'] == 'update_time') {
 | 
	
		
			
				|  |  | +                $update_time = true;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (!$create_time || !$update_time) {
 | 
	
		
			
				|  |  | +            $autoWriteTimestamp = 'protected $autoWriteTimestamp = false;';
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return str_replace(['{%namespace%}', '{%className%}', '{%primarykey%}', '{%schemas%}', '{%autoWriteTimestamp%}'], [
 | 
	
		
			
				|  |  | +            $this->namespace,
 | 
	
		
			
				|  |  | +            $this->class,
 | 
	
		
			
				|  |  | +            $primarykey,
 | 
	
		
			
				|  |  | +            $schemas,
 | 
	
		
			
				|  |  | +            $autoWriteTimestamp
 | 
	
		
			
				|  |  | +        ], $stub);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 生成 Model 文件
 | 
	
		
			
				|  |  | +     * @param  string $name 类目,包含命名空间
 | 
	
		
			
				|  |  | +     * @param string $connections 数据库配置, 默认 mysql
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public function makeModel(string $name, string $connections = 'mysql')
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        $pathname = $this->getPathName($name);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (is_file($pathname)) {
 | 
	
		
			
				|  |  | +            throw new \Exception("Model :' . $name . ' already exists!</error>", 1);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (!is_dir(dirname($pathname))) {
 | 
	
		
			
				|  |  | +            mkdir(dirname($pathname), 0755, true);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        file_put_contents($pathname, $this->codeModel($name, $connections));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 生成 Model 不生成文件
 | 
	
		
			
				|  |  | +     * @param  string $name 类目,包含命名空间
 | 
	
		
			
				|  |  | +     * @param string $connections 数据库配置, 默认 mysql
 | 
	
		
			
				|  |  | +     * @return string
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public function codeModel(string $name, string $connections = 'mysql')
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        $this->namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $this->class = str_replace($this->namespace . '\\', '', $name);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $this->tableName = Config::get('database.connections.'.$connections.'.prefix') . strtolower(preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $this->class));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $this->databaseName = Config::get('database.connections.'.$connections.'.database');
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return $this->buildClass();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 |