CRUD.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. <?php
  2. /**
  3. * User: Mike
  4. * Email: m@9026.com
  5. * Date: 2016/7/28
  6. * Time: 15:09
  7. */
  8. namespace App\Services\CRUD;
  9. use App\Models\AdminMenusModel;
  10. use App\Models\ModuleTagModel;
  11. use App\Services\Base\BaseProcess;
  12. class CRUD extends BaseProcess
  13. {
  14. private $_data;
  15. private $_date;
  16. private $_modelTpl;
  17. private $_repositoriesTpl;
  18. private $_CriteriaMultiWhereTpl;
  19. private $_controlTpl;
  20. private $_viewTpl;
  21. private $_fieldData;
  22. private $_fieldContentData;
  23. private $_fieldPrimary;
  24. public $notFillable = ['created_at','updated_at',"deleted_at"];
  25. private $_coverage = true; //强制覆盖
  26. /**
  27. * 创建CRUD
  28. * @param $data
  29. *
  30. */
  31. public function create($data) {
  32. $this->_dealData($data);
  33. \DB::beginTransaction();
  34. if(!$this->_addMenu()) {
  35. dd(1);
  36. $this->setMsg("添加菜单失败");
  37. \DB::rollback();
  38. return false;
  39. }
  40. if(!$this->_addModel()) {
  41. dd(2);
  42. $this->setMsg("添加模型失败");
  43. \DB::rollback();
  44. return false;
  45. }
  46. if(!$this->_addService()) {
  47. dd(3);
  48. $this->setMsg("添加Service失败");
  49. \DB::rollback();
  50. return false;
  51. }
  52. if(!$this->_addCriteriaMultiWhere()) {
  53. dd(4);
  54. $this->setMsg("添加Service失败");
  55. \DB::rollback();
  56. return false;
  57. }
  58. if(!$this->_addControl()) {
  59. dd(5);
  60. $this->setMsg("添加控制器失败");
  61. \DB::rollback();
  62. return false;
  63. }
  64. \DB::commit();
  65. return true;
  66. }
  67. public function _dealData($data) {
  68. $data['modelPath'] = app_path() . "/Models/" . $data['model'] . ".php";
  69. $data['modelUse'] = 'App\Models\\' . $data['model'];
  70. $data['modelName'] = $data['model'];
  71. $data['repositoriesPath'] = app_path() . "/Repositories/" . $data['repositories'] . ".php";
  72. $data['repositoriesUse'] = 'App\Repositories\\' . str_replace('/','\\',$data['repositories']);
  73. $data['CriteriaMultiWherePath'] = app_path() . "/Repositories/" . substr($data['repositories'],0,strrpos ($data['repositories'], "/")) . "/Criteria/MultiWhere" . ".php"; ;
  74. $data['CriteriaMultiWhereUse'] = substr($data['repositoriesUse'],0,strrpos ($data['repositoriesUse'], "\\")) . "\\Criteria\\MultiWhere" ;
  75. $data['repositoriesName'] = substr(strrchr( $data['repositories'], '/'), 1);
  76. $data['controlPath'] = app_path() . "/Http/Controllers/Admin/" . $data['control'] . ".php";
  77. $data['controlUse'] = 'App\Repositories\\' . str_replace('/','\\',$data['control']);
  78. $data['controlName'] = substr(strrchr( $data['control'], '/'), 1);
  79. $data['viewBaseSort'] = 'admin/'. strtolower(substr($data['control'],0,-10));
  80. $data['viewPath'] = base_path() . "/resources/views/" . $data['viewBaseSort'];
  81. $data['viewSortPath'] = str_replace('/','.',$data['viewBaseSort']);
  82. $this->_modelTpl = __DIR__ . "/tpl/model.tpl";
  83. $this->_repositoriesTpl = __DIR__ . "/tpl/repositories.tpl";
  84. $this->_CriteriaMultiWhereTpl = __DIR__ . "/tpl/creteriaMultiWhere.tpl";
  85. $this->_controlTpl = __DIR__ . "/tpl/controller.tpl";
  86. $this->_viewTpl = __DIR__ . "/tpl/view/";
  87. $this->_data = $data;
  88. $this->_date = date("Y-m-d H:i:s");
  89. $this->_fieldData = $resultRow = \DB::select("SELECT COLUMN_NAME,COLUMN_KEY,DATA_TYPE,COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA= ? AND TABLE_NAME= ? ",[env('DB_DATABASE'),$this->_data['table']]);
  90. foreach($this->_fieldData as $data) {
  91. if($data->COLUMN_KEY == "PRI") {
  92. $this->_fieldPrimary = $data->COLUMN_NAME;
  93. break;
  94. }
  95. }
  96. }
  97. /**
  98. *
  99. * 添加菜单
  100. *
  101. */
  102. public function _addMenu(){
  103. $obj = new AdminMenusModel();
  104. $addData['pid'] = $this->_data['menu_pid'];
  105. $addData['display'] = 1;
  106. $addData['name'] = $this->_data['desc'];
  107. $addData['path'] = $this->_data['path'] . "/index";
  108. $baseObj = $obj->create($addData);
  109. if(!$baseObj) {
  110. return false;
  111. }
  112. //添加
  113. $addData['display'] = 0;
  114. $addData['path'] = $this->_data['path'] . "/create";
  115. $addData['pid'] = $baseObj->id;
  116. $addData['name'] = "添加";
  117. $ok = $obj->create($addData);
  118. if(!$ok) {
  119. return false;
  120. }
  121. //修改
  122. $addData['display'] = 0;
  123. $addData['path'] = $this->_data['path'] . "/update";
  124. $addData['pid'] = $baseObj->id;
  125. $addData['name'] = "修改";
  126. $ok = $obj->create($addData);
  127. if(!$ok) {
  128. return false;
  129. }
  130. //删除
  131. $addData['display'] = 0;
  132. $addData['path'] = $this->_data['path'] . "/destroy";
  133. $addData['pid'] = $baseObj->id;
  134. $addData['name'] = "删除";
  135. $ok = $obj->create($addData);
  136. if(!$ok) {
  137. return false;
  138. }
  139. //查看
  140. $addData['display'] = 0;
  141. $addData['path'] = $this->_data['path'] . "/view";
  142. $addData['pid'] = $baseObj->id;
  143. $addData['name'] = "查看";
  144. $ok = $obj->create($addData);
  145. if(!$ok) {
  146. return false;
  147. }
  148. //check
  149. $addData['display'] = 0;
  150. $addData['path'] = $this->_data['path'] . "/check";
  151. $addData['pid'] = $baseObj->id;
  152. $addData['name'] = "选择数据";
  153. $ok = $obj->create($addData);
  154. if(!$ok) {
  155. return false;
  156. }
  157. if(dict($this->_data['table'],'status')) {
  158. //check
  159. $addData['display'] = 0;
  160. $addData['path'] = $this->_data['path'] . "/status";
  161. $addData['pid'] = $baseObj->id;
  162. $addData['name'] = "状态变更";
  163. if(!$ok) {
  164. return false;
  165. }
  166. }
  167. return true;
  168. }
  169. /**
  170. * 添加模型
  171. */
  172. public function _addModel() {
  173. $filePath = $this->_data['modelPath'];
  174. if(file_exists($filePath) && $this->_coverage===false) {
  175. return true;
  176. }
  177. $notFillable = $this->notFillable;
  178. $date = $this->_date;
  179. $tpl = file_get_contents($this->_modelTpl);
  180. $table_primary = '';
  181. $fillable = "";
  182. foreach($this->_fieldData as $data) {
  183. if($data->COLUMN_KEY == "PRI") {
  184. $table_primary = $data->COLUMN_NAME;
  185. }elseif(!in_array($data->COLUMN_NAME,$notFillable)) {
  186. $fillable .= "\r\n '{$data->COLUMN_NAME}',";
  187. }
  188. }
  189. $fillable = $fillable ? '['. substr($fillable,0,-1) ."\r\n ]": $fillable;
  190. $str = str_replace("{{table_comment}}", $this->_data['desc'], $tpl);
  191. $str = str_replace("{{table_name}}", $this->_data['table'], $str);
  192. $str = str_replace("{{table_primary}}", $table_primary, $str);
  193. $str = str_replace("{{fillable}}", $fillable, $str);
  194. $str = str_replace("{{class_name}}", $this->_data['model'], $str);
  195. $str = str_replace("{{date}}", $this->_date, $str);
  196. $ok = file_put_contents($filePath, $str);
  197. if(!$ok) {
  198. return true;
  199. }
  200. return true;
  201. }
  202. /**
  203. * 添加Service
  204. */
  205. public function _addService() {
  206. if(file_exists($this->_data['repositoriesPath']) && $this->_coverage===false) {
  207. return true;
  208. }
  209. $tpl = file_get_contents($this->_repositoriesTpl);
  210. $queryKeyord = "";
  211. foreach($this->_fieldData as $data) {
  212. $queryKeyord = " if(isset(\$this->search['{$data->COLUMN_NAME}']) && \$this->search['{$data->COLUMN_NAME}']) {
  213. \$model = \$model->where('{$data->COLUMN_NAME}',\$this->search['{$data->COLUMN_NAME}']);
  214. }\r\n";
  215. }
  216. $this->customMkdir(substr($this->_data['repositoriesPath'],0,strrpos ($this->_data['repositoriesPath'], "/")), $mode = 0777, $recursive = true);
  217. $str = str_replace("{{desc}}", $this->_data['desc'], $tpl);
  218. $str = str_replace("{{modelUse}}", $this->_data['modelUse'], $str);
  219. $str = str_replace("{{sortPath}}", str_replace('/','\\',substr($this->_data['repositories'],0,strrpos ($this->_data['repositories'], "/"))), $str);
  220. $str = str_replace("{{repositoriesName}}", $this->_data['repositoriesName'], $str);
  221. $str = str_replace("{{modelName}}", $this->_data['modelName'], $str);
  222. $str = str_replace("{{primaryKey}}", $this->_fieldPrimary, $str);
  223. $str = str_replace("{{queryKeyord}}", $queryKeyord, $str);
  224. $str = str_replace("{{date}}", $this->_date, $str);
  225. $ok = file_put_contents($this->_data['repositoriesPath'], $str);
  226. return true;
  227. }
  228. /**
  229. * 添加Service
  230. */
  231. public function _addCriteriaMultiWhere() {
  232. if(file_exists($this->_data['CriteriaMultiWherePath']) && $this->_coverage===false) {
  233. return true;
  234. }
  235. $tpl = file_get_contents($this->_CriteriaMultiWhereTpl);
  236. $queryKeyord = "";
  237. foreach($this->_fieldData as $data) {
  238. $queryKeyord = " if(isset(\$this->search['{$data->COLUMN_NAME}']) && \$this->search['{$data->COLUMN_NAME}']) {
  239. \$model = \$model->where('{$data->COLUMN_NAME}',\$this->search['{$data->COLUMN_NAME}']);
  240. }\r\n";
  241. }
  242. $this->customMkdir(substr($this->_data['CriteriaMultiWherePath'],0,strrpos ($this->_data['CriteriaMultiWherePath'], "/")), $mode = 0777, $recursive = true);
  243. $str = str_replace("{{desc}}", $this->_data['desc'], $tpl);
  244. $str = str_replace("{{sortPath}}", str_replace('/','\\',substr($this->_data['repositories'],0,strrpos ($this->_data['repositories'], "/"))), $str);
  245. $str = str_replace("{{queryKeyord}}", $queryKeyord, $str);
  246. $ok = file_put_contents($this->_data['CriteriaMultiWherePath'], $str);
  247. return true;
  248. }
  249. public function _addControl() {
  250. if(file_exists($this->_data['controlPath']) && $this->_coverage===false) {
  251. return true;
  252. }
  253. $this->customMkdir(substr($this->_data['controlPath'],0,strrpos ($this->_data['controlPath'], "/")), $mode = 0777, $recursive = true);
  254. $str = file_get_contents($this->_controlTpl);
  255. $str = str_replace("{{desc}}", $this->_data['desc'], $str);
  256. $str = str_replace("{{path}}", $this->_data['path'], $str);
  257. $str = str_replace("{{repositoriesUse}}", $this->_data['repositoriesUse'], $str);
  258. $str = str_replace("{{sortPath}}", str_replace('/','\\',substr($this->_data['control'],0,strrpos ($this->_data['control'], "/"))), $str);
  259. $str = str_replace("{{repositoriesName}}", $this->_data['repositoriesName'], $str);
  260. $str = str_replace("{{CriteriaMultiWhereUse}}", $this->_data['CriteriaMultiWhereUse'], $str);
  261. $str = str_replace("{{controlName}}", $this->_data['controlName'], $str);
  262. $str = str_replace("{{viewSortPath}}", $this->_data['viewSortPath'], $str);
  263. $str = str_replace("{{date}}", $this->_date, $str);
  264. $ok = file_put_contents($this->_data['controlPath'], $str);
  265. $this->_addView();
  266. return true;
  267. }
  268. public function _addView(){
  269. if(file_exists($this->_data['viewPath']) && $this->_coverage===false) {
  270. return true;
  271. }
  272. $this->customMkdir($this->_data['viewPath'], $mode = 0777, $recursive = true);
  273. ###index
  274. $str = file_get_contents($this->_viewTpl . "/index.blade.php");
  275. $listThStr = "";
  276. $listTdStr = "";
  277. $i = 0;
  278. foreach($this->_fieldData as $key=> $data) {
  279. if(!in_array($data->COLUMN_NAME,["deleted_at"]) && $data->DATA_TYPE !='text') {
  280. if($data->COLUMN_NAME =="id") $this->_fieldData[$key]->COLUMN_COMMENT ="ID";
  281. if($data->COLUMN_NAME =="created_at") $this->_fieldData[$key]->COLUMN_COMMENT ="创建时间";
  282. if($data->COLUMN_NAME =="updated_at") $this->_fieldData[$key]->COLUMN_COMMENT ="更新时间";
  283. $i++;
  284. if($i>7) break;
  285. $listThStr .= "\r\n <th class=\"sorting\" data-sort=\"{$data->COLUMN_NAME}\"> {$data->COLUMN_COMMENT} </th>";
  286. switch($data->DATA_TYPE) {
  287. case "tinyint":
  288. if(dict()->get($this->_data['table'],$data->COLUMN_NAME)) {
  289. $listTdStr .= "\r\n <td>{{ dict()->get('{$this->_data['table']}','{$data->COLUMN_NAME}',\$item->{$data->COLUMN_NAME}) }}</td>";
  290. }elseif(dict()->get('global',$data->COLUMN_NAME)) {
  291. $listTdStr .= "\r\n <td>{{ dict()->get('global','{$data->COLUMN_NAME}',\$item->{$data->COLUMN_NAME}) }}</td>";
  292. }else{
  293. $listTdStr .= "\r\n <td>{{ \$item->{$data->COLUMN_NAME} }}</td>";
  294. }
  295. break;
  296. default:
  297. $listTdStr .= "\r\n <td>{{ \$item->{$data->COLUMN_NAME} }}</td>";
  298. break;
  299. }
  300. }
  301. }
  302. $str = str_replace("{{desc}}", $this->_data['desc'], $str);
  303. $str = str_replace("{{path}}", $this->_data['path'], $str);
  304. $str = str_replace("{{primaryKey}}", $this->_fieldPrimary, $str);
  305. $str = str_replace("{{listThStr}}", $listThStr, $str);
  306. $str = str_replace("{{listTdStr}}", $listTdStr, $str);
  307. $ok = file_put_contents($this->_data['viewPath'] . "/index.blade.php", $str);
  308. ###check
  309. $str = file_get_contents($this->_viewTpl . "/check.blade.php");
  310. $str = str_replace("{{desc}}", $this->_data['desc'], $str);
  311. $str = str_replace("{{path}}", $this->_data['path'], $str);
  312. $str = str_replace("{{primaryKey}}", $this->_fieldPrimary, $str);
  313. $str = str_replace("{{listThStr}}", $listThStr, $str);
  314. $str = str_replace("{{listTdStr}}", $listTdStr, $str);
  315. $ok = file_put_contents($this->_data['viewPath'] . "/check.blade.php", $str);
  316. #view
  317. $str = file_get_contents($this->_viewTpl . "/view.blade.php");
  318. $str = str_replace("{{desc}}", $this->_data['desc'], $str);
  319. $str = str_replace("{{path}}", $this->_data['path'], $str);
  320. $str = str_replace("{{primaryKey}}", $this->_fieldPrimary, $str);
  321. $viewTdStr = "";
  322. foreach($this->_fieldData as $key=> $data) {
  323. if($data->COLUMN_NAME == 'id') continue;
  324. if($data->COLUMN_NAME == 'created_at') continue;
  325. if($data->COLUMN_NAME == 'updated_at') continue;
  326. if($data->COLUMN_NAME == 'deleted_at') continue;
  327. $viewTdStr .= " \r\n <div class=\"list-group-item\">
  328. \r\n <h3 class=\"list-group-item-heading\">{$data->COLUMN_COMMENT}</h3>
  329. \r\n <p class=\"list-group-item-text\">";
  330. switch($data->DATA_TYPE) {
  331. case "tinyint":
  332. if(dict()->get($this->_data['table'],$data->COLUMN_NAME)) {
  333. $viewTdStr .= "{{ dict()->get('{$this->_data['table']}','{$data->COLUMN_NAME}',\$data['{$data->COLUMN_NAME}']) }}";
  334. }elseif(dict()->get('global',$data->COLUMN_NAME)) {
  335. $viewTdStr .= "{{ dict()->get('global','{$data->COLUMN_NAME}',\$data['{$data->COLUMN_NAME}']) }}";
  336. }else{
  337. $viewTdStr .= " {{ \$data['{$data->COLUMN_NAME}'] or ''}}";
  338. }
  339. break;
  340. default:
  341. $viewTdStr .= " {{ \$data['{$data->COLUMN_NAME}'] or ''}}";
  342. break;
  343. }
  344. $viewTdStr .= "</p>
  345. \r\n </div>";
  346. }
  347. $str = str_replace("{{viewTdStr}}", $viewTdStr, $str);
  348. $ok = file_put_contents($this->_data['viewPath'] . "/view.blade.php", $str);
  349. #edit
  350. $str = file_get_contents($this->_viewTpl . "/edit.blade.php");
  351. $str = str_replace("{{desc}}", $this->_data['desc'], $str);
  352. $str = str_replace("{{path}}", $this->_data['path'], $str);
  353. $str = str_replace("{{primaryKey}}", $this->_fieldPrimary, $str);
  354. $editTdStr = "";
  355. foreach($this->_fieldData as $data) {
  356. if(!in_array($data->COLUMN_NAME,[$this->_fieldPrimary,'created_at','updated_at',"deleted_at"])) {
  357. $editTdStr .= " \r\n <div class=\"form-group\">
  358. \r\n <label class=\"control-label col-sm-3\">{$data->COLUMN_COMMENT}</label>
  359. \r\n <div class=\"col-sm-9\">";
  360. switch($data->DATA_TYPE) {
  361. case "tinyint":
  362. if(dict()->get($this->_data['table'],$data->COLUMN_NAME)) {
  363. $editTdStr .= " @foreach(dict()->get('{$this->_data['table']}','{$data->COLUMN_NAME}') as \$key=>\$val)
  364. <label class=\"radio-inline\">
  365. <input type=\"radio\" name=\"data[{$data->COLUMN_NAME}]\" value=\"\$key\" @if(isset(\$data['{$data->COLUMN_NAME}']) && \$data['{$data->COLUMN_NAME}'] == \$key)checked=\"checked\" @endif/>{{\$val}}
  366. </label>
  367. @endforeach";
  368. }elseif(dict()->get('global',$data->COLUMN_NAME)) {
  369. $editTdStr .= " @foreach(dict()->get('global','{$data->COLUMN_NAME}') as \$key=>\$val)
  370. <label class=\"radio-inline\">
  371. <input type=\"radio\" name=\"data[{$data->COLUMN_NAME}]\" value=\"\{{\$key}}\" @if(isset(\$data['{$data->COLUMN_NAME}']) && \$data['{$data->COLUMN_NAME}'] == \$key)checked=\"checked\" @endif/>{{\$val}}
  372. </label>
  373. @endforeach";
  374. }else{
  375. $editTdStr .= "\r\n <input id=\"data_{$data->COLUMN_NAME}\" name=\"data[{$data->COLUMN_NAME}]\" class=\"form-control\" value=\"{{ \$data['{$data->COLUMN_NAME}'] or ''}}\" required=\"\" aria-required=\"true\" placeholder=\"\">";
  376. }
  377. break;
  378. case "text":
  379. $editTdStr .= "\r\n {!! editor('') !!}
  380. \r\n <script id=\"container\" name=\"data[{$data->COLUMN_NAME}]\" type=\"text/plain\">{!! \$data['{$data->COLUMN_NAME}'] or '' !!}</script>
  381. ";
  382. break;
  383. case "datetime":
  384. $editTdStr .= "\r\n <input name=\"data[{$data->COLUMN_NAME}]\" class=\"form-control laydate-icon help-block m-b-none\" style=\"width:200px; height:34px;\" value=\"{{ \$data['{$data->COLUMN_NAME}'] or ''}}\" placeholder=\"{$data->COLUMN_COMMENT}\" onclick=\"laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})\" aria-invalid=\"false\">";
  385. break;
  386. default:
  387. if($data->COLUMN_NAME == 'image' || $data->COLUMN_NAME == 'pic' || $data->COLUMN_NAME == 'picture' || $data->COLUMN_NAME == 'photo' || $data->COLUMN_NAME == 'avatar'){
  388. $editTdStr .= "\r\n {!! widget('Tools.ImgUpload')->single('{$data->COLUMN_NAME}','data[{$data->COLUMN_NAME}]', isset(\$data['{$data->COLUMN_NAME}'])? \$data['{$data->COLUMN_NAME}'] : '') !!} ";
  389. }else{
  390. $editTdStr .= "\r\n <input id=\"data_{$data->COLUMN_NAME}\" name=\"data[{$data->COLUMN_NAME}]\" class=\"form-control\" value=\"{{ \$data['{$data->COLUMN_NAME}'] or ''}}\" required=\"\" aria-required=\"true\" placeholder=\"\">";
  391. }
  392. break;
  393. }
  394. $editTdStr .=" \r\n </div>
  395. \r\n </div>";
  396. }
  397. }
  398. $str = str_replace("{{editTdStr}}", $editTdStr, $str);
  399. $ok = file_put_contents($this->_data['viewPath'] . "/edit.blade.php", $str);
  400. return true;
  401. }
  402. public function customMkdir($dir)
  403. {
  404. if(!file_exists($dir)) {
  405. \File::makeDirectory($dir, $mode = 0755, $recursive = true);
  406. }
  407. }
  408. }