SystemCrudServices.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. <?php
  2. /**
  3. * +----------------------------------------------------------------------
  4. * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  5. * +----------------------------------------------------------------------
  6. * | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
  7. * +----------------------------------------------------------------------
  8. * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  9. * +----------------------------------------------------------------------
  10. * | Author: CRMEB Team <admin@crmeb.com>
  11. * +----------------------------------------------------------------------
  12. */
  13. namespace app\services\system;
  14. use app\dao\system\SystemCrudDao;
  15. use app\services\BaseServices;
  16. use crmeb\services\crud\Controller;
  17. use crmeb\services\crud\Dao;
  18. use crmeb\services\crud\Model;
  19. use crmeb\services\crud\Route;
  20. use crmeb\services\crud\Service;
  21. use crmeb\services\crud\Validate;
  22. use crmeb\services\crud\ViewApi;
  23. use crmeb\services\crud\ViewPages;
  24. use crmeb\services\crud\ViewRouter;
  25. use think\exception\ValidateException;
  26. use think\facade\Db;
  27. use think\migration\Migrator;
  28. use Phinx\Db\Adapter\MysqlAdapter;
  29. /**
  30. * Class SystemCrudServices
  31. * @author 等风来
  32. * @email 136327134@qq.com
  33. * @date 2023/4/6
  34. * @package app\services\system
  35. */
  36. class SystemCrudServices extends BaseServices
  37. {
  38. /**
  39. * SystemCrudServices constructor.
  40. * @param SystemCrudDao $dao
  41. */
  42. public function __construct(SystemCrudDao $dao)
  43. {
  44. $this->dao = $dao;
  45. }
  46. public function getTabelRule()
  47. {
  48. $adapter = app()->make(MysqlAdapter::class);
  49. return [
  50. 'types' => $adapter->getColumnTypes(),
  51. ];
  52. }
  53. /**
  54. * 获取表字段
  55. * @param string $tableName
  56. * @return mixed
  57. * @author 等风来
  58. * @email 136327134@qq.com
  59. * @date 2023/4/7
  60. */
  61. public function getColumnNamesList(string $tableName)
  62. {
  63. $sql = 'SELECT * FROM `information_schema`.`columns` WHERE TABLE_SCHEMA = ? AND table_name = ? ORDER BY ORDINAL_POSITION';
  64. $column = Db::query($sql, [config('database.connections.mysql.database'), $this->getTableName($tableName)]);
  65. $columns = [];
  66. foreach ($column as $item) {
  67. $column = [
  68. 'name' => $item['COLUMN_NAME'],
  69. 'type' => $item['DATA_TYPE'],
  70. 'dataType' => stripos($item['COLUMN_TYPE'], '(') !== false ? substr_replace($item['COLUMN_TYPE'], '', stripos($item['COLUMN_TYPE'], ')') + 1) : $item['COLUMN_TYPE'],
  71. 'default' => $item['COLUMN_DEFAULT'],
  72. 'null' => $item['IS_NULLABLE'] == 'YES',
  73. 'primaryKey' => $item['COLUMN_KEY'] == 'PRI',
  74. 'unsigned' => (bool)stripos($item['COLUMN_TYPE'], 'unsigned'),
  75. 'autoIncrement' => stripos($item['EXTRA'], 'auto_increment') !== false,
  76. 'comment' => $item['COLUMN_COMMENT'],
  77. ];
  78. $columns[$item['COLUMN_NAME']] = $column;
  79. }
  80. return $columns;
  81. }
  82. public function createCrud(array $data)
  83. {
  84. $tableName = $data['tableName'];
  85. $tableComment = $data['tableComment'];
  86. $tableField = $data['tableField'];
  87. $filePath = $data['filePath'];
  88. //创建数据库
  89. if ($tableField) {
  90. $this->makeDatebase($tableName, $tableComment, $tableField);
  91. }
  92. //读取表结构
  93. $column = $this->getColumnNamesList($tableName);
  94. if (!$column) {
  95. throw new ValidateException('请先创建' . $tableName . '表');
  96. }
  97. //TODO 没写完
  98. $routeName = '';
  99. $uniqueAuth = '';
  100. $make = $this->makeFile($tableName, $routeName, true, $data, $filePath);
  101. $makePath = [];
  102. foreach ($make as $key => $item) {
  103. $makePath[$key] = $item['path'];
  104. }
  105. //创建菜单
  106. if (!$data['menuName']) {
  107. $data['menuName'] = $tableName;
  108. }
  109. $data = [
  110. 'pid' => $data['pid'],
  111. 'menu_name' => $data['menuName'],
  112. 'menu_path' => '',
  113. 'auth_type' => 1,
  114. 'is_show' => 1,
  115. 'is_del' => 0,
  116. 'unique_auth' => $uniqueAuth,
  117. 'is_header' => $data['pid'] ? 0 : 1,
  118. ];
  119. $menuInfo = app()->make(SystemMenusServices::class)->save($data);
  120. //写入路由权限
  121. //TODO 没写完
  122. //记录crud生成
  123. $this->dao->save([
  124. 'pid' => $data['pid'],
  125. 'name' => $data['menuName'],
  126. 'table_name' => $tableName,
  127. 'field' => json_encode($data),
  128. 'make_path' => json_encode($makePath),
  129. 'add_time' => time()
  130. ]);
  131. }
  132. /**
  133. * 创建数据库
  134. * @param string $tableName
  135. * @param string $tableComment
  136. * @param array $tableField
  137. * @author 等风来
  138. * @email 136327134@qq.com
  139. * @date 2023/4/7
  140. */
  141. public function makeDatebase(string $tableName, string $tableComment, array $tableField = [])
  142. {
  143. $migrator = app()->make(Migrator::class);
  144. //创建表
  145. $table = $migrator->table($tableName, $tableComment);
  146. //创建字段
  147. foreach ($tableField as $item) {
  148. $option = [];
  149. if (!isset($item['limit'])) {
  150. $option['limit'] = (int)$item['limit'];
  151. }
  152. if (!isset($item['default'])) {
  153. $option['default'] = $item['default'];
  154. }
  155. $option['comment'] = $item['comment'];
  156. $table->addColumn($item['field'], $item['type'], $option);
  157. }
  158. //创建修改和增加时间
  159. if (!empty($data['tableTime'])) {
  160. $table->addTimestamps();
  161. }
  162. //创建索引
  163. if (!empty($data['tableIndex'])) {
  164. foreach ($data['tableIndex'] as $item) {
  165. $table->addIndex($item);
  166. }
  167. }
  168. //创建伪删除
  169. if (!empty($data['tableDelete'])) {
  170. $table->addSoftDelete();
  171. }
  172. //执行创建
  173. $table->create();
  174. }
  175. /**
  176. * 创建文件返回文件路径和内容
  177. * @param string $tableName
  178. * @param string $routeName
  179. * @param bool $isMake
  180. * @param array $options
  181. * @param array $filePath
  182. * @return array[]
  183. * @author 等风来
  184. * @email 136327134@qq.com
  185. * @date 2023/4/7
  186. */
  187. public function makeFile(string $tableName, string $routeName, bool $isMake = false, array $options = [], array $filePath = [])
  188. {
  189. //生成控制器
  190. $controller = app()->make(Controller::class);
  191. [$controllerContent, $controllerPath] = $controller->setFilePathName($filePath['controller'] ?? '')->isMake($isMake)->handle($tableName, '/');
  192. //生成模型
  193. $model = app()->make(Model::class);
  194. [$modelContent, $modelPath] = $model->setFilePathName($filePath['model'] ?? '')->isMake($isMake)->handle($tableName, '/');
  195. //生成dao
  196. $dao = app()->make(Dao::class);
  197. [$daoContent, $daoPath] = $dao->setFilePathName($filePath['dao'] ?? '')->isMake($isMake)->handle($tableName, '/');
  198. //生成路由
  199. $route = app()->make(Route::class);
  200. [$routeContent, $routePath] = $route->setFilePathName($filePath['route'] ?? '')->isMake($isMake)->handle($tableName, '/', [
  201. 'menus' => $options['menuName'],
  202. 'route' => $routeName
  203. ]);
  204. //生成service
  205. $service = app()->make(Service::class);
  206. [$serviceContent, $servicePath] = $service->setFilePathName($filePath['service'] ?? '')->isMake($isMake)->handle($tableName, '/', [
  207. 'field' => $options['fromField']
  208. ]);
  209. //生成验证器
  210. $validate = app()->make(Validate::class);
  211. [$validateContent, $validatePath] = $validate->setFilePathName($filePath['validate'] ?? '')->isMake($isMake)->handle($tableName, '/');
  212. //生成前台路由
  213. $viewRouter = app()->make(ViewRouter::class);
  214. [$routerContent, $routerPath] = $viewRouter->setFilePathName($filePath['router'] ?? '')->isMake($isMake)->handle($tableName, '/', [
  215. 'route' => $routeName,
  216. ]);
  217. //生成前台接口
  218. $viewApi = app()->make(ViewApi::class);
  219. [$apiContent, $apiPath] = $viewApi->setFilePathName($filePath['api'] ?? '')->isMake($isMake)->handle($tableName, '/', [
  220. 'route' => $routeName,
  221. ]);
  222. //生成前台页面
  223. $viewPages = app()->make(ViewPages::class);
  224. [$pagesContent, $pagesPath] = $viewPages->setFilePathName($filePath['pages'] ?? '')->isMake($isMake)->handle($tableName, '/', [
  225. 'field' => $options['columnField']
  226. ]);
  227. return [
  228. 'controller' => [
  229. 'path' => $controllerContent,
  230. 'content' => $controllerPath
  231. ],
  232. 'model' => [
  233. 'path' => $modelPath,
  234. 'content' => $modelContent
  235. ],
  236. 'dao' => [
  237. 'path' => $daoPath,
  238. 'content' => $daoContent
  239. ],
  240. 'route' => [
  241. 'path' => $routePath,
  242. 'content' => $routeContent
  243. ],
  244. 'service' => [
  245. 'path' => $servicePath,
  246. 'content' => $serviceContent
  247. ],
  248. 'validate' => [
  249. 'path' => $validatePath,
  250. 'content' => $validateContent
  251. ],
  252. 'router' => [
  253. 'path' => $routerPath,
  254. 'content' => $routerContent
  255. ],
  256. 'api' => [
  257. 'path' => $apiPath,
  258. 'content' => $apiContent
  259. ],
  260. 'pages' => [
  261. 'path' => $pagesPath,
  262. 'content' => $pagesContent
  263. ],
  264. ];
  265. }
  266. /**
  267. * @param string $tableName
  268. * @param bool $fullName
  269. * @return string
  270. * @author 等风来
  271. * @email 136327134@qq.com
  272. * @date 2023/4/7
  273. */
  274. public function getTableName(string $tableName, bool $fullName = true)
  275. {
  276. $tablePrefix = config('database.connections.mysql.prefix');
  277. $pattern = '/^' . $tablePrefix . '/i';
  278. return ($fullName ? $tablePrefix : '') . (preg_replace($pattern, '', $tableName));
  279. }
  280. }