first commit

This commit is contained in:
Your Name
2026-01-19 14:19:22 +08:00
commit fe2d9c1868
4777 changed files with 665503 additions and 0 deletions

View File

@@ -0,0 +1,230 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\service\generator;
use app\common\service\generator\core\ControllerGenerator;
use app\common\service\generator\core\ListsGenerator;
use app\common\service\generator\core\LogicGenerator;
use app\common\service\generator\core\ModelGenerator;
use app\common\service\generator\core\SqlGenerator;
use app\common\service\generator\core\ValidateGenerator;
use app\common\service\generator\core\VueApiGenerator;
use app\common\service\generator\core\VueEditGenerator;
use app\common\service\generator\core\VueIndexGenerator;
/**
* 生成器
* Class GenerateService
* @package app\common\service\generator
*/
class GenerateService
{
// 标记
protected $flag;
// 生成文件路径
protected $generatePath;
// runtime目录
protected $runtimePath;
// 压缩包名称
protected $zipTempName;
// 压缩包临时路径
protected $zipTempPath;
public function __construct()
{
$this->generatePath = root_path() . 'runtime/generate/';
$this->runtimePath = root_path() . 'runtime/';
}
/**
* @notes 删除生成文件夹内容
* @author 段誉
* @date 2022/6/23 18:52
*/
public function delGenerateDirContent()
{
// 删除runtime目录制定文件夹
!is_dir($this->generatePath) && mkdir($this->generatePath, 0755, true);
del_target_dir($this->generatePath, false);
}
/**
* @notes 设置生成状态
* @param $name
* @param false $status
* @author 段誉
* @date 2022/6/23 18:53
*/
public function setGenerateFlag($name, $status = false)
{
$this->flag = $name;
cache($name, (int)$status, 3600);
}
/**
* @notes 获取生成状态标记
* @return mixed|object|\think\App
* @author 段誉
* @date 2022/6/23 18:53
*/
public function getGenerateFlag()
{
return cache($this->flag);
}
/**
* @notes 删除标记时间
* @author 段誉
* @date 2022/6/23 18:53
*/
public function delGenerateFlag()
{
cache($this->flag, null);
}
/**
* @notes 生成器相关类
* @return string[]
* @author 段誉
* @date 2022/6/23 17:17
*/
public function getGeneratorClass()
{
return [
ControllerGenerator::class,
ListsGenerator::class,
ModelGenerator::class,
ValidateGenerator::class,
LogicGenerator::class,
VueApiGenerator::class,
VueIndexGenerator::class,
VueEditGenerator::class,
SqlGenerator::class,
];
}
/**
* @notes 生成文件
* @param array $tableData
* @author 段誉
* @date 2022/6/23 18:52
*/
public function generate(array $tableData)
{
foreach ($this->getGeneratorClass() as $item) {
$generator = app()->make($item);
$generator->initGenerateData($tableData);
$generator->generate();
// 是否为压缩包下载
if ($generator->isGenerateTypeZip()) {
$this->setGenerateFlag($this->flag, true);
}
// 是否构建菜单
if ($item == 'app\common\service\generator\core\SqlGenerator') {
$generator->isBuildMenu() && $generator->buildMenuHandle();
}
}
}
/**
* @notes 预览文件
* @param array $tableData
* @return array
* @author 段誉
* @date 2022/6/23 18:52
*/
public function preview(array $tableData)
{
$data = [];
foreach ($this->getGeneratorClass() as $item) {
$generator = app()->make($item);
$generator->initGenerateData($tableData);
$data[] = $generator->fileInfo();
}
return $data;
}
/**
* @notes 压缩文件
* @author 段誉
* @date 2022/6/23 19:02
*/
public function zipFile()
{
$fileName = 'curd-' . date('YmdHis') . '.zip';
$this->zipTempName = $fileName;
$this->zipTempPath = $this->generatePath . $fileName;
$zip = new \ZipArchive();
$zip->open($this->zipTempPath, \ZipArchive::CREATE);
$this->addFileZip($this->runtimePath, 'generate', $zip);
$zip->close();
}
/**
* @notes 往压缩包写入文件
* @param $basePath
* @param $dirName
* @param $zip
* @author 段誉
* @date 2022/6/23 19:02
*/
public function addFileZip($basePath, $dirName, $zip)
{
$handler = opendir($basePath . $dirName);
while (($filename = readdir($handler)) !== false) {
if ($filename != '.' && $filename != '..') {
if (is_dir($basePath . $dirName . '/' . $filename)) {
// 当前路径是文件夹
$this->addFileZip($basePath, $dirName . '/' . $filename, $zip);
} else {
// 写入文件到压缩包
$zip->addFile($basePath . $dirName . '/' . $filename, $dirName . '/' . $filename);
}
}
}
closedir($handler);
}
/**
* @notes 返回压缩包临时路径
* @return mixed
* @author 段誉
* @date 2022/6/24 9:41
*/
public function getDownloadUrl()
{
$vars = ['file' => $this->zipTempName];
cache('curd_file_name' . $this->zipTempName, $this->zipTempName, 3600);
return (string)url("adminapi/tools.generator/download", $vars, false, true);
}
}

View File

@@ -0,0 +1,483 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\service\generator\core;
use think\helper\Str;
use app\common\enum\GeneratorEnum;
/**
* 生成器基类
* Class BaseGenerator
* @package app\common\service\generator\core
*/
abstract class BaseGenerator
{
/**
* 模板文件夹
* @var string
*/
protected $templateDir;
/**
* 模块名
* @var string
*/
protected $moduleName;
/**
* 类目录
* @var string
*/
protected $classDir;
/**
* 表信息
* @var array
*/
protected $tableData;
/**
* 表字段信息
* @var array
*/
protected $tableColumn;
/**
* 文件内容
* @var string
*/
protected $content;
/**
* basePath
* @var string
*/
protected $basePath;
/**
* rootPath
* @var string
*/
protected $rootPath;
/**
* 生成的文件夹
* @var string
*/
protected $generatorDir;
/**
* 删除配置
* @var array
*/
protected $deleteConfig;
/**
* 菜单配置
* @var array
*/
protected $menuConfig;
/**
* 模型关联配置
* @var array
*/
protected $relationConfig;
/**
* 树表配置
* @var array
*/
protected $treeConfig;
public function __construct()
{
$this->basePath = base_path();
$this->rootPath = root_path();
$this->templateDir = $this->basePath . 'common/service/generator/stub/';
$this->generatorDir = $this->rootPath . 'runtime/generate/';
$this->checkDir($this->generatorDir);
}
/**
* @notes 初始化表表数据
* @param array $tableData
* @author 段誉
* @date 2022/6/22 18:03
*/
public function initGenerateData(array $tableData)
{
// 设置当前表信息
$this->setTableData($tableData);
// 设置模块名
$this->setModuleName($tableData['module_name']);
// 设置类目录
$this->setClassDir($tableData['class_dir'] ?? '');
// 替换模板变量
$this->replaceVariables();
}
/**
* @notes 菜单配置
* @author 段誉
* @date 2022/12/13 15:14
*/
public function setMenuConfig()
{
$this->menuConfig = [
'pid' => $this->tableData['menu']['pid'] ?? 0,
'type' => $this->tableData['menu']['type'] ?? GeneratorEnum::DELETE_TRUE,
'name' => $this->tableData['menu']['name'] ?? $this->tableData['table_comment']
];
}
/**
* @notes 删除配置
* @return array
* @author 段誉
* @date 2022/12/13 15:09
*/
public function setDeleteConfig()
{
$this->deleteConfig = [
'type' => $this->tableData['delete']['type'] ?? GeneratorEnum::DELETE_TRUE,
'name' => $this->tableData['delete']['name'] ?? GeneratorEnum::DELETE_NAME,
];
}
/**
* @notes 关联模型配置
* @author 段誉
* @date 2022/12/14 11:28
*/
public function setRelationConfig()
{
$this->relationConfig = empty($this->tableData['relations']) ? [] : $this->tableData['relations'];
}
/**
* @notes 设置树表配置
* @author 段誉
* @date 2022/12/20 14:30
*/
public function setTreeConfig()
{
$this->treeConfig = [
'tree_id' => $this->tableData['tree']['tree_id'] ?? '',
'tree_pid' => $this->tableData['tree']['tree_pid'] ?? '',
'tree_name' => $this->tableData['tree']['tree_name'] ?? '',
];
}
/**
* @notes 生成文件到模块或runtime目录
* @author 段誉
* @date 2022/6/22 18:03
*/
public function generate()
{
//生成方式 0-压缩包下载 1-生成到模块
if ($this->tableData['generate_type']) {
// 生成路径
$path = $this->getModuleGenerateDir() . $this->getGenerateName();
} else {
// 生成到runtime目录
$path = $this->getRuntimeGenerateDir() . $this->getGenerateName();
}
// 写入内容
file_put_contents($path, $this->content);
}
/**
* @notes 获取文件生成到模块的文件夹路径
* @return mixed
* @author 段誉
* @date 2022/6/22 18:05
*/
abstract public function getModuleGenerateDir();
/**
* @notes 获取文件生成到runtime的文件夹路径
* @return mixed
* @author 段誉
* @date 2022/6/22 18:05
*/
abstract public function getRuntimeGenerateDir();
/**
* @notes 替换模板变量
* @return mixed
* @author 段誉
* @date 2022/6/22 18:06
*/
abstract public function replaceVariables();
/**
* @notes 生成文件名
* @return mixed
* @author 段誉
* @date 2022/6/22 18:17
*/
abstract public function getGenerateName();
/**
* @notes 文件夹不存在则创建
* @param string $path
* @author 段誉
* @date 2022/6/22 18:07
*/
public function checkDir(string $path)
{
!is_dir($path) && mkdir($path, 0755, true);
}
/**
* @notes 设置表信息
* @param $tableData
* @author 段誉
* @date 2022/6/22 18:07
*/
public function setTableData($tableData)
{
$this->tableData = !empty($tableData) ? $tableData : [];
$this->tableColumn = $tableData['table_column'] ?? [];
// 菜单配置
$this->setMenuConfig();
// 删除配置
$this->setDeleteConfig();
// 关联模型配置
$this->setRelationConfig();
// 设置树表配置
$this->setTreeConfig();
}
/**
* @notes 设置模块名
* @param string $moduleName
* @author 段誉
* @date 2022/6/22 18:07
*/
public function setModuleName(string $moduleName): void
{
$this->moduleName = strtolower($moduleName);
}
/**
* @notes 设置类目录
* @param string $classDir
* @author 段誉
* @date 2022/6/22 18:08
*/
public function setClassDir(string $classDir): void
{
$this->classDir = $classDir;
}
/**
* @notes 设置生成文件内容
* @param string $content
* @author 段誉
* @date 2022/6/22 18:08
*/
public function setContent(string $content): void
{
$this->content = $content;
}
/**
* @notes 获取模板路径
* @param string $templateName
* @return string
* @author 段誉
* @date 2022/6/22 18:09
*/
public function getTemplatePath(string $templateName): string
{
return $this->templateDir . $templateName . '.stub';
}
/**
* @notes 小驼峰命名
* @return string
* @author 段誉
* @date 2022/6/27 18:44
*/
public function getLowerCamelName()
{
return Str::camel($this->getTableName());
}
/**
* @notes 大驼峰命名
* @return string
* @author 段誉
* @date 2022/6/22 18:09
*/
public function getUpperCamelName()
{
return Str::studly($this->getTableName());
}
/**
* @notes 表名小写
* @return string
* @author 段誉
* @date 2022/7/12 10:41
*/
public function getLowerTableName()
{
return Str::lower($this->getTableName());
}
/**
* @notes 获取表名
* @return array|string|string[]
* @author 段誉
* @date 2022/6/22 18:09
*/
public function getTableName()
{
return get_no_prefix_table_name($this->tableData['table_name']);
}
/**
* @notes 获取表主键
* @return mixed|string
* @author 段誉
* @date 2022/6/22 18:09
*/
public function getPkContent()
{
$pk = 'id';
if (empty($this->tableColumn)) {
return $pk;
}
foreach ($this->tableColumn as $item) {
if ($item['is_pk']) {
$pk = $item['column_name'];
}
}
return $pk;
}
/**
* @notes 获取作者信息
* @return mixed|string
* @author 段誉
* @date 2022/6/24 10:18
*/
public function getAuthorContent()
{
return empty($this->tableData['author']) ? 'likeadmin' : $this->tableData['author'];
}
/**
* @notes 代码生成备注时间
* @return false|string
* @author 段誉
* @date 2022/6/24 10:28
*/
public function getNoteDateContent()
{
return date('Y/m/d H:i');
}
/**
* @notes 设置空额占位符
* @param $content
* @param $blankpace
* @return string
* @author 段誉
* @date 2022/6/22 18:09
*/
public function setBlankSpace($content, $blankpace)
{
$content = explode(PHP_EOL, $content);
foreach ($content as $line => $text) {
$content[$line] = $blankpace . $text;
}
return (implode(PHP_EOL, $content));
}
/**
* @notes 替换内容
* @param $needReplace
* @param $waitReplace
* @param $template
* @return array|false|string|string[]
* @author 段誉
* @date 2022/6/23 9:52
*/
public function replaceFileData($needReplace, $waitReplace, $template)
{
return str_replace($needReplace, $waitReplace, file_get_contents($template));
}
/**
* @notes 生成方式是否为压缩包
* @return bool
* @author 段誉
* @date 2022/6/23 17:02
*/
public function isGenerateTypeZip()
{
return $this->tableData['generate_type'] == GeneratorEnum::GENERATE_TYPE_ZIP;
}
/**
* @notes 是否为树表crud
* @return bool
* @author 段誉
* @date 2022/12/23 11:25
*/
public function isTreeCrud()
{
return $this->tableData['template_type'] == GeneratorEnum::TEMPLATE_TYPE_TREE;
}
}

