Channel.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <?php
  2. namespace app\admin\model\cms;
  3. use think\Exception;
  4. use think\Model;
  5. class Channel extends Model
  6. {
  7. // 表名
  8. protected $name = 'cms_channel';
  9. // 自动写入时间戳字段
  10. protected $autoWriteTimestamp = 'int';
  11. // 定义时间戳字段名
  12. protected $createTime = 'createtime';
  13. protected $updateTime = 'updatetime';
  14. // 追加属性
  15. protected $append = [
  16. 'type_text',
  17. 'status_text',
  18. 'url',
  19. 'fullurl',
  20. 'outlink',
  21. ];
  22. protected static $config = [];
  23. public function getUrlAttr($value, $data)
  24. {
  25. return $this->buildUrl($value, $data);
  26. }
  27. public function getFullurlAttr($value, $data)
  28. {
  29. return $this->buildUrl($value, $data, true);
  30. }
  31. private function buildUrl($value, $data, $domain = false)
  32. {
  33. $diyname = isset($data['diyname']) && $data['diyname'] ? $data['diyname'] : $data['id'];
  34. $cateid = $data['id'] ?? 0;
  35. $catename = isset($data['diyname']) && $data['diyname'] ? $data['diyname'] : 'all';
  36. $time = $data['createtime'] ?? time();
  37. $vars = [
  38. ':id' => $data['id'],
  39. ':diyname' => $diyname,
  40. ':channel' => $cateid,
  41. ':catename' => $catename,
  42. ':cateid' => $cateid,
  43. ':year' => date("Y", $time),
  44. ':month' => date("m", $time),
  45. ':day' => date("d", $time)
  46. ];
  47. if (isset($data['type']) && isset($data['outlink']) && $data['type'] == 'link') {
  48. return $this->getAttr('outlink');
  49. }
  50. return addon_url('cms/channel/index', $vars, static::$config['urlsuffix'], $domain);
  51. }
  52. public function getOutlinkAttr($value, $data)
  53. {
  54. $indexUrl = $view_replace_str = config('view_replace_str.__PUBLIC__');
  55. $indexUrl = rtrim($indexUrl, '/');
  56. return str_replace('__INDEX__', $indexUrl, $value);
  57. }
  58. protected static function init()
  59. {
  60. $config = static::$config = get_addon_config('cms');
  61. self::beforeInsert(function ($row) {
  62. if ($row->getData('type') == 'link') {
  63. $row->model_id = 0;
  64. }
  65. });
  66. self::beforeUpdate(function ($row) {
  67. if ($row['parent_id']) {
  68. $childrenIds = self::getChildrenIds($row['id'], true);
  69. if (in_array($row['parent_id'], $childrenIds)) {
  70. throw new Exception("上级栏目不能是其自身或子栏目");
  71. }
  72. }
  73. });
  74. self::beforeWrite(function ($row) {
  75. //在更新之前对数组进行处理
  76. foreach ($row->getData() as $k => $value) {
  77. if (is_array($value) && is_array(reset($value))) {
  78. $value = json_encode(self::getArrayData($value), JSON_UNESCAPED_UNICODE);
  79. } else {
  80. $value = is_array($value) ? implode(',', $value) : $value;
  81. }
  82. $row->$k = $value;
  83. }
  84. });
  85. self::afterInsert(function ($row) {
  86. //创建时自动添加权重值
  87. $pk = $row->getPk();
  88. $row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);
  89. });
  90. self::afterDelete(function ($row) {
  91. //删除时,删除子节点,同时将所有相关文档移入回收站
  92. $childIds = self::getChildrenIds($row['id']);
  93. if ($childIds) {
  94. Channel::destroy(function ($query) use ($childIds) {
  95. $query->where('id', 'in', $childIds);
  96. });
  97. }
  98. $childIds[] = $row['id'];
  99. db('cms_archives')->where('channel_id', 'in', $childIds)->update(['deletetime' => time()]);
  100. });
  101. self::afterWrite(function ($row) use ($config) {
  102. $changed = $row->getChangedData();
  103. //隐藏时判断是否有子节点,有则隐藏
  104. if (isset($changed['status']) && $changed['status'] == 'hidden') {
  105. $childIds = self::getChildrenIds($row['id']);
  106. db('cms_channel')->where('id', 'in', $childIds)->update(['status' => 'hidden']);
  107. }
  108. //隐藏栏目显示时判断是否有子节点
  109. if (isset($changed['isnav']) && !$changed['isnav']) {
  110. $childIds = self::getChildrenIds($row['id']);
  111. db('cms_channel')->where('id', 'in', $childIds)->update(['isnav' => 0]);
  112. }
  113. if (isset($changed['status']) && $changed['status'] == 'normal') {
  114. //推送到熊掌号+百度站长
  115. if ($config['baidupush']) {
  116. $urls = [$row->fullurl];
  117. \think\Hook::listen("baidupush", $urls);
  118. }
  119. }
  120. });
  121. }
  122. public static function getTypeList()
  123. {
  124. return ['channel' => __('Channel'), 'list' => __('List'), 'link' => __('Link')];
  125. }
  126. public static function getStatusList()
  127. {
  128. return ['normal' => __('Normal'), 'hidden' => __('Hidden')];
  129. }
  130. public static function getListtypeList()
  131. {
  132. return ['0' => __('自已和所有子级'), '1' => __('自己和一级子级'), '2' => __('仅自己'), '3' => __('仅包含一级子级(不含自己)'), '4' => __('仅包含所有子级(不含自己)')];
  133. }
  134. public function getTypeTextAttr($value, $data)
  135. {
  136. $value = $value ? $value : $data['type'];
  137. $list = $this->getTypeList();
  138. return isset($list[$value]) ? $list[$value] : '';
  139. }
  140. public function getStatusTextAttr($value, $data)
  141. {
  142. $value = $value ? $value : $data['status'];
  143. $list = $this->getStatusList();
  144. return isset($list[$value]) ? $list[$value] : '';
  145. }
  146. /**
  147. * 获取栏目的所有子节点ID
  148. * @param int $id 栏目ID
  149. * @param bool $withself 是否包含自身
  150. * @return array
  151. */
  152. public static function getChildrenIds($id, $withself = false)
  153. {
  154. static $tree;
  155. if (!$tree) {
  156. $tree = \fast\Tree::instance();
  157. $tree->init(collection(Channel::order('weigh desc,id desc')->field('id,parent_id,name,type,diyname,status')->select())->toArray(), 'parent_id');
  158. }
  159. $childIds = $tree->getChildrenIds($id, $withself);
  160. return $childIds;
  161. }
  162. public function model()
  163. {
  164. return $this->belongsTo('Modelx', 'model_id')->setEagerlyType(0);
  165. }
  166. }