Field.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. <?php
  2. namespace app\admin\controller\famysql;
  3. use app\common\controller\Backend;
  4. use think\Db;
  5. use think\Config;
  6. /**
  7. * 字段管理
  8. */
  9. class Field extends Backend
  10. {
  11. protected $dbName = '';
  12. protected $noNeedRight = ['selectfields', 'getType', 'getSuffix'];
  13. public function _initialize()
  14. {
  15. parent::_initialize();
  16. if (!config("app_debug")) {
  17. $this->error("数据库管理插件只允许在开发环境下使用");
  18. }
  19. if (!$this->auth->isSuperAdmin()) {
  20. $this->error(__('Access is allowed only to the super management group'));
  21. }
  22. $this->dbName = Config::get("database.database");
  23. $this->view->assign("suffixList", $this->getSuffixList());
  24. }
  25. /**
  26. * 字段首页
  27. */
  28. public function fields()
  29. {
  30. $name = $this->request->get('name');
  31. $is_admin = (int) $this->request->get('is_admin');
  32. $offset = $this->request->get("offset");
  33. $limit = $this->request->get("limit");
  34. if ($name == NULL) {
  35. $this->error(__('Parameter %s can not be empty', 'name'));
  36. }
  37. $ints = ["int", "tinyint", "smallint", "mediumint", "bigint", "float", "double", "decimal"];
  38. if ($this->request->isAjax()) {
  39. $tableFields = Db::table("information_schema.COLUMNS")->field("*")->where(['TABLE_SCHEMA' => $this->dbName, 'TABLE_NAME' => $name])->select();
  40. $list = [];
  41. foreach ($tableFields as $key => $tableField) {
  42. $list[$key]['id'] = $tableField['ORDINAL_POSITION'];
  43. $list[$key]['name'] = $tableField['COLUMN_NAME'];
  44. $list[$key]['type'] = $tableField['DATA_TYPE'];
  45. $list[$key]['length'] = $tableField['COLUMN_TYPE'];
  46. $list[$key]['default'] = $tableField['COLUMN_DEFAULT'];
  47. $list[$key]['primary_key'] = $tableField['COLUMN_KEY'] == 'PRI' ? 1 : 0;
  48. $list[$key]['index'] = $tableField['COLUMN_KEY'] == 'MUL' ? 1 : 0;
  49. $list[$key]['is_null'] = $tableField['IS_NULLABLE'] == 'YES' ? '否' : '是';
  50. $list[$key]['unsigned'] = strpos($tableField['COLUMN_TYPE'], 'unsigned') !== false ? '是' : (in_array($tableField['DATA_TYPE'], $ints) ? '否' : '-');
  51. $list[$key]['auto_increment'] = strpos($tableField['EXTRA'], 'auto_increment') !== false ? 1 : 0;
  52. $list[$key]['comment'] = $tableField['COLUMN_COMMENT'];
  53. $list[$key]['is_admin'] = $is_admin;
  54. }
  55. $result = array("total" => count($list), "rows" => array_slice($list, $offset, $limit));
  56. return json($result);
  57. }
  58. $this->view->assign("name", $name);
  59. $this->view->assign("is_admin", $is_admin);
  60. return $this->view->fetch();
  61. }
  62. /**
  63. * 快速建表
  64. */
  65. public function create()
  66. {
  67. $name = $this->request->get('name');
  68. $is_admin = (int) $this->request->get('is_admin');
  69. if ($name == NULL) {
  70. $this->error(__('Parameter %s can not be empty', 'name'));
  71. }
  72. if ($this->request->isPost()) {
  73. $params = $this->request->post("row/a");
  74. if ($params) {
  75. $result = false;
  76. $sql = "ALTER TABLE `{$name}`";
  77. $column_name = explode(',', $params['column_name']);
  78. foreach ($column_name as $column) {
  79. $sql .= $this->getCommonFields($column);
  80. }
  81. $sql = rtrim($sql, ',');
  82. Db::startTrans();
  83. try {
  84. $result = Db::execute($sql);
  85. if (Db::getPdo()->inTransaction() == true) {
  86. Db::commit();
  87. }
  88. } catch (\think\exception\PDOException $e) {
  89. Db::rollback();
  90. $this->error($e->getMessage());
  91. } catch (\think\Exception $e) {
  92. Db::rollback();
  93. $this->error($e->getMessage());
  94. }
  95. if ($result !== false) {
  96. $this->success();
  97. } else {
  98. $this->error(__('No rows were inserted'));
  99. }
  100. }
  101. $this->error(__('Parameter %s can not be empty', ''));
  102. }
  103. $this->view->assign("name", $name);
  104. $this->view->assign("is_admin", $is_admin);
  105. return $this->view->fetch();
  106. }
  107. /**
  108. * 添加字段
  109. */
  110. public function field_add()
  111. {
  112. if ($this->request->isPost()) {
  113. $name = $this->request->param('name');
  114. $params = $this->request->post("row/a");
  115. $column_name = $params['suffix'] == '无' ? $params['name'] : $params['name'] . $params['suffix'];
  116. if ($params) {
  117. $result = false;
  118. $sql = "ALTER TABLE `{$name}` ADD COLUMN `{$column_name}` ";
  119. Db::startTrans();
  120. try {
  121. if (in_array($params['type'], ['enum', 'set'])) {
  122. $length_arr = json_decode($params['length'], true);
  123. $default_arr = [];
  124. foreach ($length_arr as $value) {
  125. $default_arr[] = $value['vo'];
  126. }
  127. $params['length'] = $default_arr;
  128. }
  129. $sql .= $this->getFieldSql($column_name, $params);
  130. $result = Db::execute($sql);
  131. if (Db::getPdo()->inTransaction() == true) {
  132. Db::commit();
  133. }
  134. } catch (\think\exception\PDOException $e) {
  135. Db::rollback();
  136. $this->error($e->getMessage());
  137. } catch (\think\Exception $e) {
  138. Db::rollback();
  139. $this->error($e->getMessage());
  140. }
  141. if ($result !== false) {
  142. $this->success();
  143. } else {
  144. $this->error(__('No rows were updated'));
  145. }
  146. }
  147. }
  148. return $this->view->fetch();
  149. }
  150. /**
  151. * 修改字段
  152. */
  153. public function field_edit()
  154. {
  155. $table = $this->request->param("table");
  156. if ($table == NULL) {
  157. $this->error(__('Parameter %s can not be empty', 'table'));
  158. }
  159. $field = $this->request->param("field");
  160. if ($field == NULL) {
  161. $this->error(__('Parameter %s can not be empty', 'field'));
  162. }
  163. $properties = Db::query("SHOW FULL COLUMNS FROM `{$table}` WHERE Field = '{$field}'");
  164. $type_arr = explode(" ", $properties[0]["Type"]);
  165. $type = strstr($type_arr[0], "(", true) !== false ? strstr($type_arr[0], "(", true) : $type_arr[0];
  166. $length = preg_match('/\((.*?)\)/', $type_arr[0], $matches) ? $matches[1] : 0;
  167. $row['name'] = $properties[0]["Field"];
  168. $row['type'] = $type;
  169. $row['collate'] = $properties[0]["Collation"];
  170. if (in_array($type, ["enum", "set"])) {
  171. $length_arr = explode(",", $length);
  172. $length_res = [];
  173. foreach ($length_arr as $key => $value) {
  174. preg_match("/\'(.*?)\'/", $value, $matches);
  175. $length_res[$key]['vo'] = $matches[1];
  176. }
  177. $length = json_encode($length_res);
  178. }
  179. $row['length'] = $length;
  180. $row['default'] = $properties[0]["Default"];
  181. $row['is_null'] = $properties[0]["Null"];
  182. $row['unsigned'] = in_array("unsigned", $type_arr) ? 1 : 0;
  183. $row['zerofill'] = in_array("zerofill", $type_arr) ? 1 : 0;
  184. $row['comment'] = $properties[0]["Comment"];
  185. if ($this->request->isPost()) {
  186. $params = $this->request->post("row/a");
  187. if ($params) {
  188. $result = false;
  189. $sql = "ALTER TABLE `{$table}` MODIFY COLUMN `{$field}` ";
  190. Db::startTrans();
  191. try {
  192. if ($params['name'] !== $row['name']) {
  193. $sql = "ALTER TABLE `{$table}` CHANGE `{$row['name']}` `{$params['name']}`";
  194. }
  195. if (in_array($params['type'], ['enum', 'set'])) {
  196. $length_arr = json_decode($params['length'], true);
  197. $default_arr = [];
  198. foreach ($length_arr as $value) {
  199. $default_arr[] = $value['vo'];
  200. }
  201. $params['length'] = $default_arr;
  202. }
  203. $sql .= $this->getFieldSql($params['name'], $params);
  204. // halt($sql);
  205. $result = Db::execute($sql);
  206. if (Db::getPdo()->inTransaction() == true) {
  207. Db::commit();
  208. }
  209. } catch (\think\exception\PDOException $e) {
  210. Db::rollback();
  211. $this->error($e->getMessage());
  212. } catch (\think\Exception $e) {
  213. Db::rollback();
  214. $this->error($e->getMessage());
  215. }
  216. if ($result !== false) {
  217. $this->success();
  218. } else {
  219. $this->error(__('No rows were updated'));
  220. }
  221. }
  222. $this->error(__('Parameter %s can not be empty', ''));
  223. }
  224. $ints = ["int", "tinyint", "smallint", "mediumint", "bigint", "float", "double", "decimal"];
  225. $no_length = ['date', 'datetime', 'time', 'year', "mediumtext", "longtext", "text"];
  226. $this->view->assign("row", $row);
  227. $this->view->assign("is_int", in_array($row['type'], $ints));
  228. $this->view->assign("is_enum", in_array($row['type'], ['enum', 'set']));
  229. $this->view->assign("is_length", in_array($row['type'], $no_length));
  230. return $this->view->fetch();
  231. }
  232. /**
  233. * 删除
  234. */
  235. public function field_del()
  236. {
  237. $table = $this->request->param("table");
  238. if ($table == NULL) {
  239. $this->error(__('Parameter %s can not be empty', 'table'));
  240. }
  241. $field = $this->request->param("field");
  242. if ($field == NULL) {
  243. $this->error(__('Parameter %s can not be empty', 'field'));
  244. }
  245. $result = false;
  246. Db::startTrans();
  247. try {
  248. $sql = "ALTER TABLE `{$table}` DROP COLUMN `{$field}`;";
  249. $result = Db::execute($sql);
  250. if (Db::getPdo()->inTransaction() == true) {
  251. Db::commit();
  252. }
  253. } catch (\think\exception\PDOException $e) {
  254. Db::rollback();
  255. $this->error($e->getMessage());
  256. } catch (\think\Exception $e) {
  257. Db::rollback();
  258. $this->error($e->getMessage());
  259. }
  260. if ($result !== false) {
  261. $this->success();
  262. } else {
  263. $this->error(__('No rows were deleted'));
  264. }
  265. }
  266. /**
  267. * 字段排序
  268. */
  269. public function field_drag()
  270. {
  271. $name = $this->request->get('name');
  272. if ($name == NULL) {
  273. $this->error(__('Parameter %s can not be empty', 'name'));
  274. }
  275. $fields = Db::getTableFields($name);
  276. //排序的数组
  277. $ids = $this->request->post("ids");
  278. //拖动的记录ID
  279. $changeid = (int) $this->request->post("changeid");
  280. $ids = explode(',', $ids);
  281. $position = array_search($changeid, $ids);
  282. switch ($position) {
  283. case 0:
  284. if ($ids[array_search($changeid, $ids) + 1] > 1) {
  285. $changeField = $fields[$changeid - 1];
  286. $afterField = $fields[$ids[1] - 2];
  287. $properties = $this->getProperties($name, $changeField);
  288. $sql = "ALTER TABLE `{$name}` MODIFY COLUMN `{$changeField}` {$properties} AFTER `{$afterField}`";
  289. } else {
  290. $afterField = $fields[$changeid - 1];
  291. $properties = $this->getProperties($name, $afterField);
  292. $sql = "ALTER TABLE `{$name}` MODIFY COLUMN `{$afterField}` {$properties} FIRST";
  293. }
  294. break;
  295. default:
  296. $changeField = $fields[$changeid - 1];
  297. $afterField = $fields[($ids[array_search($changeid, $ids) - 1] - 1)];
  298. $properties = $this->getProperties($name, $changeField);
  299. $sql = "ALTER TABLE `{$name}` MODIFY COLUMN `{$changeField}` {$properties} AFTER `{$afterField}`";
  300. }
  301. $result = false;
  302. Db::startTrans();
  303. try {
  304. $result = Db::execute($sql);
  305. if (Db::getPdo()->inTransaction() == true) {
  306. Db::commit();
  307. }
  308. } catch (\think\exception\PDOException $e) {
  309. Db::rollback();
  310. $this->error($e->getMessage());
  311. } catch (\think\Exception $e) {
  312. Db::rollback();
  313. $this->error($e->getMessage());
  314. }
  315. if ($result !== false) {
  316. $this->success();
  317. } else {
  318. $this->error(__('No rows were updated'));
  319. }
  320. }
  321. /**
  322. * 查看
  323. * @internal
  324. */
  325. public function index()
  326. {
  327. $this->error('禁止访问');
  328. }
  329. /**
  330. * 添加
  331. * @internal
  332. */
  333. public function add()
  334. {
  335. $this->error('禁止访问');
  336. }
  337. /**
  338. * 编辑
  339. * @param string $ids
  340. * @internal
  341. */
  342. public function edit($ids = null)
  343. {
  344. $this->error('禁止访问');
  345. }
  346. /**
  347. * 删除
  348. * @param string $ids
  349. * @internal
  350. */
  351. public function del($ids = null)
  352. {
  353. $this->error('禁止访问');
  354. }
  355. /**
  356. * 批量更新
  357. * @internal
  358. * @param string $ids
  359. * @return void
  360. */
  361. public function multi($ids = null)
  362. {
  363. $this->error('禁止访问');
  364. }
  365. /**
  366. * 字段选择
  367. * @internal
  368. */
  369. public function selectfields()
  370. {
  371. //当前页
  372. $page = $this->request->request("pageNumber");
  373. //分页大小
  374. $pagesize = $this->request->request("pageSize");
  375. $q_word = (array) $this->request->request("q_word/a");
  376. $word = $q_word[0];
  377. $custom = (array) $this->request->request("custom/a");
  378. if ($custom && is_array($custom)) {
  379. $table = $custom['table'];
  380. }
  381. $fields = $this->getFields($table, ['id']);
  382. $commonFields = $this->getCommonFields();
  383. $fieldLists = [];
  384. foreach ($commonFields as $commonField) {
  385. if (!in_array($commonField['column_name'], $fields)) {
  386. $fieldLists[] = $commonField;
  387. }
  388. }
  389. if (!empty($word)) {
  390. $res_arr = [];
  391. foreach ($fieldLists as $fieldList) {
  392. $res_arr[] = $fieldList['column_name'] . '-' . $fieldList['comment'];
  393. }
  394. $res_arr = array_filter($res_arr, function ($v) use ($word) {
  395. return stripos($v, $word) !== false;
  396. });
  397. $res_arrs = array_values($res_arr);
  398. $fieldLists_arr = [];
  399. foreach ($res_arrs as $res) {
  400. $fieldLists_arr[] = [
  401. 'column_name' => explode('-', $res)[0],
  402. 'comment' => explode('-', $res)[1]
  403. ];
  404. }
  405. $fieldLists = $fieldLists_arr;
  406. }
  407. $result = array("total" => count($fieldLists), "list" => array_slice($fieldLists, ($page - 1) * $pagesize, $pagesize));
  408. return json($result);
  409. }
  410. /**
  411. * 字段类型
  412. * @internal
  413. */
  414. public function getType()
  415. {
  416. //当前页
  417. $page = $this->request->request("pageNumber");
  418. //分页大小
  419. $pagesize = $this->request->request("pageSize");
  420. $q_word = (array) $this->request->request("q_word/a");
  421. $word = $q_word ? $q_word[0] : '';
  422. $custom = (array) $this->request->request("custom/a");
  423. $keyValue = $this->request->request('keyValue');
  424. if (!$keyValue) {
  425. $suffix = [];
  426. $type = [];
  427. if ($custom && is_array($custom)) {
  428. $suffix = $custom['suffix'];
  429. $suffixList = $this->getSuffixList($suffix);
  430. $type = !is_array($suffixList['type']) ? [$suffixList['type']] : $suffixList['type'];
  431. }
  432. $typeList = $this->getTypeList($type);
  433. $lists = [];
  434. foreach ($typeList as $v) {
  435. $lists[] = ['type' => $v];
  436. }
  437. if (!empty($word)) {
  438. $res_arr = [];
  439. foreach ($lists as $list) {
  440. $res_arr[] = $list['type'];
  441. }
  442. $res_arr = array_filter($res_arr, function ($v) use ($word) {
  443. return stripos($v, $word) !== false;
  444. });
  445. $res_arrs = array_values($res_arr);
  446. $lists_arr = [];
  447. foreach ($res_arrs as $res) {
  448. $lists_arr[] = [
  449. 'type' => $res,
  450. ];
  451. }
  452. $lists = $lists_arr;
  453. }
  454. } else {
  455. $lists[] = ['type' => $keyValue];
  456. }
  457. $result = array("total" => count($lists), "rows" => array_slice($lists, ($page - 1) * $pagesize, $pagesize));
  458. return json($result);
  459. }
  460. /**
  461. * 字段后缀
  462. * @internal
  463. */
  464. public function getSuffix()
  465. {
  466. $name = $this->request->request("name");
  467. $suffix = $this->getSuffixList($name);
  468. return json($suffix);
  469. }
  470. /**
  471. * 读取后缀规则
  472. * @return array
  473. */
  474. protected function getSuffixList($suffix = '')
  475. {
  476. $suffixList = [];
  477. $suffixList['time'] = ["type" => ["bigint", "datetime"], "length" => 16, "default" => NULL, "comment" => '时间', "remark" => '识别为日期时间型数据,自动创建选择时间的组件'];
  478. $suffixList['image'] = ["type" => ["varchar"], "length" => 255, "default" => '', "comment" => '缩略图', "remark" => '识别为图片文件,自动生成可上传图片的组件,单图'];
  479. $suffixList['images'] = ["type" => ["varchar"], "length" => 1500, "default" => '', "comment" => '组图', "remark" => '识别为图片文件,自动生成可上传图片的组件,多图'];
  480. $suffixList['file'] = ["type" => ["varchar"], "length" => 100, "default" => '', "is_null" => 1, "comment" => '附件', "remark" => '识别为普通文件,自动生成可上传文件的组件,单文件'];
  481. $suffixList['files'] = ["type" => ["varchar"], "length" => 1000, "default" => '', "is_null" => 1, "comment" => '附件', "remark" => '识别为普通文件,自动生成可上传文件的组件,多文件'];
  482. $suffixList['avatar'] = ["type" => ["varchar"], "length" => 255, "default" => '', "is_null" => 1, "comment" => '头像', "remark" => '识别为头像,自动生成可上传图片的组件,单图'];
  483. $suffixList['avatars'] = ["type" => ["varchar"], "length" => 1500, "default" => '', "is_null" => 1, "comment" => '头像', "remark" => '识别为头像,自动生成可上传图片的组件,多图'];
  484. $suffixList['seconds'] = ["type" => ["int"], "length" => 10, "default" => NULL, "is_null" => 1, "comment" => '时长/分钟'];
  485. $suffixList['price'] = ["type" => ["decimal"], "length" => '10,2', "default" => '0.00', "is_null" => 1, 'unsigned' => 1, "comment" => '价格'];
  486. $suffixList['content'] = ["type" => ["text", "mediumtext", "longtext"], "is_null" => 1, "comment" => '内容', "remark" => '识别为内容,自动生成富文本编辑器(需安装富文本插件)'];
  487. $suffixList['_id'] = ["type" => ["int"], "length" => 10, "default" => 0, "is_null" => 1, "unsigned" => 1, "zerofill" => 0, "comment" => 'ID', "remark" => '识别为关联字段,自动生成可自动完成的文本框,单选'];
  488. $suffixList['_ids'] = ["type" => ["varchar"], "length" => 100, "default" => '', "comment" => 'ID集合', "remark" => '识别为关联字段,自动生成可自动完成的文本框,多选'];
  489. $suffixList['list'] = ["type" => ["enum", "set"], "is_null" => 1, "remark" => ['识别为列表字段,自动生成单选下拉列表', '识别为列表字段,自动生成多选下拉列表']];
  490. $suffixList['data'] = ["type" => ["enum", "set"], "is_null" => 1, "remark" => ['识别为选项字段,自动生成单选框', '识别为选项字段,自动生成复选框']];
  491. if (version_compare(config('fastadmin.version'), '1.3.0', '<')) {
  492. $suffixList['json'] = ["type" => ["varchar"], "length" => 255, "default" => '', "is_null" => 1, "comment" => '管理员ID', "remark" => '识别为键值组件,自动生成键值录入组件,仅支持1.2.0+'];
  493. $suffixList['switch'] = ["type" => ["tinyint"], "length" => 1, "default" => 0, "is_null" => 1, "comment" => '开关', "remark" => '识别为开关字段,自动生成开关组件,默认值1为开,0为关,仅支持FastAdmin 1.2.0+'];
  494. } else {
  495. $suffixList['range'] = ["type" => ["varchar"], "length" => 100, "default" => '', "is_null" => 1, "comment" => '区间', "remark" => '识别为时间区间组件,自动生成时间区间组件,仅支持FastAdmin 1.3.0+'];
  496. $suffixList['tag'] = ["type" => ["varchar"], "length" => 255, "default" => '', "is_null" => 1, "comment" => '标签', "remark" => '识别为Tagsinput,自动生成标签输入组件,仅支持FastAdmin 1.3.0+'];
  497. $suffixList['tags'] = ["type" => ["varchar"], "length" => 255, "default" => '', "is_null" => 1, "comment" => '标签组', "remark" => '识别为Tagsinput,自动生成标签输入组件,仅支持FastAdmin 1.3.0+'];
  498. }
  499. return empty($suffix) ? array_keys($suffixList) : $suffixList[$suffix];
  500. }
  501. /**
  502. * 读取类型规则
  503. * @return array
  504. */
  505. protected function getTypeList($types = [])
  506. {
  507. $typeList = [];
  508. $sql = "SELECT DISTINCT DATA_TYPE FROM information_schema.COLUMNS";
  509. $result = Db::query($sql);
  510. foreach ($result as $key => $value) {
  511. $typeList[$value['DATA_TYPE']] = $value['DATA_TYPE'];
  512. if (!empty($types) && !in_array($value['DATA_TYPE'], $types)) {
  513. unset($typeList[$value['DATA_TYPE']]);
  514. }
  515. }
  516. return $typeList;
  517. }
  518. protected function getCommonFields($fields = '')
  519. {
  520. $fieldList = include ADDON_PATH . 'famysql' . DS . 'data' . DS . 'fields.php';
  521. $fields = $fields == '' ? [] : explode(',', $fields);
  522. if (!empty($fields)) {
  523. $sql = "";
  524. foreach ($fieldList as $field => $fieldInfo) {
  525. if (in_array($field, $fields)) {
  526. $sql .= " ADD COLUMN `{$field}`" . $this->getFieldSql($field, $fieldInfo);
  527. $sql .= ",";
  528. }
  529. }
  530. return $sql;
  531. } else {
  532. $fields = array_keys($fieldList);
  533. $result = [];
  534. foreach ($fields as $key => $field) {
  535. $result[$key] = [
  536. "column_name" => $field,
  537. "comment" => isset($fieldList[$field]['comment']) ? $fieldList[$field]['comment'] : ucwords($field)
  538. ];
  539. }
  540. return $result;
  541. }
  542. }
  543. /**
  544. * 获取表字段属性
  545. */
  546. protected function getProperties($table, $field)
  547. {
  548. $all = Db::query("SHOW FULL COLUMNS FROM `{$table}` WHERE Field = '{$field}'");
  549. $str = '';
  550. $str .= "{$all[0]['Type']}";
  551. if ($all[0]['Collation'] != NULL) {
  552. $charset = substr($all[0]['Collation'], 0, strpos($all[0]['Collation'], '_'));
  553. $str .= " CHARACTER SET {$charset} COLLATE {$all[0]['Collation']}";
  554. }
  555. if ($all[0]['Null'] == 'NO')
  556. $str .= ' NOT NULL';
  557. if ($all[0]['Default'] === '')
  558. $str .= " DEFAULT ''";
  559. if ($all[0]['Default'] != NULL && $all[0]['Default'] != '')
  560. $str .= " DEFAULT '{$all[0]['Default']}'";
  561. if ($all[0]['Extra'] == 'auto_increment')
  562. $str .= ' AUTO_INCREMENT';
  563. $str .= " Comment '{$all[0]['Comment']}'";
  564. return $str;
  565. }
  566. protected function getFieldSql($field, $fieldInfo)
  567. {
  568. $sql = "";
  569. if (isset($fieldInfo['type'])) {
  570. $sql .= " {$fieldInfo['type']}";
  571. }
  572. if (!in_array($fieldInfo['type'], ["enum", "set"]) && isset($fieldInfo['length'])) {
  573. $sql .= "(" . $fieldInfo['length'] . ")";
  574. } elseif (in_array($fieldInfo['type'], ["enum", "set"])) {
  575. $length = "";
  576. foreach ($fieldInfo['length'] as $value) {
  577. $length .= "'{$value}',";
  578. }
  579. $length = rtrim($length, ",");
  580. $sql .= "(" . $length . ")";
  581. }
  582. if (isset($fieldInfo['unsigned']) && $fieldInfo['unsigned'] == 1) {
  583. $sql .= " UNSIGNED";
  584. }
  585. if (isset($fieldInfo['zerofill']) && $fieldInfo['zerofill'] == 1) {
  586. $sql .= " ZEROFILL";
  587. }
  588. if (isset($fieldInfo['is_null']) && $fieldInfo['is_null'] == 0) {
  589. $sql .= " NOT NULL";
  590. }
  591. if (isset($fieldInfo['default'])) {
  592. if (in_array($fieldInfo['type'], ["int", "tinyint", "smallint", "mediumint", "bigint"])) {
  593. if ($fieldInfo['default'] == "") {
  594. $sql .= "";
  595. } elseif ($fieldInfo['default'] == 0) {
  596. $sql .= " DEFAULT 0";
  597. } else {
  598. $sql .= empty($fieldInfo['default']) ? "" : " DEFAULT {$fieldInfo['default']}";
  599. }
  600. } elseif (in_array($fieldInfo['type'], ["float", "double", "decimal"])) {
  601. if ($fieldInfo['default'] == "") {
  602. $sql .= "";
  603. } elseif ($fieldInfo['default'] == 0) {
  604. $sql .= " DEFAULT '0.00'";
  605. } else {
  606. $sql .= empty($fieldInfo['default']) ? "" : " DEFAULT '{$fieldInfo['default']}'";
  607. }
  608. } elseif (in_array($fieldInfo['type'], ["text", "longtext", "mediumtext"])) {
  609. $sql .= empty($fieldInfo['default']) ? "" : " DEFAULT '{$fieldInfo['default']}'";
  610. } elseif (in_array($fieldInfo['type'], ["enum", "set"])) {
  611. $sql .= (empty($fieldInfo['default']) && $fieldInfo['default'] !== '0') ? "" : " DEFAULT '{$fieldInfo['default']}'";
  612. } else {
  613. if ($fieldInfo['default'] === '0') {
  614. $sql .= " DEFAULT '0'";
  615. } elseif (empty($fieldInfo['default'])) {
  616. } else {
  617. $sql .= " DEFAULT '{$fieldInfo['default']}'";
  618. }
  619. }
  620. }
  621. $comment = isset($fieldInfo['comment']) ? $fieldInfo['comment'] : ucwords($field);
  622. $sql .= " COMMENT '{$comment}'";
  623. return $sql;
  624. }
  625. protected function getFields($table, $excludeFields = [])
  626. {
  627. $fields = Db::getFields($table);
  628. $result = [];
  629. foreach ($fields as $field => $fieldInfo) {
  630. if (!in_array($field, $excludeFields)) {
  631. $result[] = $field;
  632. }
  633. }
  634. return $result;
  635. }
  636. }