View File

@@ -0,0 +1,223 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\service\generator\core;
/**
* 控制器生成器
* Class ControllerGenerator
* @package app\common\service\generator\core
*/
class ControllerGenerator extends BaseGenerator implements GenerateInterface
{
/**
* @notes 替换变量
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:09
*/
public function replaceVariables()
{
// 需要替换的变量
$needReplace = [
'{NAMESPACE}',
'{USE}',
'{CLASS_COMMENT}',
'{UPPER_CAMEL_NAME}',
'{MODULE_NAME}',
'{PACKAGE_NAME}',
'{EXTENDS_CONTROLLER}',
'{NOTES}',
'{AUTHOR}',
'{DATE}'
];
// 等待替换的内容
$waitReplace = [
$this->getNameSpaceContent(),
$this->getUseContent(),
$this->getClassCommentContent(),
$this->getUpperCamelName(),
$this->moduleName,
$this->getPackageNameContent(),
$this->getExtendsControllerContent(),
$this->tableData['class_comment'],
$this->getAuthorContent(),
$this->getNoteDateContent(),
];
$templatePath = $this->getTemplatePath('php/controller');
// 替换内容
$content = $this->replaceFileData($needReplace, $waitReplace, $templatePath);
$this->setContent($content);
}
/**
* @notes 获取命名空间内容
* @return string
* @author 段誉
* @date 2022/6/22 18:10
*/
public function getNameSpaceContent()
{
if (!empty($this->classDir)) {
return "namespace app\\" . $this->moduleName . "\\controller\\" . $this->classDir . ';';
}
return "namespace app\\" . $this->moduleName . "\\controller;";
}
/**
* @notes 获取use模板内容
* @return string
* @author 段誉
* @date 2022/6/22 18:10
*/
public function getUseContent()
{
if ($this->moduleName == 'adminapi') {
$tpl = "use app\\" . $this->moduleName . "\\controller\\BaseAdminController;" . PHP_EOL;
} else {
$tpl = "use app\\common\\controller\\BaseLikeAdminController;" . PHP_EOL;
}
if (!empty($this->classDir)) {
$tpl .= "use app\\" . $this->moduleName . "\\lists\\" . $this->classDir . "\\" . $this->getUpperCamelName() . "Lists;" . PHP_EOL .
"use app\\" . $this->moduleName . "\\logic\\" . $this->classDir . "\\" . $this->getUpperCamelName() . "Logic;" . PHP_EOL .
"use app\\" . $this->moduleName . "\\validate\\" . $this->classDir . "\\" . $this->getUpperCamelName() . "Validate;";
} else {
$tpl .= "use app\\" . $this->moduleName . "\\lists\\" . $this->getUpperCamelName() . "Lists;" . PHP_EOL .
"use app\\" . $this->moduleName . "\\logic\\" . $this->getUpperCamelName() . "Logic;" . PHP_EOL .
"use app\\" . $this->moduleName . "\\validate\\" . $this->getUpperCamelName() . "Validate;";
}
return $tpl;
}
/**
* @notes 获取类描述内容
* @return string
* @author 段誉
* @date 2022/6/22 18:10
*/
public function getClassCommentContent()
{
if (!empty($this->tableData['class_comment'])) {
$tpl = $this->tableData['class_comment'] . '控制器';
} else {
$tpl = $this->getUpperCamelName() . '控制器';
}
return $tpl;
}
/**
* @notes 获取包名
* @return string
* @author 段誉
* @date 2022/6/22 18:10
*/
public function getPackageNameContent()
{
return !empty($this->classDir) ? '\\' . $this->classDir : '';
}
/**
* @notes 获取继承控制器
* @return string
* @author 段誉
* @date 2022/6/22 18:10
*/
public function getExtendsControllerContent()
{
$tpl = 'BaseAdminController';
if ($this->moduleName != 'adminapi') {
$tpl = 'BaseLikeAdminController';
}
return $tpl;
}
/**
* @notes 获取文件生成到模块的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:10
*/
public function getModuleGenerateDir()
{
$dir = $this->basePath . $this->moduleName . '/controller/';
if (!empty($this->classDir)) {
$dir .= $this->classDir . '/';
$this->checkDir($dir);
}
return $dir;
}
/**
* @notes 获取文件生成到runtime的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:11
*/
public function getRuntimeGenerateDir()
{
$dir = $this->generatorDir . 'php/app/' . $this->moduleName . '/controller/';
$this->checkDir($dir);
if (!empty($this->classDir)) {
$dir .= $this->classDir . '/';
$this->checkDir($dir);
}
return $dir;
}
/**
* @notes 生成文件名
* @return string
* @author 段誉
* @date 2022/6/22 18:11
*/
public function getGenerateName()
{
return $this->getUpperCamelName() . 'Controller.php';
}
/**
* @notes 文件信息
* @return array
* @author 段誉
* @date 2022/6/23 15:57
*/
public function fileInfo(): array
{
return [
'name' => $this->getGenerateName(),
'type' => 'php',
'content' => $this->content
];
}
}

View File

@@ -0,0 +1,23 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\service\generator\core;
interface GenerateInterface
{
public function generate();
public function fileInfo();
}

View File

