Models.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // |
  4. // +----------------------------------------------------------------------
  5. // |
  6. // +----------------------------------------------------------------------
  7. // |
  8. // +----------------------------------------------------------------------
  9. // |
  10. // +----------------------------------------------------------------------
  11. // +----------------------------------------------------------------------
  12. // | 模型模型
  13. // +----------------------------------------------------------------------
  14. namespace app\admin\model\cms;
  15. use think\Exception;
  16. use think\facade\Cache;
  17. use think\facade\Config;
  18. use think\facade\Db;
  19. use think\Model;
  20. /**
  21. * 模型
  22. */
  23. class Models extends Model
  24. {
  25. protected $name = 'cms_model';
  26. protected $autoWriteTimestamp = true;
  27. protected static $ext_table = '_data';
  28. public function getSettingAttr($value, $data)
  29. {
  30. return is_array($value) ? $value : (array) json_decode($data['setting'], true);
  31. }
  32. public function setSettingAttr($value)
  33. {
  34. return is_array($value) ? json_encode($value) : $value;
  35. }
  36. public static function onBeforeInsert($row)
  37. {
  38. $row['module'] = 'cms';
  39. $info = null;
  40. try {
  41. $info = Db::name($row['tablename'])->getPk();
  42. } catch (\Exception $e) {
  43. }
  44. if ($info) {
  45. throw new Exception("数据表已经存在");
  46. }
  47. }
  48. public static function onAfterInsert($row)
  49. {
  50. Cache::set("Model", null);
  51. Cache::set('ModelField', null);
  52. //创建模型表和模型字段
  53. if (self::createTable($row)) {
  54. self::addFieldRecord($row['id'], $row['type']);
  55. }
  56. }
  57. public static function onBeforeUpdate($row)
  58. {
  59. //编辑
  60. $changedData = $row->getChangedData();
  61. if (isset($changedData['category_template'])) {
  62. $row['setting']['category_template'] = $row->category_template;
  63. }
  64. if (isset($changedData['list_template'])) {
  65. $row['setting']['list_template'] = $row->list_template;
  66. }
  67. if (isset($changedData['show_template'])) {
  68. $row['setting']['show_template'] = $row->show_template;
  69. }
  70. if (isset($changedData['tablename'])) {
  71. $info = null;
  72. try {
  73. $info = Db::name($row['tablename'])->getPk();
  74. } catch (\Exception $e) {
  75. }
  76. if ($info) {
  77. throw new Exception("数据表已经存在");
  78. }
  79. try {
  80. $info = Db::name($row['tablename'] . self::$ext_table)->getPk();
  81. } catch (\Exception $e) {
  82. }
  83. if ($info) {
  84. throw new Exception("数据表已经存在");
  85. }
  86. }
  87. }
  88. public static function onAfterUpdate($row)
  89. {
  90. //更新缓存
  91. Cache::set("Model", null);
  92. Cache::set('ModelField', null);
  93. Cache::set('getModel_' . $row['id'], '');
  94. $changedData = $row->getChangedData();
  95. if (isset($changedData['tablename'])) {
  96. //表前缀
  97. $dbPrefix = Config::get("database.connections.mysql.prefix");
  98. //表名更改
  99. Db::execute("RENAME TABLE `{$dbPrefix}{$row->getOrigin('tablename')}` TO `{$dbPrefix}{$changedData['tablename']}` ;");
  100. //修改副表
  101. if ($row['type'] == 2) {
  102. Db::execute("RENAME TABLE `{$dbPrefix}{$row->getOrigin('tablename')}_data` TO `{$dbPrefix}{$changedData['tablename']}_data` ;");
  103. }
  104. }
  105. }
  106. public static function onBeforeDelete($row)
  107. {
  108. //删除
  109. $exist = Category::where('modelid', $row['id'])->find();
  110. if ($exist) {
  111. throw new Exception("该模型使用中,删除栏目后再删除!");
  112. }
  113. }
  114. public static function onAfterDelete($row)
  115. {
  116. Cache::set("Model", null);
  117. Cache::set('ModelField', null);
  118. //删除所有和这个模型相关的字段
  119. ModelField::where("modelid", $row['id'])->delete();
  120. //删除主表
  121. $table_name = Config::get("database.connections.mysql.prefix") . $row['tablename'];
  122. Db::execute("DROP TABLE IF EXISTS `{$table_name}`");
  123. if ((int) $row['type'] == 2) {
  124. //删除副表
  125. $table_name .= self::$ext_table;
  126. Db::execute("DROP TABLE IF EXISTS `{$table_name}`");
  127. }
  128. }
  129. /**
  130. * 创建内容模型
  131. */
  132. public static function createTable($data)
  133. {
  134. $data['tablename'] = strtolower($data['tablename']);
  135. $table = Config::get("database.connections.mysql.prefix") . $data['tablename'];
  136. $sql = <<<EOF
  137. CREATE TABLE `{$table}` (
  138. `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '文档ID',
  139. `catid` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT '栏目ID',
  140. `title` varchar(255) DEFAULT '' COMMENT '标题',
  141. `thumb` varchar(255) NOT NULL DEFAULT '' COMMENT '缩略图',
  142. `flag` varchar(32) DEFAULT '' COMMENT '属性',
  143. `keywords` varchar(255) DEFAULT '' COMMENT 'SEO关键词',
  144. `description` varchar(255) DEFAULT '' COMMENT 'SEO描述',
  145. `tags` varchar(255) DEFAULT '' COMMENT 'Tags标签',
  146. `listorder` smallint(5) unsigned NOT NULL DEFAULT '100' COMMENT '排序',
  147. `user_id` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT '用户id',
  148. `admin_id` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT '管理员id',
  149. `sysadd` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否后台添加',
  150. `hits` mediumint(8) UNSIGNED DEFAULT 0 COMMENT '点击量' ,
  151. `publish_time` int(10) unsigned DEFAULT NULL COMMENT '发布时间',
  152. `create_time` int(10) unsigned DEFAULT NULL COMMENT '创建时间',
  153. `update_time` int(10) unsigned DEFAULT NULL COMMENT '更新时间',
  154. `url` varchar(100) NOT NULL DEFAULT '' COMMENT '链接地址',
  155. `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态',
  156. PRIMARY KEY (`id`),
  157. KEY `status` (`catid`,`status`)
  158. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{$data['name']}模型表';
  159. EOF;
  160. $res = Db::execute($sql);
  161. if ($data['type'] == 2) {
  162. $table = $table . self::$ext_table;
  163. // 新建附属表
  164. $sql = <<<EOF
  165. CREATE TABLE `{$table}` (
  166. `did` mediumint(8) unsigned NOT NULL DEFAULT '0',
  167. `content` mediumtext COMMENT '内容',
  168. KEY `idx_did` (`did`)
  169. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{$data['name']}模型表';
  170. EOF;
  171. $res = Db::execute($sql);
  172. }
  173. return true;
  174. }
  175. /**
  176. * 添加默认字段
  177. */
  178. public static function addFieldRecord($modelid, $type)
  179. {
  180. $fieldsArr = [];
  181. $default = [
  182. 'modelid' => $modelid,
  183. 'pattern' => '',
  184. 'errortips' => '',
  185. 'create_time' => time(),
  186. 'update_time' => time(),
  187. 'ifsystem' => 1,
  188. 'status' => 1,
  189. 'listorder' => 100,
  190. 'ifsearch' => 0,
  191. 'iffixed' => 1,
  192. 'remark' => '',
  193. 'isadd' => 0,
  194. 'iscore' => 0,
  195. 'ifrequire' => 0,
  196. 'setting' => '[]',
  197. ];
  198. $data = [
  199. [
  200. 'name' => 'id',
  201. 'title' => '文档id',
  202. 'type' => 'hidden',
  203. 'isadd' => 1,
  204. 'setting' => '[]',
  205. ],
  206. [
  207. 'name' => 'catid',
  208. 'title' => '栏目id',
  209. 'type' => 'hidden',
  210. 'isadd' => 1,
  211. 'setting' => '[]',
  212. ],
  213. [
  214. 'name' => 'user_id',
  215. 'title' => '用户id',
  216. 'type' => 'number',
  217. 'iscore' => 1,
  218. 'setting' => '[]',
  219. ],
  220. [
  221. 'name' => 'admin_id',
  222. 'title' => '用户id',
  223. 'type' => 'number',
  224. 'iscore' => 1,
  225. 'setting' => '[]',
  226. ],
  227. [
  228. 'name' => 'sysadd',
  229. 'title' => '是否后台添加',
  230. 'type' => 'number',
  231. 'iscore' => 1,
  232. 'setting' => '[]',
  233. ],
  234. [
  235. 'name' => 'title',
  236. 'title' => '标题',
  237. 'type' => 'text',
  238. 'ifsearch' => 1,
  239. 'ifrequire' => 1,
  240. 'setting' => '{"define":"varchar(255) NOT NULL DEFAULT \'\'"}',
  241. 'isadd' => 1,
  242. 'listorder' => 300,
  243. ],
  244. [
  245. 'name' => 'flag',
  246. 'title' => '属性',
  247. 'type' => 'checkbox',
  248. 'setting' => '{"define":"varchar(32) NOT NULL DEFAULT \'\'","options":"1:\u7f6e\u9876[1]\r\n2:\u5934\u6761[2]\r\n3:\u7279\u8350[3]\r\n4:\u63a8\u8350[4]\r\n5:\u70ed\u70b9[5]\r\n6:\u5e7b\u706f[6]"}',
  249. 'listorder' => 295,
  250. ],
  251. [
  252. 'name' => 'keywords',
  253. 'title' => 'SEO关键词',
  254. 'type' => 'tags',
  255. 'iffixed' => 0,
  256. 'remark' => '关键词用回车确认',
  257. 'setting' => '{"define":"varchar(255) NOT NULL DEFAULT \'\'"}',
  258. 'isadd' => 1,
  259. 'listorder' => 290,
  260. ],
  261. [
  262. 'name' => 'description',
  263. 'title' => 'SEO摘要',
  264. 'type' => 'textarea',
  265. 'iffixed' => 0,
  266. 'remark' => '如不填写,则自动截取附表中编辑器的200字符',
  267. 'setting' => '{"define":"varchar(255) NOT NULL DEFAULT \'\'"}',
  268. 'isadd' => 1,
  269. 'listorder' => 285,
  270. ],
  271. [
  272. 'name' => 'tags',
  273. 'title' => 'Tags标签',
  274. 'type' => 'tags',
  275. 'iffixed' => 0,
  276. 'remark' => '关键词用回车确认',
  277. 'setting' => '{"define":"varchar(255) NOT NULL DEFAULT \'\'"}',
  278. 'listorder' => 280,
  279. ],
  280. [
  281. 'name' => 'thumb',
  282. 'title' => '缩略图',
  283. 'type' => 'image',
  284. 'ifrequire' => 0,
  285. 'iffixed' => 0,
  286. 'setting' => '{"define":"text NOT NULL"}',
  287. 'isadd' => 1,
  288. 'listorder' => 275,
  289. ],
  290. [
  291. 'name' => 'hits',
  292. 'title' => '点击量',
  293. 'type' => 'number',
  294. 'listorder' => 265,
  295. 'setting' => '{"define":"mediumint(8) UNSIGNED NOT NULL DEFAULT \'0\'"}',
  296. ],
  297. [
  298. 'name' => 'listorder',
  299. 'title' => '排序',
  300. 'type' => 'number',
  301. 'setting' => '{"define":"tinyint(3) UNSIGNED NOT NULL","value":100}',
  302. 'listorder' => 260,
  303. ],
  304. [
  305. 'name' => 'url',
  306. 'title' => '链接地址',
  307. 'type' => 'text',
  308. 'listorder' => 255,
  309. 'setting' => '{"define":"varchar(100) NOT NULL DEFAULT \'\'"}',
  310. 'remark' => '有值时生效,内部链接格式:模块/控制器/操作?参数=参数值&...,外部链接则必须http://开头',
  311. ],
  312. [
  313. 'name' => 'publish_time',
  314. 'title' => '发布时间',
  315. 'type' => 'datetime',
  316. 'listorder' => 250,
  317. 'setting' => '{"define":"int(10) UNSIGNED DEFAULT NULL"}',
  318. ],
  319. [
  320. 'name' => 'create_time',
  321. 'title' => '创建时间',
  322. 'type' => 'datetime',
  323. 'listorder' => 250,
  324. 'setting' => '{"define":"int(10) UNSIGNED DEFAULT NULL"}',
  325. 'iscore' => 1,
  326. ],
  327. [
  328. 'name' => 'update_time',
  329. 'title' => '更新时间',
  330. 'type' => 'datetime',
  331. 'listorder' => 245,
  332. 'setting' => '{"define":"int(10) UNSIGNED DEFAULT NULL"}',
  333. 'iscore' => 1,
  334. ],
  335. [
  336. 'name' => 'status',
  337. 'title' => '状态',
  338. 'type' => 'radio',
  339. 'setting' => '{"define":"tinyint(1) UNSIGNED NOT NULL DEFAULT \'0\'","options":"0:\u7981\u7528\r\n1:\u542f\u7528","value":1}',
  340. 'listorder' => 240,
  341. ],
  342. ];
  343. if ($type == 2) {
  344. array_push($data, [
  345. 'name' => 'did',
  346. 'title' => '附表文档id',
  347. 'type' => 'hidden',
  348. 'iscore' => 1,
  349. 'ifsystem' => 0,
  350. 'setting' => '[]',
  351. ],
  352. [
  353. 'name' => 'content',
  354. 'title' => '内容',
  355. 'type' => 'editor',
  356. 'ifsystem' => 0,
  357. 'iffixed' => 0,
  358. 'setting' => '{"define":"text NOT NULL"}',
  359. 'isadd' => 1,
  360. 'listorder' => 270,
  361. ]);
  362. }
  363. foreach ($data as $item) {
  364. $fieldsArr[] = array_merge($default, $item);
  365. }
  366. Db::name('cms_field')->insertAll($fieldsArr);
  367. return true;
  368. }
  369. }