@@ -0,0 +1,338 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\service\generator\core;
use app\common\enum\GeneratorEnum;
/**
* 列表生成器
* Class ListsGenerator
* @package app\common\service\generator\core
*/
class ListsGenerator extends BaseGenerator implements GenerateInterface
{
/**
* @notes 替换变量
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:12
*/
public function replaceVariables()
{
// 需要替换的变量
$needReplace = [
'{NAMESPACE}',
'{USE}',
'{CLASS_COMMENT}',
'{UPPER_CAMEL_NAME}',
'{MODULE_NAME}',
'{PACKAGE_NAME}',
'{EXTENDS_LISTS}',
'{PK}',
'{QUERY_CONDITION}',
'{FIELD_DATA}',
'{NOTES}',
'{AUTHOR}',
'{DATE}',
];
// 等待替换的内容
$waitReplace = [
$this->getNameSpaceContent(),
$this->getUseContent(),
$this->getClassCommentContent(),
$this->getUpperCamelName(),
$this->moduleName,
$this->getPackageNameContent(),
$this->getExtendsListsContent(),
$this->getPkContent(),
$this->getQueryConditionContent(),
$this->getFieldDataContent(),
$this->tableData['class_comment'],
$this->getAuthorContent(),
$this->getNoteDateContent(),
];
$templatePath = $this->getTemplatePath('php/lists');
if ($this->isTreeCrud()) {
// 插入树表相关
array_push($needReplace, '{TREE_ID}', '{TREE_PID}');
array_push($waitReplace, $this->treeConfig['tree_id'], $this->treeConfig['tree_pid']);
$templatePath = $this->getTemplatePath('php/tree_lists');
}
// 替换内容
$content = $this->replaceFileData($needReplace, $waitReplace, $templatePath);
$this->setContent($content);
}
/**
* @notes 获取命名空间内容
* @return string
* @author 段誉
* @date 2022/6/22 18:12
*/
public function getNameSpaceContent()
{
if (!empty($this->classDir)) {
return "namespace app\\" . $this->moduleName . "\\lists\\" . $this->classDir . ';';
}
return "namespace app\\" . $this->moduleName . "\\lists;";
}
/**
* @notes 获取use内容
* @return string
* @author 段誉
* @date 2022/6/22 18:12
*/
public function getUseContent()
{
if ($this->moduleName == 'adminapi') {
$tpl = "use app\\" . $this->moduleName . "\\lists\\BaseAdminDataLists;" . PHP_EOL;
} else {
$tpl = "use app\\common\\lists\\BaseDataLists;" . PHP_EOL;
}
if (!empty($this->classDir)) {
$tpl .= "use app\\common\\model\\" . $this->classDir . "\\" . $this->getUpperCamelName() . ';';
} else {
$tpl .= "use app\\common\\model\\" . $this->getUpperCamelName() . ';';
}
return $tpl;
}
/**
* @notes 获取类描述
* @return string
* @author 段誉
* @date 2022/6/22 18:12
*/
public function getClassCommentContent()
{
if (!empty($this->tableData['class_comment'])) {
$tpl = $this->tableData['class_comment'] . '列表';
} else {
$tpl = $this->getUpperCamelName() . '列表';
}
return $tpl;
}
/**
* @notes 获取包名
* @return string
* @author 段誉
* @date 2022/6/22 18:12
*/
public function getPackageNameContent()
{
return !empty($this->classDir) ? $this->classDir : '';
}
/**
* @notes 获取继承控制器
* @return string
* @author 段誉
* @date 2022/6/22 18:12
*/
public function getExtendsListsContent()
{
$tpl = 'BaseAdminDataLists';
if ($this->moduleName != 'adminapi') {
$tpl = 'BaseDataLists';
}
return $tpl;
}
/**
* @notes 获取查询条件内容
* @return string
* @author 段誉
* @date 2022/6/22 18:12
*/
public function getQueryConditionContent()
{
$columnQuery = array_column($this->tableColumn, 'query_type');
$query = array_unique($columnQuery);
$conditon = '';
$specQueryHandle = ['between', 'like'];
foreach ($query as $queryName) {
$columnValue = '';
foreach ($this->tableColumn as $column) {
if (empty($column['query_type']) || $column['is_pk']) {
continue;
}
if ($queryName == $column['query_type'] && $column['is_query'] && !in_array($queryName, $specQueryHandle)) {
$columnValue .= "'" . $column['column_name'] . "', ";
}
}
if (!empty($columnValue)) {
$columnValue = substr($columnValue, 0, -2);
$conditon .= "'$queryName' => [" . trim($columnValue) . "]," . PHP_EOL;
}
}
$likeColumn = '';
$betweenColumn = '';
$betweenTimeColumn = '';
// 另外处理between,like 等查询条件
foreach ($this->tableColumn as $item) {
if (!$item['is_query']) {
continue;
}
// like
if ($item['query_type'] == 'like') {
$likeColumn .= "'" . $item['column_name'] . "', ";
continue;
}
// between
if ($item['query_type'] == 'between') {
if ($item['view_type'] == 'datetime') {
$betweenTimeColumn .= "'" . $item['column_name'] . "', ";
} else {
$betweenColumn .= "'" . $item['column_name'] . "', ";
}
}
}
if (!empty($likeColumn)) {
$likeColumn = substr($likeColumn, 0, -2);
$conditon .= "'%like%' => " . "[" . trim($likeColumn) . "]," . PHP_EOL;
}
if (!empty($betweenColumn)) {
$betweenColumn = substr($betweenColumn, 0, -2);
$conditon .= "'between' => " . "[" . trim($betweenColumn) . "]," . PHP_EOL;
}
if (!empty($betweenTimeColumn)) {
$betweenTimeColumn = substr($betweenTimeColumn, 0, -2);
$conditon .= "'between_time' => " . "[" . trim($betweenTimeColumn) . "]," . PHP_EOL;
}
$content = substr($conditon, 0, -1);
return $this->setBlankSpace($content, " ");
}
/**
* @notes 获取查询字段
* @return false|string
* @author 段誉
* @date 2022/6/22 18:13
*/
public function getFieldDataContent()
{
$content = "'" . $this->getPkContent() . "', ";
$isExist = [$this->getPkContent()];
foreach ($this->tableColumn as $column) {
if ($column['is_lists'] && !in_array($column['column_name'], $isExist)) {
$content .= "'" . $column['column_name'] . "', ";
$isExist[] = $column['column_name'];
}
if ($this->isTreeCrud() && !in_array($column['column_name'], $isExist)
&& in_array($column['column_name'], [$this->treeConfig['tree_id'], $this->treeConfig['tree_pid']])
) {
$content .= "'" . $column['column_name'] . "', ";
}
}
return substr($content, 0, -2);
}
/**
* @notes 获取文件生成到模块的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:13
*/
public function getModuleGenerateDir()
{
$dir = $this->basePath . $this->moduleName . '/lists/';
$this->checkDir($dir);
if (!empty($this->classDir)) {
$dir .= $this->classDir . '/';
$this->checkDir($dir);
}
return $dir;
}
/**
* @notes 获取文件生成到runtime的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:13
*/
public function getRuntimeGenerateDir()
{
$dir = $this->generatorDir . 'php/app/' . $this->moduleName . '/lists/';
$this->checkDir($dir);
if (!empty($this->classDir)) {
$dir .= $this->classDir . '/';
$this->checkDir($dir);
}
return $dir;
}
/**
* @notes 生成的文件名
* @return string
* @author 段誉
* @date 2022/6/22 18:13
*/
public function getGenerateName()
{
return $this->getUpperCamelName() . 'Lists.php';
}
/**
* @notes 文件信息
* @return array
* @author 段誉
* @date 2022/6/23 15:57
*/
public function fileInfo(): array
{
return [
'name' => $this->getGenerateName(),
'type' => 'php',
'content' => $this->content
];
}
}

View File

@@ -0,0 +1,268 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\service\generator\core;
/**
* 逻辑生成器
* Class LogicGenerator
* @package app\common\service\generator\core
*/
class LogicGenerator extends BaseGenerator implements GenerateInterface
{
/**
* @notes 替换变量
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:14
*/
public function replaceVariables()
{
// 需要替换的变量
$needReplace = [
'{NAMESPACE}',
'{USE}',
'{CLASS_COMMENT}',
'{UPPER_CAMEL_NAME}',
'{MODULE_NAME}',
'{PACKAGE_NAME}',
'{PK}',
'{CREATE_DATA}',
'{UPDATE_DATA}',
'{NOTES}',
'{AUTHOR}',
'{DATE}'
];
// 等待替换的内容
$waitReplace = [
$this->getNameSpaceContent(),
$this->getUseContent(),
$this->getClassCommentContent(),
$this->getUpperCamelName(),
$this->moduleName,
$this->getPackageNameContent(),
$this->getPkContent(),
$this->getCreateDataContent(),
$this->getUpdateDataContent(),
$this->tableData['class_comment'],
$this->getAuthorContent(),
$this->getNoteDateContent(),
];
$templatePath = $this->getTemplatePath('php/logic');
// 替换内容
$content = $this->replaceFileData($needReplace, $waitReplace, $templatePath);
$this->setContent($content);
}
/**
* @notes 添加内容
* @return string
* @author 段誉
* @date 2022/6/22 18:14
*/
public function getCreateDataContent()
{
$content = '';
foreach ($this->tableColumn as $column) {
if (!$column['is_insert']) {
continue;
}
$content .= $this->addEditColumn($column);
}
if (empty($content)) {
return $content;
}
$content = substr($content, 0, -2);
return $this->setBlankSpace($content, " ");
}
/**
* @notes 编辑内容
* @return string
* @author 段誉
* @date 2022/6/22 18:14
*/
public function getUpdateDataContent()
{
$columnContent = '';
foreach ($this->tableColumn as $column) {
if (!$column['is_update']) {
continue;
}
$columnContent .= $this->addEditColumn($column);
}
if (empty($columnContent)) {
return $columnContent;
}
$columnContent = substr($columnContent, 0, -2);
$content = $columnContent;
return $this->setBlankSpace($content, " ");
}
/**
* @notes 添加编辑字段内容
* @param $column
* @return mixed
* @author 段誉
* @date 2022/6/27 15:37
*/
public function addEditColumn($column)
{
if ($column['column_type'] == 'int' && $column['view_type'] == 'datetime') {
// 物理类型为int显示类型选择日期的情况
$content = "'" . $column['column_name'] . "' => " . 'strtotime($params[' . "'" . $column['column_name'] . "'" . ']),' . PHP_EOL;
} else {
$content = "'" . $column['column_name'] . "' => " . '$params[' . "'" . $column['column_name'] . "'" . '],' . PHP_EOL;
}
return $content;
}
/**
* @notes 获取命名空间内容
* @return string
* @author 段誉
* @date 2022/6/22 18:14
*/
public function getNameSpaceContent()
{
if (!empty($this->classDir)) {
return "namespace app\\" . $this->moduleName . "\\logic\\" . $this->classDir . ';';
}
return "namespace app\\" . $this->moduleName . "\\logic;";
}
/**
* @notes 获取use内容
* @return string
* @author 段誉
* @date 2022/6/22 18:14
*/
public function getUseContent()
{
$tpl = "use app\\common\\model\\" . $this->getUpperCamelName() . ';';
if (!empty($this->classDir)) {
$tpl = "use app\\common\\model\\" . $this->classDir . "\\" . $this->getUpperCamelName() . ';';
}
return $tpl;
}
/**
* @notes 获取类描述
* @return string
* @author 段誉
* @date 2022/6/22 18:14
*/
public function getClassCommentContent()
{
if (!empty($this->tableData['class_comment'])) {
$tpl = $this->tableData['class_comment'] . '逻辑';
} else {
$tpl = $this->getUpperCamelName() . '逻辑';
}
return $tpl;
}
/**
* @notes 获取包名
* @return string
* @author 段誉
* @date 2022/6/22 18:14
*/
public function getPackageNameContent()
{
return !empty($this->classDir) ? '\\' . $this->classDir : '';
}
/**
* @notes 获取文件生成到模块的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:15
*/
public function getModuleGenerateDir()
{
$dir = $this->basePath . $this->moduleName . '/logic/';
if (!empty($this->classDir)) {
$dir .= $this->classDir . '/';
$this->checkDir($dir);
}
return $dir;
}
/**
* @notes 获取文件生成到runtime的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:15
*/
public function getRuntimeGenerateDir()
{
$dir = $this->generatorDir . 'php/app/' . $this->moduleName . '/logic/';
$this->checkDir($dir);
if (!empty($this->classDir)) {
$dir .= $this->classDir . '/';
$this->checkDir($dir);
}
return $dir;
}
/**
* @notes 生成的文件名
* @return string
* @author 段誉
* @date 2022/6/22 18:15
*/
public function getGenerateName()
{
return $this->getUpperCamelName() . 'Logic.php';
}
/**
* @notes 文件信息
* @return array
* @author 段誉
* @date 2022/6/23 15:57
*/
public function fileInfo(): array
{
return [
'name' => $this->getGenerateName(),
'type' => 'php',
'content' => $this->content
];
}
}

View File

@@ -0,0 +1,275 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\service\generator\core;
/**
* 模型生成器
* Class ModelGenerator
* @package app\common\service\generator\core
*/
class ModelGenerator extends BaseGenerator implements GenerateInterface
{
/**
* @notes 替换变量
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:16
*/
public function replaceVariables()
{
// 需要替换的变量
$needReplace = [
'{NAMESPACE}',
'{CLASS_COMMENT}',
'{UPPER_CAMEL_NAME}',
'{PACKAGE_NAME}',
'{TABLE_NAME}',
'{USE}',
'{DELETE_USE}',
'{DELETE_TIME}',
'{RELATION_MODEL}',
];
// 等待替换的内容
$waitReplace = [
$this->getNameSpaceContent(),
$this->getClassCommentContent(),
$this->getUpperCamelName(),
$this->getPackageNameContent(),
$this->getTableName(),
$this->getUseContent(),
$this->getDeleteUseContent(),
$this->getDeleteTimeContent(),
$this->getRelationModel(),
];
$templatePath = $this->getTemplatePath('php/model');
// 替换内容
$content = $this->replaceFileData($needReplace, $waitReplace, $templatePath);
$this->setContent($content);
}
/**
* @notes 获取命名空间模板内容
* @return string
* @author 段誉
* @date 2022/6/22 18:16
*/
public function getNameSpaceContent()
{
if (!empty($this->classDir)) {
return "namespace app\\common\\model\\" . $this->classDir . ';';
}
return "namespace app\\common\\model;";
}
/**
* @notes 获取类描述
* @return string
* @author 段誉
* @date 2022/6/22 18:16
*/
public function getClassCommentContent()
{
if (!empty($this->tableData['class_comment'])) {
$tpl = $this->tableData['class_comment'] . '模型';
} else {
$tpl = $this->getUpperCamelName() . '模型';
}
return $tpl;
}
/**
* @notes 获取包名
* @return string
* @author 段誉
* @date 2022/6/22 18:16
*/
public function getPackageNameContent()
{
return !empty($this->classDir) ? '\\' . $this->classDir : '';
}
/**
* @notes 引用内容
* @return string
* @author 段誉
* @date 2022/12/12 17:32
*/
public function getUseContent()
{
$tpl = "";
if ($this->deleteConfig['type']) {
$tpl = "use think\\model\\concern\\SoftDelete;";
}
return $tpl;
}
/**
* @notes 软删除引用
* @return string
* @author 段誉
* @date 2022/12/12 17:34
*/
public function getDeleteUseContent()
{
$tpl = "";
if ($this->deleteConfig['type']) {
$tpl = "use SoftDelete;";
}
return $tpl;
}
/**
* @notes 软删除时间字段定义
* @return string
* @author 段誉
* @date 2022/12/12 17:38
*/
public function getDeleteTimeContent()
{
$tpl = "";
if ($this->deleteConfig['type']) {
$deleteTime = $this->deleteConfig['name'];
$tpl = 'protected $deleteTime = ' . "'". $deleteTime ."';";
}
return $tpl;
}
/**
* @notes 关联模型
* @return string
* @author 段誉
* @date 2022/12/14 14:46
*/
public function getRelationModel()
{
$tpl = '';
if (empty($this->relationConfig)) {
return $tpl;
}
// 遍历关联配置
foreach ($this->relationConfig as $config) {
if (empty($config) || empty($config['name']) || empty($config['model'])) {
continue;
}
$needReplace = [
'{RELATION_NAME}',
'{AUTHOR}',
'{DATE}',
'{RELATION_MODEL}',
'{FOREIGN_KEY}',
'{LOCAL_KEY}',
];
$waitReplace = [
$config['name'],
$this->getAuthorContent(),
$this->getNoteDateContent(),
$config['model'],
$config['foreign_key'],
$config['local_key'],
];
$templatePath = $this->getTemplatePath('php/model/' . $config['type']);
if (!file_exists($templatePath)) {
continue;
}
$tpl .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . PHP_EOL;
}
return $tpl;
}
/**
* @notes 获取文件生成到模块的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:16
*/
public function getModuleGenerateDir()
{
$dir = $this->basePath . 'common/model/';
if (!empty($this->classDir)) {
$dir .= $this->classDir . '/';
$this->checkDir($dir);
}
return $dir;
}
/**
* @notes 获取文件生成到runtime的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:17
*/
public function getRuntimeGenerateDir()
{
$dir = $this->generatorDir . 'php/app/common/model/';
$this->checkDir($dir);
if (!empty($this->classDir)) {
$dir .= $this->classDir . '/';
$this->checkDir($dir);
}
return $dir;
}
/**
* @notes 生成的文件名
* @return string
* @author 段誉
* @date 2022/6/22 18:17
*/
public function getGenerateName()
{
return $this->getUpperCamelName() . '.php';
}
/**
* @notes 文件信息
* @return array
* @author 段誉
* @date 2022/6/23 15:57
*/
public function fileInfo(): array
{
return [
'name' => $this->getGenerateName(),
'type' => 'php',
'content' => $this->content
];
}
}

View File

@@ -0,0 +1,191 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\service\generator\core;
use app\common\enum\GeneratorEnum;
use think\facade\Db;
use think\helper\Str;
/**
* sql文件生成器
* Class SqlGenerator
* @package app\common\service\generator\core
*/
class SqlGenerator extends BaseGenerator implements GenerateInterface
{
/**
* @notes 替换变量
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:19
*/
public function replaceVariables()
{
// 需要替换的变量
$needReplace = [
'{MENU_TABLE}',
'{PARTNER_ID}',
'{LISTS_NAME}',
'{PERMS_NAME}',
'{PATHS_NAME}',
'{COMPONENT_NAME}',
'{CREATE_TIME}',
'{UPDATE_TIME}'
];
// 等待替换的内容
$waitReplace = [
$this->getMenuTableNameContent(),
$this->menuConfig['pid'],
$this->menuConfig['name'],
$this->getPermsNameContent(),
$this->getLowerTableName(),
$this->getLowerTableName(),
time(),
time()
];
$templatePath = $this->getTemplatePath('sql/sql');
// 替换内容
$content = $this->replaceFileData($needReplace, $waitReplace, $templatePath);
$this->setContent($content);
}
/**
* @notes 路由权限内容
* @return string
* @author 段誉
* @date 2022/8/11 17:18
*/
public function getPermsNameContent()
{
if (!empty($this->classDir)) {
return $this->classDir . '.' . Str::lower($this->getTableName());
}
return Str::lower($this->getTableName());
}
/**
* @notes 获取菜单表内容
* @return string
* @author 段誉
* @date 2022/7/7 15:57
*/
public function getMenuTableNameContent()
{
$tablePrefix = config('database.connections.mysql.prefix');
return $tablePrefix . 'system_menu';
}
/**
* @notes 是否构建菜单
* @return bool
* @author 段誉
* @date 2022/7/8 14:24
*/
public function isBuildMenu()
{
return $this->menuConfig['type'] == GeneratorEnum::GEN_AUTO;
}
/**
* @notes 构建菜单
* @return bool
* @author 段誉
* @date 2022/7/8 15:27
*/
public function buildMenuHandle()
{
if (empty($this->content)) {
return false;
}
$sqls = explode(';', trim($this->content));
//执行sql
foreach ($sqls as $sql) {
if (!empty(trim($sql))) {
Db::execute($sql . ';');
}
}
return true;
}
/**
* @notes 获取文件生成到模块的文件夹路径
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:19
*/
public function getModuleGenerateDir()
{
$dir = $this->generatorDir . 'sql/';
$this->checkDir($dir);
return $dir;
}
/**
* @notes 获取文件生成到runtime的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:20
*/
public function getRuntimeGenerateDir()
{
$dir = $this->generatorDir . 'sql/';
$this->checkDir($dir);
return $dir;
}
/**
* @notes 生成的文件名
* @return string
* @author 段誉
* @date 2022/6/22 18:20
*/
public function getGenerateName()
{
return 'menu.sql';
}
/**
* @notes 文件信息
* @return array
* @author 段誉
* @date 2022/6/23 15:57
*/
public function fileInfo(): array
{
return [
'name' => $this->getGenerateName(),
'type' => 'sql',
'content' => $this->content
];
}
}

View File

@@ -0,0 +1,278 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\service\generator\core;
/**
* 验证器生成器
* Class ValidateGenerator
* @package app\common\service\generator\core
*/
class ValidateGenerator extends BaseGenerator implements GenerateInterface
{
/**
* @notes 替换变量
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:18
*/
public function replaceVariables()
{
// 需要替换的变量
$needReplace = [
'{NAMESPACE}',
'{CLASS_COMMENT}',
'{UPPER_CAMEL_NAME}',
'{MODULE_NAME}',
'{PACKAGE_NAME}',
'{PK}',
'{RULE}',
'{NOTES}',
'{AUTHOR}',
'{DATE}',
'{ADD_PARAMS}',
'{EDIT_PARAMS}',
'{FIELD}',
];
// 等待替换的内容
$waitReplace = [
$this->getNameSpaceContent(),
$this->getClassCommentContent(),
$this->getUpperCamelName(),
$this->moduleName,
$this->getPackageNameContent(),
$this->getPkContent(),
$this->getRuleContent(),
$this->tableData['class_comment'],
$this->getAuthorContent(),
$this->getNoteDateContent(),
$this->getAddParamsContent(),
$this->getEditParamsContent(),
$this->getFiledContent(),
];
$templatePath = $this->getTemplatePath('php/validate');
// 替换内容
$content = $this->replaceFileData($needReplace, $waitReplace, $templatePath);
$this->setContent($content);
}
/**
* @notes 验证规则
* @return mixed|string
* @author 段誉
* @date 2022/6/22 18:18
*/
public function getRuleContent()
{
$content = "'" . $this->getPkContent() . "' => 'require'," . PHP_EOL;
foreach ($this->tableColumn as $column) {
if ($column['is_required'] == 1) {
$content .= "'" . $column['column_name'] . "' => 'require'," . PHP_EOL;
}
}
$content = substr($content, 0, -1);
return $this->setBlankSpace($content, " ");
}
/**
* @notes 添加场景验证参数
* @return string
* @author 段誉
* @date 2022/12/7 15:26
*/
public function getAddParamsContent()
{
$content = "";
foreach ($this->tableColumn as $column) {
if ($column['is_required'] == 1 && $column['column_name'] != $this->getPkContent()) {
$content .= "'" . $column['column_name'] . "',";
}
}
$content = substr($content, 0, -1);
// 若无设置添加场景校验字段时, 排除主键
if (!empty($content)) {
$content = 'return $this->only([' . $content . ']);';
} else {
$content = 'return $this->remove(' . "'". $this->getPkContent() . "'" . ', true);';
}
return $this->setBlankSpace($content, "");
}
/**
* @notes 编辑场景验证参数
* @return string
* @author 段誉
* @date 2022/12/7 15:20
*/
public function getEditParamsContent()
{
$content = "'" . $this->getPkContent() . "'," ;
foreach ($this->tableColumn as $column) {
if ($column['is_required'] == 1) {
$content .= "'" . $column['column_name'] . "',";
}
}
$content = substr($content, 0, -1);
if (!empty($content)) {
$content = 'return $this->only([' . $content . ']);';
}
return $this->setBlankSpace($content, "");
}
/**
* @notes 验证字段描述
* @return string
* @author 段誉
* @date 2022/12/9 15:09
*/
public function getFiledContent()
{
$content = "'" . $this->getPkContent() . "' => '" . $this->getPkContent() . "'," . PHP_EOL;
foreach ($this->tableColumn as $column) {
if ($column['is_required'] == 1) {
$columnComment = $column['column_comment'];
if (empty($column['column_comment'])) {
$columnComment = $column['column_name'];
}
$content .= "'" . $column['column_name'] . "' => '" . $columnComment . "'," . PHP_EOL;
}
}
$content = substr($content, 0, -1);
return $this->setBlankSpace($content, " ");
}
/**
* @notes 获取命名空间模板内容
* @return string
* @author 段誉
* @date 2022/6/22 18:18
*/
public function getNameSpaceContent()
{
if (!empty($this->classDir)) {
return "namespace app\\" . $this->moduleName . "\\validate\\" . $this->classDir . ';';
}
return "namespace app\\" . $this->moduleName . "\\validate;";
}
/**
* @notes 获取类描述
* @return string
* @author 段誉
* @date 2022/6/22 18:18
*/
public function getClassCommentContent()
{
if (!empty($this->tableData['class_comment'])) {
$tpl = $this->tableData['class_comment'] . '验证器';
} else {
$tpl = $this->getUpperCamelName() . '验证器';
}
return $tpl;
}
/**
* @notes 获取包名
* @return string
* @author 段誉
* @date 2022/6/22 18:18
*/
public function getPackageNameContent()
{
return !empty($this->classDir) ? '\\' . $this->classDir : '';
}
/**
* @notes 获取文件生成到模块的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:18
*/
public function getModuleGenerateDir()
{
$dir = $this->basePath . $this->moduleName . '/validate/';
if (!empty($this->classDir)) {
$dir .= $this->classDir . '/';
$this->checkDir($dir);
}
return $dir;
}
/**
* @notes 获取文件生成到runtime的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:18
*/
public function getRuntimeGenerateDir()
{
$dir = $this->generatorDir . 'php/app/' . $this->moduleName . '/validate/';
$this->checkDir($dir);
if (!empty($this->classDir)) {
$dir .= $this->classDir . '/';
$this->checkDir($dir);
}
return $dir;
}
/**
* @notes 生成的文件名
* @return string
* @author 段誉
* @date 2022/6/22 18:19
*/
public function getGenerateName()
{
return $this->getUpperCamelName() . 'Validate.php';
}
/**
* @notes 文件信息
* @return array
* @author 段誉
* @date 2022/6/23 15:57
*/
public function fileInfo(): array
{
return [
'name' => $this->getGenerateName(),
'type' => 'php',
'content' => $this->content
];
}
}

View File

@@ -0,0 +1,144 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\service\generator\core;
use think\helper\Str;
/**
* vue-api生成器
* Class VueApiGenerator
* @package app\common\service\generator\core
*/
class VueApiGenerator extends BaseGenerator implements GenerateInterface
{
/**
* @notes 替换变量
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:19
*/
public function replaceVariables()
{
// 需要替换的变量
$needReplace = [
'{COMMENT}',
'{UPPER_CAMEL_NAME}',
'{ROUTE}'
];
// 等待替换的内容
$waitReplace = [
$this->getCommentContent(),
$this->getUpperCamelName(),
$this->getRouteContent(),
];
$templatePath = $this->getTemplatePath('vue/api');
// 替换内容
$content = $this->replaceFileData($needReplace, $waitReplace, $templatePath);
$this->setContent($content);
}
/**
* @notes 描述
* @return mixed
* @author 段誉
* @date 2022/6/22 18:19
*/
public function getCommentContent()
{
return $this->tableData['table_comment'];
}
/**
* @notes 路由名称
* @return array|string|string[]
* @author 段誉
* @date 2022/6/22 18:19
*/
public function getRouteContent()
{
$content = $this->getTableName();
if (!empty($this->classDir)) {
$content = $this->classDir . '.' . $this->getTableName();
}
return Str::lower($content);
}
/**
* @notes 获取文件生成到模块的文件夹路径
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:19
*/
public function getModuleGenerateDir()
{
$dir = dirname(app()->getRootPath()) . '/admin/src/api/';
$this->checkDir($dir);
return $dir;
}
/**
* @notes 获取文件生成到runtime的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:20
*/
public function getRuntimeGenerateDir()
{
$dir = $this->generatorDir . 'vue/src/api/';
$this->checkDir($dir);
return $dir;
}
/**
* @notes 生成的文件名
* @return string
* @author 段誉
* @date 2022/6/22 18:20
*/
public function getGenerateName()
{
return $this->getLowerTableName() . '.ts';
}
/**
* @notes 文件信息
* @return array
* @author 段誉
* @date 2022/6/23 15:57
*/
public function fileInfo(): array
{
return [
'name' => $this->getGenerateName(),
'type' => 'ts',
'content' => $this->content
];
}
}

View File

@@ -0,0 +1,493 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\service\generator\core;
use app\common\enum\GeneratorEnum;
/**
* vue-edit生成器
* Class VueEditGenerator
* @package app\common\service\generator\core
*/
class VueEditGenerator extends BaseGenerator implements GenerateInterface
{
/**
* @notes 替换变量
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:19
*/
public function replaceVariables()
{
// 需要替换的变量
$needReplace = [
'{FORM_VIEW}',
'{UPPER_CAMEL_NAME}',
'{DICT_DATA}',
'{DICT_DATA_API}',
'{FORM_DATA}',
'{FORM_VALIDATE}',
'{TABLE_COMMENT}',
'{PK}',
'{API_DIR}',
'{CHECKBOX_JOIN}',
'{CHECKBOX_SPLIT}',
'{FORM_DATE}',
'{SETUP_NAME}',
'{IMPORT_LISTS}',
'{TREE_CONST}',
'{GET_TREE_LISTS}'
];
// 等待替换的内容
$waitReplace = [
$this->getFormViewContent(),
$this->getUpperCamelName(),
$this->getDictDataContent(),
$this->getDictDataApiContent(),
$this->getFormDataContent(),
$this->getFormValidateContent(),
$this->tableData['table_comment'],
$this->getPkContent(),
$this->getTableName(),
$this->getCheckBoxJoinContent(),
$this->getCheckBoxSplitContent(),
$this->getFormDateContent(),
$this->getLowerCamelName(),
$this->getImportListsContent(),
$this->getTreeConstContent(),
$this->getTreeListsContent(),
];
$templatePath = $this->getTemplatePath('vue/edit');
// 替换内容
$content = $this->replaceFileData($needReplace, $waitReplace, $templatePath);
$this->setContent($content);
}
/**
* @notes 复选框处理
* @return string
* @author 段誉
* @date 2022/6/24 19:30
*/
public function getCheckBoxJoinContent()
{
$content = '';
foreach ($this->tableColumn as $column) {
if (empty($column['view_type']) || $column['is_pk']) {
continue;
}
if ($column['view_type'] != 'checkbox') {
continue;
}
$content .= $column['column_name'] . ': formData.' . $column['column_name'] . '.join(",")' . PHP_EOL;
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
return $content;
}
/**
* @notes 复选框处理
* @return string
* @author 段誉
* @date 2022/6/24 19:30
*/
public function getCheckBoxSplitContent()
{
$content = '';
foreach ($this->tableColumn as $column) {
if (empty($column['view_type']) || $column['is_pk']) {
continue;
}
if ($column['view_type'] != 'checkbox') {
continue;
}
$content .= '//@ts-ignore' . PHP_EOL;
$content .= 'data.' . $column['column_name'] . ' && ' .'(formData.' . $column['column_name'] . ' = String(data.' . $column['column_name'] . ').split(","))' . PHP_EOL;
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
/**
* @notes 树表contst
* @return string
* @author 段誉
* @date 2022/12/22 18:19
*/
public function getTreeConstContent()
{
$content = "";
if ($this->isTreeCrud()) {
$content = file_get_contents($this->getTemplatePath('vue/other_item/editTreeConst'));
}
return $content;
}
/**
* @notes 获取树表列表
* @return string
* @author 段誉
* @date 2022/12/22 18:26
*/
public function getTreeListsContent()
{
$content = '';
if (!$this->isTreeCrud()) {
return $content;
}
$needReplace = [
'{TREE_ID}',
'{TREE_NAME}',
'{UPPER_CAMEL_NAME}',
];
$waitReplace = [
$this->treeConfig['tree_id'],
$this->treeConfig['tree_name'],
$this->getUpperCamelName(),
];
$templatePath = $this->getTemplatePath('vue/other_item/editTreeLists');
if (file_exists($templatePath)) {
$content = $this->replaceFileData($needReplace, $waitReplace, $templatePath);
}
return $content;
}
/**
* @notes 表单日期处理
* @return string
* @author 段誉
* @date 2022/6/27 16:45
*/
public function getFormDateContent()
{
$content = '';
foreach ($this->tableColumn as $column) {
if (empty($column['view_type']) || $column['is_pk']) {
continue;
}
if ($column['view_type'] != 'datetime' || $column['column_type'] != 'int') {
continue;
}
$content .= '//@ts-ignore' . PHP_EOL;
$content .= 'formData.' . $column['column_name'] . ' = timeFormat(formData.' . $column['column_name'] . ','."'yyyy-mm-dd hh:MM:ss'".') ' . PHP_EOL;
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
/**
* @notes 获取表单内容
* @return string
* @author 段誉
* @date 2022/6/23 11:57
*/
public function getFormViewContent()
{
$content = '';
foreach ($this->tableColumn as $column) {
if (!$column['is_insert'] || !$column['is_update'] || $column['is_pk']) {
continue;
}
$needReplace = [
'{COLUMN_COMMENT}',
'{COLUMN_NAME}',
'{DICT_TYPE}',
];
$waitReplace = [
$column['column_comment'],
$column['column_name'],
$column['dict_type'],
];
$viewType = $column['view_type'];
// 树表,树状结构下拉框
if ($this->isTreeCrud() && $column['column_name'] == $this->treeConfig['tree_pid']) {
$viewType = 'treeSelect';
array_push($needReplace, '{TREE_ID}', '{TREE_NAME}');
array_push($waitReplace, $this->treeConfig['tree_id'], $this->treeConfig['tree_name']);
}
$templatePath = $this->getTemplatePath('vue/form_item/' . $viewType);
if (!file_exists($templatePath)) {
continue;
}
// 单选框值处理
if ($column['view_type'] == 'radio' || $column['view_type'] == 'select') {
$stubItemValue = 'item.value';
$intFieldValue = ['tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint'];
if (in_array($column['column_type'], $intFieldValue)) {
$stubItemValue = 'parseInt(item.value)';
}
array_push($needReplace, '{ITEM_VALUE}');
array_push($waitReplace, $stubItemValue);
}
$content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . PHP_EOL;
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
$content = $this->setBlankSpace($content, ' ');
return $content;
}
/**
* @notes 获取字典数据内容
* @return string
* @author 段誉
* @date 2022/6/23 11:58
*/
public function getDictDataContent()
{
$content = '';
$isExist = [];
foreach ($this->tableColumn as $column) {
if (empty($column['dict_type']) || $column['is_pk']) {
continue;
}
if (in_array($column['dict_type'], $isExist)) {
continue;
}
$content .= $column['dict_type'] . ': ' . "[]," . PHP_EOL;
$isExist[] = $column['dict_type'];
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
/**
* @notes 获取字典数据api内容
* @return false|string
* @author 段誉
* @date 2022/6/23 11:58
*/
public function getDictDataApiContent()
{
$content = '';
$isExist = [];
foreach ($this->tableColumn as $column) {
if (empty($column['dict_type']) || $column['is_pk']) {
continue;
}
if (in_array($column['dict_type'], $isExist)) {
continue;
}
$needReplace = [
'{UPPER_CAMEL_NAME}',
'{DICT_TYPE}',
];
$waitReplace = [
$this->getUpperCamelName(),
$column['dict_type'],
];
$templatePath = $this->getTemplatePath('vue/other_item/dictDataApi');
if (!file_exists($templatePath)) {
continue;
}
$content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . '' . PHP_EOL;
$isExist[] = $column['dict_type'];
}
$content = substr($content, 0, -1);
return $content;
}
/**
* @notes 获取表单默认字段内容
* @return string
* @author 段誉
* @date 2022/6/23 15:15
*/
public function getFormDataContent()
{
$content = '';
$isExist = [];
foreach ($this->tableColumn as $column) {
if (!$column['is_insert'] || !$column['is_update'] || $column['is_pk']) {
continue;
}
if (in_array($column['column_name'], $isExist)) {
continue;
}
// 复选框类型返回数组
if ($column['view_type'] == 'checkbox') {
$content .= $column['column_name'] . ': ' . "[]," . PHP_EOL;
} else {
$content .= $column['column_name'] . ': ' . "''," . PHP_EOL;
}
$isExist[] = $column['column_name'];
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
/**
* @notes 表单验证内容
* @return false|string
* @author 段誉
* @date 2022/6/23 15:16
*/
public function getFormValidateContent()
{
$content = '';
$isExist = [];
$specDictType = ['input', 'textarea', 'editor'];
foreach ($this->tableColumn as $column) {
if (!$column['is_required'] || $column['is_pk']) {
continue;
}
if (in_array($column['column_name'], $isExist)) {
continue;
}
$validateMsg = in_array($column['view_type'], $specDictType) ? '请输入' : '请选择';
$validateMsg .= $column['column_comment'];
$needReplace = [
'{COLUMN_NAME}',
'{VALIDATE_MSG}',
];
$waitReplace = [
$column['column_name'],
$validateMsg,
];
$templatePath = $this->getTemplatePath('vue/other_item/formValidate');
if (!file_exists($templatePath)) {
continue;
}
$content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . ',' . PHP_EOL;
$isExist[] = $column['column_name'];
}
$content = substr($content, 0, -2);
return $content;
}
/**
* @notes 树表时导入列表
* @author 段誉
* @date 2022/12/23 9:56
*/
public function getImportListsContent()
{
$content = "";
if ($this->isTreeCrud()) {
$content = "api". $this->getUpperCamelName(). 'Lists,';
}
if (empty($content)) {
return $content;
}
return $this->setBlankSpace($content, ' ');
}
/**
* @notes 获取文件生成到模块的文件夹路径
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:19
*/
public function getModuleGenerateDir()
{
$dir = dirname(app()->getRootPath()) . '/admin/src/views/' . $this->getTableName() . '/';
$this->checkDir($dir);
return $dir;
}
/**
* @notes 获取文件生成到runtime的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:20
*/
public function getRuntimeGenerateDir()
{
$dir = $this->generatorDir . 'vue/src/views/' . $this->getTableName() . '/';
$this->checkDir($dir);
return $dir;
}
/**
* @notes 生成的文件名
* @return string
* @author 段誉
* @date 2022/6/22 18:20
*/
public function getGenerateName()
{
return 'edit.vue';
}
/**
* @notes 文件信息
* @return array
* @author 段誉
* @date 2022/6/23 15:57
*/
public function fileInfo(): array
{
return [
'name' => $this->getGenerateName(),
'type' => 'vue',
'content' => $this->content
];
}
}

View File

@@ -0,0 +1,308 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\service\generator\core;
use app\common\enum\GeneratorEnum;
/**
* vue-index生成器
* Class VueIndexGenerator
* @package app\common\service\generator\core
*/
class VueIndexGenerator extends BaseGenerator implements GenerateInterface
{
/**
* @notes 替换变量
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:19
*/
public function replaceVariables()
{
// 需要替换的变量
$needReplace = [
'{SEARCH_VIEW}',
'{LISTS_VIEW}',
'{UPPER_CAMEL_NAME}',
'{QUERY_PARAMS}',
'{DICT_DATA}',
'{PK}',
'{API_DIR}',
'{PERMS_ADD}',
'{PERMS_EDIT}',
'{PERMS_DELETE}',
'{SETUP_NAME}'
];
// 等待替换的内容
$waitReplace = [
$this->getSearchViewContent(),
$this->getListsViewContent(),
$this->getUpperCamelName(),
$this->getQueryParamsContent(),
$this->getDictDataContent(),
$this->getPkContent(),
$this->getTableName(),
$this->getPermsContent(),
$this->getPermsContent('edit'),
$this->getPermsContent('delete'),
$this->getLowerCamelName()
];
$templatePath = $this->getTemplatePath('vue/index');
if ($this->isTreeCrud()) {
// 插入树表相关
array_push($needReplace, '{TREE_ID}', '{TREE_PID}');
array_push($waitReplace, $this->treeConfig['tree_id'], $this->treeConfig['tree_pid']);
$templatePath = $this->getTemplatePath('vue/index-tree');
}
// 替换内容
$content = $this->replaceFileData($needReplace, $waitReplace, $templatePath);
$this->setContent($content);
}
/**
* @notes 获取搜索内容
* @return string
* @author 段誉
* @date 2022/6/23 11:57
*/
public function getSearchViewContent()
{
$content = '';
foreach ($this->tableColumn as $column) {
if (!$column['is_query'] || $column['is_pk']) {
continue;
}
$needReplace = [
'{COLUMN_COMMENT}',
'{COLUMN_NAME}',
'{DICT_TYPE}',
];
$waitReplace = [
$column['column_comment'],
$column['column_name'],
$column['dict_type'],
];
$searchStubType = $column['view_type'];
if ($column['view_type'] == 'radio') {
$searchStubType = 'select';
}
$templatePath = $this->getTemplatePath('vue/search_item/' . $searchStubType);
if (!file_exists($templatePath)) {
continue;
}
$content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . PHP_EOL;
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
$content = $this->setBlankSpace($content, ' ');
return $content;
}
/**
* @notes 获取列表内容
* @return string
* @author 段誉
* @date 2022/6/23 11:57
*/
public function getListsViewContent()
{
$content = '';
foreach ($this->tableColumn as $column) {
if (!$column['is_lists']) {
continue;
}
$needReplace = [
'{COLUMN_COMMENT}',
'{COLUMN_NAME}',
'{DICT_TYPE}',
];
$waitReplace = [
$column['column_comment'],
$column['column_name'],
$column['dict_type'],
];
$templatePath = $this->getTemplatePath('vue/table_item/default');
if ($column['view_type'] == 'imageSelect') {
$templatePath = $this->getTemplatePath('vue/table_item/image');
}
if (in_array($column['view_type'], ['select', 'radio', 'checkbox'])) {
$templatePath = $this->getTemplatePath('vue/table_item/options');
}
if ($column['column_type'] == 'int' && $column['view_type'] == 'datetime') {
$templatePath = $this->getTemplatePath('vue/table_item/datetime');
}
if (!file_exists($templatePath)) {
continue;
}
$content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . PHP_EOL;
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, ' ');
}
/**
* @notes 获取查询条件内容
* @return string
* @author 段誉
* @date 2022/6/23 11:57
*/
public function getQueryParamsContent()
{
$content = '';
$queryDate = false;
foreach ($this->tableColumn as $column) {
if (!$column['is_query'] || $column['is_pk']) {
continue;
}
$content .= $column['column_name'] . ": ''," . PHP_EOL;
if ($column['query_type'] == 'between' && $column['view_type'] == 'datetime') {
$queryDate = true;
}
}
if ($queryDate) {
$content .= "start_time: ''," . PHP_EOL;
$content .= "end_time: ''," . PHP_EOL;
}
$content = substr($content, 0, -2);
return $this->setBlankSpace($content, ' ');
}
/**
* @notes 获取字典数据内容
* @return string
* @author 段誉
* @date 2022/6/23 11:58
*/
public function getDictDataContent()
{
$content = '';
$isExist = [];
foreach ($this->tableColumn as $column) {
if (empty($column['dict_type']) || $column['is_pk']) {
continue;
}
if (in_array($column['dict_type'], $isExist)) {
continue;
}
$content .= $column['dict_type'] .",";
$isExist[] = $column['dict_type'];
}
if (!empty($content)) {
$content = substr($content, 0, -1);
}
return $this->setBlankSpace($content, '');
}
/**
* @notes 权限规则
* @param string $type
* @return string
* @author 段誉
* @date 2022/7/7 9:47
*/
public function getPermsContent($type = 'add')
{
if (!empty($this->classDir)) {
$classDir = $this->classDir . '.';
} else {
$classDir = '';
}
return trim($classDir . $this->getLowerTableName() . '/' . $type);
}
/**
* @notes 获取文件生成到模块的文件夹路径
* @return mixed|void
* @author 段誉
* @date 2022/6/22 18:19
*/
public function getModuleGenerateDir()
{
$dir = dirname(app()->getRootPath()) . '/admin/src/views/' . $this->getLowerTableName() . '/';
$this->checkDir($dir);
return $dir;
}
/**
* @notes 获取文件生成到runtime的文件夹路径
* @return string
* @author 段誉
* @date 2022/6/22 18:20
*/
public function getRuntimeGenerateDir()
{
$dir = $this->generatorDir . 'vue/src/views/' . $this->getLowerTableName() . '/';
$this->checkDir($dir);
return $dir;
}
/**
* @notes 生成的文件名
* @return string
* @author 段誉
* @date 2022/6/22 18:20
*/
public function getGenerateName()
{
return 'index.vue';
}
/**
* @notes 文件信息
* @return array
* @author 段誉
* @date 2022/6/23 15:57
*/
public function fileInfo(): array
{
return [
'name' => $this->getGenerateName(),
'type' => 'vue',
'content' => $this->content
];
}
}

View File

@@ -0,0 +1,91 @@
<?php
{NAMESPACE}
{USE}
/**
* {CLASS_COMMENT}
* Class {UPPER_CAMEL_NAME}Controller
* @package app\{MODULE_NAME}\controller{PACKAGE_NAME}
*/
class {UPPER_CAMEL_NAME}Controller extends {EXTENDS_CONTROLLER}
{
/**
* @notes 获取{NOTES}列表
* @return \think\response\Json
* @author {AUTHOR}
* @date {DATE}
*/
public function lists()
{
return $this->dataLists(new {UPPER_CAMEL_NAME}Lists());
}
/**
* @notes 添加{NOTES}
* @return \think\response\Json
* @author {AUTHOR}
* @date {DATE}
*/
public function add()
{
$params = (new {UPPER_CAMEL_NAME}Validate())->post()->goCheck('add');
$result = {UPPER_CAMEL_NAME}Logic::add($params);
if (true === $result) {
return $this->success('添加成功', [], 1, 1);
}
return $this->fail({UPPER_CAMEL_NAME}Logic::getError());
}
/**
* @notes 编辑{NOTES}
* @return \think\response\Json
* @author {AUTHOR}
* @date {DATE}
*/
public function edit()
{
$params = (new {UPPER_CAMEL_NAME}Validate())->post()->goCheck('edit');
$result = {UPPER_CAMEL_NAME}Logic::edit($params);
if (true === $result) {
return $this->success('编辑成功', [], 1, 1);
}
return $this->fail({UPPER_CAMEL_NAME}Logic::getError());
}
/**
* @notes 删除{NOTES}
* @return \think\response\Json
* @author {AUTHOR}
* @date {DATE}
*/
public function delete()
{
$params = (new {UPPER_CAMEL_NAME}Validate())->post()->goCheck('delete');
{UPPER_CAMEL_NAME}Logic::delete($params);
return $this->success('删除成功', [], 1, 1);
}
/**
* @notes 获取{NOTES}详情
* @return \think\response\Json
* @author {AUTHOR}
* @date {DATE}
*/
public function detail()
{
$params = (new {UPPER_CAMEL_NAME}Validate())->goCheck('detail');
$result = {UPPER_CAMEL_NAME}Logic::detail($params);
return $this->data($result);
}
}

View File

@@ -0,0 +1,63 @@
<?php
{NAMESPACE}
{USE}
use app\common\lists\ListsSearchInterface;
/**
* {CLASS_COMMENT}
* Class {UPPER_CAMEL_NAME}Lists
* @package app\{MODULE_NAME}\lists{PACKAGE_NAME}
*/
class {UPPER_CAMEL_NAME}Lists extends {EXTENDS_LISTS} implements ListsSearchInterface
{
/**
* @notes 设置搜索条件
* @return \string[][]
* @author {AUTHOR}
* @date {DATE}
*/
public function setSearch(): array
{
return [
{QUERY_CONDITION}
];
}
/**
* @notes 获取{NOTES}列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author {AUTHOR}
* @date {DATE}
*/
public function lists(): array
{
return {UPPER_CAMEL_NAME}::where($this->searchWhere)
->field([{FIELD_DATA}])
->limit($this->limitOffset, $this->limitLength)
->order(['{PK}' => 'desc'])
->select()
->toArray();
}
/**
* @notes 获取{NOTES}数量
* @return int
* @author {AUTHOR}
* @date {DATE}
*/
public function count(): int
{
return {UPPER_CAMEL_NAME}::where($this->searchWhere)->count();
}
}

View File

@@ -0,0 +1,93 @@
<?php
{NAMESPACE}
{USE}
use app\common\logic\BaseLogic;
use think\facade\Db;
/**
* {CLASS_COMMENT}
* Class {UPPER_CAMEL_NAME}Logic
* @package app\{MODULE_NAME}\logic{PACKAGE_NAME}
*/
class {UPPER_CAMEL_NAME}Logic extends BaseLogic
{
/**
* @notes 添加{NOTES}
* @param array $params
* @return bool
* @author {AUTHOR}
* @date {DATE}
*/
public static function add(array $params): bool
{
Db::startTrans();
try {
{UPPER_CAMEL_NAME}::create([
{CREATE_DATA}
]);
Db::commit();
return true;
} catch (\Exception $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 编辑{NOTES}
* @param array $params
* @return bool
* @author {AUTHOR}
* @date {DATE}
*/
public static function edit(array $params): bool
{
Db::startTrans();
try {
{UPPER_CAMEL_NAME}::where('{PK}', $params['{PK}'])->update([
{UPDATE_DATA}
]);
Db::commit();
return true;
} catch (\Exception $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 删除{NOTES}
* @param array $params
* @return bool
* @author {AUTHOR}
* @date {DATE}
*/
public static function delete(array $params): bool
{
return {UPPER_CAMEL_NAME}::destroy($params['{PK}']);
}
/**
* @notes 获取{NOTES}详情
* @param $params
* @return array
* @author {AUTHOR}
* @date {DATE}
*/
public static function detail($params): array
{
return {UPPER_CAMEL_NAME}::findOrEmpty($params['{PK}'])->toArray();
}
}

View File

@@ -0,0 +1,21 @@
<?php
{NAMESPACE}
use app\common\model\BaseModel;
{USE}
/**
* {CLASS_COMMENT}
* Class {UPPER_CAMEL_NAME}
* @package app\common\model{PACKAGE_NAME}
*/
class {UPPER_CAMEL_NAME} extends BaseModel
{
{DELETE_USE}
protected $name = '{TABLE_NAME}';
{DELETE_TIME}
{RELATION_MODEL}
}

View File

@@ -0,0 +1,11 @@
/**
* @notes 关联{RELATION_NAME}
* @return \think\model\relation\HasMany
* @author {AUTHOR}
* @date {DATE}
*/
public function {RELATION_NAME}()
{
return $this->hasMany({RELATION_MODEL}::class, '{FOREIGN_KEY}', '{LOCAL_KEY}');
}

View File

@@ -0,0 +1,11 @@
/**
* @notes 关联{RELATION_NAME}
* @return \think\model\relation\HasOne
* @author {AUTHOR}
* @date {DATE}
*/
public function {RELATION_NAME}()
{
return $this->hasOne({RELATION_MODEL}::class, '{FOREIGN_KEY}', '{LOCAL_KEY}');
}

View File

@@ -0,0 +1,64 @@
<?php
{NAMESPACE}
{USE}
use app\common\lists\ListsSearchInterface;
/**
* {CLASS_COMMENT}
* Class {UPPER_CAMEL_NAME}Lists
* @package app\{MODULE_NAME}\lists{PACKAGE_NAME}
*/
class {UPPER_CAMEL_NAME}Lists extends {EXTENDS_LISTS} implements ListsSearchInterface
{
/**
* @notes 设置搜索条件
* @return \string[][]
* @author {AUTHOR}
* @date {DATE}
*/
public function setSearch(): array
{
return [
{QUERY_CONDITION}
];
}
/**
* @notes 获取{NOTES}列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author {AUTHOR}
* @date {DATE}
*/
public function lists(): array
{
$lists = {UPPER_CAMEL_NAME}::where($this->searchWhere)
->field([{FIELD_DATA}])
->order(['{PK}' => 'desc'])
->select()
->toArray();
return linear_to_tree($lists, 'children', '{TREE_ID}', '{TREE_PID}');
}
/**
* @notes 获取{NOTES}数量
* @return int
* @author {AUTHOR}
* @date {DATE}
*/
public function count(): int
{
return {UPPER_CAMEL_NAME}::where($this->searchWhere)->count();
}
}

View File

@@ -0,0 +1,81 @@
<?php
{NAMESPACE}
use app\common\validate\BaseValidate;
/**
* {CLASS_COMMENT}
* Class {UPPER_CAMEL_NAME}Validate
* @package app\{MODULE_NAME}\validate{PACKAGE_NAME}
*/
class {UPPER_CAMEL_NAME}Validate extends BaseValidate
{
/**
* 设置校验规则
* @var string[]
*/
protected $rule = [
{RULE}
];
/**
* 参数描述
* @var string[]
*/
protected $field = [
{FIELD}
];
/**
* @notes 添加场景
* @return {UPPER_CAMEL_NAME}Validate
* @author {AUTHOR}
* @date {DATE}
*/
public function sceneAdd()
{
{ADD_PARAMS}
}
/**
* @notes 编辑场景
* @return {UPPER_CAMEL_NAME}Validate
* @author {AUTHOR}
* @date {DATE}
*/
public function sceneEdit()
{
{EDIT_PARAMS}
}
/**
* @notes 删除场景
* @return {UPPER_CAMEL_NAME}Validate
* @author {AUTHOR}
* @date {DATE}
*/
public function sceneDelete()
{
return $this->only(['{PK}']);
}
/**
* @notes 详情场景
* @return {UPPER_CAMEL_NAME}Validate
* @author {AUTHOR}
* @date {DATE}
*/
public function sceneDetail()
{
return $this->only(['{PK}']);
}
}

View File

@@ -0,0 +1,13 @@
INSERT INTO `{MENU_TABLE}`(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
VALUES ({PARTNER_ID}, 'C', '{LISTS_NAME}', '', 1, '{PERMS_NAME}/lists', '{PATHS_NAME}', '{COMPONENT_NAME}/index', '', '', 0, 1, 0, {CREATE_TIME}, {UPDATE_TIME});
SELECT @pid := LAST_INSERT_ID();
INSERT INTO `{MENU_TABLE}`(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
VALUES (@pid, 'A', '添加', '', 1, '{PERMS_NAME}/add', '', '', '', '', 0, 1, 0, {CREATE_TIME}, {UPDATE_TIME});
INSERT INTO `{MENU_TABLE}`(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
VALUES (@pid, 'A', '编辑', '', 1, '{PERMS_NAME}/edit', '', '', '', '', 0, 1, 0, {CREATE_TIME}, {UPDATE_TIME});
INSERT INTO `{MENU_TABLE}`(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
VALUES (@pid, 'A', '删除', '', 1, '{PERMS_NAME}/delete', '', '', '', '', 0, 1, 0, {CREATE_TIME}, {UPDATE_TIME});

View File

@@ -0,0 +1,26 @@
import request from '@/utils/request'
// {COMMENT}列表
export function api{UPPER_CAMEL_NAME}Lists(params: any) {
return request.get({ url: '/{ROUTE}/lists', params })
}
// 添加{COMMENT}
export function api{UPPER_CAMEL_NAME}Add(params: any) {
return request.post({ url: '/{ROUTE}/add', params })
}
// 编辑{COMMENT}
export function api{UPPER_CAMEL_NAME}Edit(params: any) {
return request.post({ url: '/{ROUTE}/edit', params })
}
// 删除{COMMENT}
export function api{UPPER_CAMEL_NAME}Delete(params: any) {
return request.post({ url: '/{ROUTE}/delete', params })
}
// {COMMENT}详情
export function api{UPPER_CAMEL_NAME}Detail(params: any) {
return request.get({ url: '/{ROUTE}/detail', params })
}

View File

@@ -0,0 +1,103 @@
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="550px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
{FORM_VIEW}
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="{SETUP_NAME}Edit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import {{IMPORT_LISTS} api{UPPER_CAMEL_NAME}Add, api{UPPER_CAMEL_NAME}Edit, api{UPPER_CAMEL_NAME}Detail } from '@/api/{API_DIR}'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
{TREE_CONST}
// 弹窗标题
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑{TABLE_COMMENT}' : '新增{TABLE_COMMENT}'
})
// 表单数据
const formData = reactive({
{PK}: '',
{FORM_DATA}
})
// 表单验证
const formRules = reactive<any>({
{FORM_VALIDATE}
})
// 获取详情
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
{CHECKBOX_SPLIT}
{FORM_DATE}
}
const getDetail = async (row: Record<string, any>) => {
const data = await api{UPPER_CAMEL_NAME}Detail({
{PK}: row.{PK}
})
setFormData(data)
}
// 提交按钮
const handleSubmit = async () => {
await formRef.value?.validate()
const data = { ...formData, {CHECKBOX_JOIN} }
mode.value == 'edit'
? await api{UPPER_CAMEL_NAME}Edit(data)
: await api{UPPER_CAMEL_NAME}Add(data)
popupRef.value?.close()
emit('success')
}
//打开弹窗
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
// 关闭回调
const handleClose = () => {
emit('close')
}
{GET_TREE_LISTS}
defineExpose({
open,
setFormData,
getDetail
})
</script>

View File

@@ -0,0 +1,11 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<el-checkbox-group v-model="formData.{COLUMN_NAME}" placeholder="请选择{COLUMN_COMMENT}">
<el-checkbox
v-for="(item, index) in dictData.{DICT_TYPE}"
:key="index"
:label="item.value"
>
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>

View File

@@ -0,0 +1,10 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<el-date-picker
class="flex-1 !flex"
v-model="formData.{COLUMN_NAME}"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择{COLUMN_COMMENT}">
</el-date-picker>
</el-form-item>

View File

@@ -0,0 +1,6 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<daterange-picker
v-model:startTime="formData.start_{COLUMN_NAME}"
v-model:endTime="formData.end_{COLUMN_NAME}"
/>
</el-form-item>

View File

@@ -0,0 +1,3 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<editor class="flex-1" v-model="formData.{COLUMN_NAME}" :height="500" />
</el-form-item>

View File

@@ -0,0 +1,3 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<material-picker v-model="formData.{COLUMN_NAME}" />
</el-form-item>

View File

@@ -0,0 +1,3 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<el-input v-model="formData.{COLUMN_NAME}" clearable placeholder="请输入{COLUMN_COMMENT}" />
</el-form-item>

View File

@@ -0,0 +1,11 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<el-radio-group v-model="formData.{COLUMN_NAME}" placeholder="请选择{COLUMN_COMMENT}">
<el-radio
v-for="(item, index) in dictData.{DICT_TYPE}"
:key="index"
:label="{ITEM_VALUE}"
>
{{ item.name }}
</el-radio>
</el-radio-group>
</el-form-item>

View File

@@ -0,0 +1,10 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<el-select class="flex-1" v-model="formData.{COLUMN_NAME}" clearable placeholder="请选择{COLUMN_COMMENT}">
<el-option
v-for="(item, index) in dictData.{DICT_TYPE}"
:key="index"
:label="item.name"
:value="{ITEM_VALUE}"
/>
</el-select>
</el-form-item>

View File

@@ -0,0 +1,3 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<el-input class="flex-1" v-model="formData.{COLUMN_NAME}" type="textarea" rows="4" clearable placeholder="请输入{COLUMN_COMMENT}" />
</el-form-item>

View File

@@ -0,0 +1,13 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<el-tree-select
class="flex-1"
v-model="formData.{COLUMN_NAME}"
:data="treeList"
clearable
node-key="{TREE_ID}"
:props="{ label: '{TREE_NAME}', value: '{TREE_ID}', children: 'children' }"
:default-expand-all="true"
placeholder="请选择{COLUMN_COMMENT}"
check-strictly
/>
</el-form-item>

View File

@@ -0,0 +1,167 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form
ref="formRef"
class="mb-[-16px]"
:model="queryParams"
inline
>
{SEARCH_VIEW}
<el-form-item>
<el-button type="primary" @click="getLists">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none" shadow="never">
<div>
<el-button v-perms="['{PERMS_ADD}']" type="primary" @click="handleAdd()">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
<el-button @click="handleExpand"> 展开/折叠 </el-button>
</div>
<div class="mt-4">
<el-table
v-loading="loading"
ref="tableRef"
class="mt-4"
size="large"
:data="lists"
row-key="{TREE_ID}"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
{LISTS_VIEW}
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button
v-perms="['{PERMS_ADD}']"
type="primary"
link
@click="handleAdd(row.{TREE_ID})"
>
新增
</el-button>
<el-button
v-perms="['{PERMS_EDIT}']"
type="primary"
link
@click="handleEdit(row)"
>
编辑
</el-button>
<el-button
v-perms="['{PERMS_DELETE}']"
type="danger"
link
@click="handleDelete(row.{PK})"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup name="{SETUP_NAME}Lists">
import { timeFormat } from '@/utils/util'
import { useDictData } from '@/hooks/useDictOptions'
import { api{UPPER_CAMEL_NAME}Lists, api{UPPER_CAMEL_NAME}Delete } from '@/api/{API_DIR}'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import type { ElTable, FormInstance } from 'element-plus'
const tableRef = shallowRef<InstanceType<typeof ElTable>>()
const formRef = shallowRef<FormInstance>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
let isExpand = false
// 是否显示编辑框
const showEdit = ref(false)
const loading = ref(false)
const lists = ref<any[]>([])
// 查询条件
const queryParams = reactive({
{QUERY_PARAMS}
})
const resetParams = () => {
formRef.value?.resetFields()
getLists()
}
const getLists = async () => {
loading.value = true
try {
const data = await api{UPPER_CAMEL_NAME}Lists(queryParams)
lists.value = data.lists
loading.value = false
} catch (error) {
loading.value = false
}
}
// 选中数据
const selectData = ref<any[]>([])
// 表格选择后回调事件
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ {PK} }) => {PK})
}
// 获取字典数据
const { dictData } = useDictData('{DICT_DATA}')
// 添加
const handleAdd = async ({TREE_ID}?: number) => {
showEdit.value = true
await nextTick()
if ({TREE_ID}) {
editRef.value?.setFormData({
{TREE_PID}: {TREE_ID}
})
}
editRef.value?.open('add')
}
// 编辑
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
}
// 删除
const handleDelete = async ({PK}: number | any[]) => {
await feedback.confirm('确定要删除?')
await api{UPPER_CAMEL_NAME}Delete({ {PK} })
getLists()
}
const handleExpand = () => {
isExpand = !isExpand
toggleExpand(lists.value, isExpand)
}
const toggleExpand = (children: any[], unfold = true) => {
for (const key in children) {
tableRef.value?.toggleRowExpansion(children[key], unfold)
if (children[key].children) {
toggleExpand(children[key].children!, unfold)
}
}
}
getLists()
</script>

View File

@@ -0,0 +1,123 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form
class="mb-[-16px]"
:model="queryParams"
inline
>
{SEARCH_VIEW}
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<el-button v-perms="['{PERMS_ADD}']" type="primary" @click="handleAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
<el-button
v-perms="['{PERMS_DELETE}']"
:disabled="!selectData.length"
@click="handleDelete(selectData)"
>
删除
</el-button>
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
{LISTS_VIEW}
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button
v-perms="['{PERMS_EDIT}']"
type="primary"
link
@click="handleEdit(row)"
>
编辑
</el-button>
<el-button
v-perms="['{PERMS_DELETE}']"
type="danger"
link
@click="handleDelete(row.{PK})"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup name="{SETUP_NAME}Lists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { api{UPPER_CAMEL_NAME}Lists, api{UPPER_CAMEL_NAME}Delete } from '@/api/{API_DIR}'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
// 是否显示编辑框
const showEdit = ref(false)
// 查询条件
const queryParams = reactive({
{QUERY_PARAMS}
})
// 选中数据
const selectData = ref<any[]>([])
// 表格选择后回调事件
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ {PK} }) => {PK})
}
// 获取字典数据
const { dictData } = useDictData('{DICT_DATA}')
// 分页相关
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: api{UPPER_CAMEL_NAME}Lists,
params: queryParams
})
// 添加
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
// 编辑
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
}
// 删除
const handleDelete = async ({PK}: number | any[]) => {
await feedback.confirm('确定要删除?')
await api{UPPER_CAMEL_NAME}Delete({ {PK} })
getLists()
}
getLists()
</script>

View File

@@ -0,0 +1,6 @@
dictDataLists({
type_value: '{DICT_TYPE}',
page_type: 0
}).then((res: any) => {
dictData.{DICT_TYPE} = res.lists
})

View File

@@ -0,0 +1 @@
const treeList = ref<any[]>([])

View File

@@ -0,0 +1,8 @@
const getLists = async () => {
const data: any = await api{UPPER_CAMEL_NAME}Lists()
const item = { {TREE_ID}: 0, {TREE_NAME}: '顶级', children: [] }
item.children = data.lists
treeList.value.push(item)
}
getLists()

View File

@@ -0,0 +1,5 @@
{COLUMN_NAME}: [{
required: true,
message: '{VALIDATE_MSG}',
trigger: ['blur']
}]

View File

@@ -0,0 +1,6 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<daterange-picker
v-model:startTime="queryParams.start_time"
v-model:endTime="queryParams.end_time"
/>
</el-form-item>

View File

@@ -0,0 +1,3 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<el-input class="w-[280px]" v-model="queryParams.{COLUMN_NAME}" clearable placeholder="请输入{COLUMN_COMMENT}" />
</el-form-item>

View File

@@ -0,0 +1,11 @@
<el-form-item label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<el-select class="w-[280px]" v-model="queryParams.{COLUMN_NAME}" clearable placeholder="请选择{COLUMN_COMMENT}">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in dictData.{DICT_TYPE}"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>

View File

@@ -0,0 +1,5 @@
<el-table-column label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<template #default="{ row }">
<span>{{ row.{COLUMN_NAME} ? timeFormat(row.{COLUMN_NAME}, 'yyyy-mm-dd hh:MM:ss') : '' }}</span>
</template>
</el-table-column>

View File

@@ -0,0 +1 @@
<el-table-column label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}" show-overflow-tooltip />

View File

@@ -0,0 +1,5 @@
<el-table-column label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<template #default="{ row }">
<el-image style="width:50px;height:50px;" :src="row.{COLUMN_NAME}" />
</template>
</el-table-column>

View File

@@ -0,0 +1,5 @@
<el-table-column label="{COLUMN_COMMENT}" prop="{COLUMN_NAME}">
<template #default="{ row }">
<dict-value :options="dictData.{DICT_TYPE}" :value="row.{COLUMN_NAME}" />
</template>
</el-table-column>