ArticleController.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: chenkuan
  5. * Date: 2017/11/9
  6. * Time: 上午10:39
  7. */
  8. namespace frontend\controllers;
  9. use common\helpers\PaginationHelper;
  10. use common\helpers\ValidatorHelper;
  11. use frontend\models\Article;
  12. use frontend\models\ArticleCategory;
  13. use Symfony\Component\Yaml\Tests\A;
  14. use yii\data\Pagination;
  15. /**
  16. * 注:article表的is_publication,is_recommend,is_top的数据类型是bit(1),在线上不能按常规的判断方式判断,所以在这里先转换
  17. * 刚开始使用的是CONVERT函数,但是当select方法的参数是字符串时,select方法会根据逗号分隔成数据,CONVERT函数的两个参数之间有逗号,所以不能正确地转换成数据,解决办法是使用CAST函数或调用select方法时传入数组
  18. *
  19. * CONVERT(is_top, SIGNED) AS is_top 第一个参数是字段,第二个是要转换的类型,AS取别名,Mysql函数有多个参数时,不要传字符串到select方法
  20. * CAST(is_top AS SIGNED) AS is_top 第一个AS是类型转换,第二个AS是取别名
  21. *
  22. * @see \yii\db\Query::select()
  23. * @see https://dev.mysql.com/doc/refman/5.6/en/type-conversion.html
  24. * @see https://dev.mysql.com/doc/refman/5.6/en/cast-functions.html
  25. */
  26. class ArticleController extends BaseController
  27. {
  28. /**
  29. * 前台首页公告/动态/汇评列表获取接口
  30. * 1:Announcement
  31. * 2:Devisenmarkt
  32. * 5:ReviewAnalysis
  33. */
  34. public function actionGetArticleList()
  35. {
  36. $request = \Yii::$app->request;
  37. $articleCategory = $request->get('id');
  38. $type = $request->get('type', '');
  39. $isContainChildren = $request->get('isContainChildren', true);
  40. $pageNumber = $request->get('pageNumber', 1);
  41. $pageSize = $request->get('pageSize', 10);
  42. $offset = 0;
  43. if ($pageNumber > 1) {
  44. $offset = ($pageNumber - 1) * $pageSize;
  45. }
  46. $ac = ArticleCategory::findOne(['id' => $articleCategory]);
  47. $query = Article::find()->alias('a')
  48. ->leftJoin('bit_article_category ac', 'a.article_category_id = ac.id');
  49. if ($articleCategory != null) {
  50. if (strcasecmp($type, 'top') == 0) {
  51. if ($isContainChildren) {
  52. $query->andWhere([
  53. 'a.is_publication' => 1,
  54. 'a.is_top' => 1,
  55. ])->andWhere(['like', 'ac.path', $ac->path.'%', false])->orderBy([
  56. 'a.is_top' => SORT_DESC,
  57. 'a.create_date' => SORT_DESC,
  58. ]);
  59. } else {
  60. $query->andWhere([
  61. 'a.is_publication' => 1,
  62. 'a.is_top' => 1,
  63. 'a.article_category_id' => $articleCategory,
  64. ])->orderBy([
  65. 'a.is_top' => SORT_DESC,
  66. 'a.create_date' => SORT_DESC,
  67. ]);
  68. }
  69. } elseif (strcasecmp($type, 'recommend') == 0) {
  70. if ($isContainChildren) {
  71. $query->andWhere([
  72. 'a.is_publication' => 1,
  73. 'a.is_recommend' => 1,
  74. ])->andWhere(['like', 'ac.path', $ac->path.'%', false])->orderBy([
  75. 'a.is_top' => SORT_DESC,
  76. 'a.create_date' => SORT_DESC,
  77. ]);
  78. } else {
  79. $query->andWhere([
  80. 'a.is_publication' => 1,
  81. 'a.is_recommend' => 1,
  82. 'a.article_category_id' => $articleCategory,
  83. ])->orderBy([
  84. 'a.is_top' => SORT_DESC,
  85. 'a.create_date' => SORT_DESC,
  86. ]);
  87. }
  88. } elseif (strcasecmp($type, 'hot') == 0) {
  89. if ($isContainChildren) {
  90. $query->andWhere([
  91. 'a.is_publication' => 1,
  92. ])->andWhere(['like', 'ac.path', $ac->path.'%', false])->orderBy([
  93. 'a.hits' => SORT_DESC,
  94. 'a.create_date' => SORT_DESC,
  95. ]);
  96. } else {
  97. $query->andWhere([
  98. 'a.is_publication' => 1,
  99. 'a.article_category_id' => $articleCategory,
  100. ])->orderBy([
  101. 'a.hits' => SORT_DESC,
  102. 'a.create_date' => SORT_DESC,
  103. ]);
  104. }
  105. } elseif (strcasecmp($type, 'img') == 0) {
  106. if ($isContainChildren) {
  107. $query->andWhere([
  108. 'a.is_publication' => 1,
  109. ])->andWhere(['NOT', ['a.image_path' => null]])->andWhere(
  110. ['like', 'ac.path', $ac->path.'%', false]
  111. )->orderBy([
  112. 'a.create_date' => SORT_DESC,
  113. ]);
  114. } else {
  115. $query->andWhere([
  116. 'a.is_publication' => 1,
  117. 'a.article_category_id' => $articleCategory,
  118. ])->andWhere(['NOT', ['a.image_path' => null]])->orderBy([
  119. 'a.hits' => SORT_DESC,
  120. 'a.create_date' => SORT_DESC,
  121. ]);
  122. }
  123. } elseif ($isContainChildren) {
  124. $query->andWhere([
  125. 'a.is_publication' => 1,
  126. ])->andWhere(
  127. ['like', 'ac.path', $ac->path.'%', false]
  128. )->orderBy([
  129. 'a.is_top' => SORT_DESC,
  130. 'a.create_date' => SORT_DESC,
  131. ]);
  132. } else {
  133. $query->andWhere([
  134. 'a.is_publication' => 1,
  135. 'a.article_category_id' => $articleCategory,
  136. ])->orderBy([
  137. 'a.is_top' => SORT_DESC,
  138. 'a.create_date' => SORT_DESC,
  139. ]);
  140. }
  141. } elseif (strcasecmp($type, 'top') == 0) {
  142. $query->andWhere([
  143. 'a.is_publication' => 1,
  144. 'a.is_top' => 1,
  145. ])->orderBy([
  146. 'a.is_top' => SORT_DESC,
  147. 'a.create_date' => SORT_DESC,
  148. ]);
  149. } elseif (strcasecmp($type, 'recommend') == 0) {
  150. $query->andWhere([
  151. 'a.is_publication' => 1,
  152. 'a.is_recommend' => 1,
  153. ])->orderBy([
  154. 'a.is_top' => SORT_DESC,
  155. 'a.create_date' => SORT_DESC,
  156. ]);
  157. } elseif (strcasecmp($type, 'hot') == 0) {
  158. $query->andWhere([
  159. 'a.is_publication' => 1,
  160. ])->orderBy([
  161. 'a.hits' => SORT_DESC,
  162. 'a.create_date' => SORT_DESC,
  163. ]);
  164. } elseif (strcasecmp($type, 'img') == 0) {
  165. $query->andWhere([
  166. 'a.is_publication' => 1,
  167. ])->andWhere(
  168. ['NOT', ['a.image_path' => null]]
  169. )->orderBy([
  170. 'a.create_date' => SORT_DESC,
  171. ]);
  172. } else {
  173. $query->andWhere([
  174. 'a.is_publication' => 1,
  175. ])->orderBy([
  176. 'a.is_top' => SORT_DESC,
  177. 'a.create_date' => SORT_DESC,
  178. ]);
  179. }
  180. $countQuery = clone $query;
  181. $count = (int)$countQuery->select('count(*)')->scalar();
  182. $query->select('a.id, CAST(is_publication AS SIGNED) AS is_publication, CAST(is_recommend AS SIGNED) AS is_recommend, CAST(is_top AS SIGNED) AS is_top,a.create_date,
  183. a.article_category_id,a.hits,a.image_path,a.title,a.link_url,
  184. a.min_content,a.content,ac.name,
  185. ac.path');
  186. $query->offset($offset)->limit($pageSize);
  187. $result['data'] = $query->asArray()->all();
  188. $result['totalCount'] = $count;
  189. return $this->outJson(1, $result);
  190. }
  191. /**
  192. * 文章详情
  193. */
  194. public function actionArticleDetail()
  195. {
  196. $result = [];
  197. $articleId = \Yii::$app->request->get('id');
  198. $model = Article::find()->alias('a')
  199. ->leftJoin(ArticleCategory::tableName().' ac', 'a.article_category_id = ac.id')
  200. ->select([
  201. 'a.*',
  202. 'CONVERT(a.is_publication, SIGNED) AS is_publication',
  203. 'CONVERT(a.is_recommend, SIGNED) AS is_recommend',
  204. 'CONVERT(a.is_top, SIGNED) AS is_top',
  205. 'ac.name AS category_name'
  206. ])->where(['a.id' => $articleId]);
  207. $modelClone = clone $model;
  208. $article = $model->one();
  209. if ($article) {
  210. $article->hits += 1;
  211. $article->save();
  212. $result['article'] = $modelClone->asArray()->one();
  213. $result['nextArticle'] = $this->getNextArticle($article);
  214. $result['previousArticle'] = $this->getPreviousArticle($article);
  215. $result['relationArticle'] = $this->getRelationArticle($article);
  216. return $this->outJson(1, $result);
  217. } else {
  218. return $this->outJson(0, [], '获取文章详情失败');
  219. }
  220. }
  221. private function getNextArticle(Article $article)
  222. {
  223. $query = Article::find()->alias('a')
  224. ->select('a.id,CAST(is_publication AS SIGNED) AS is_publication, CAST(is_recommend AS SIGNED) AS is_recommend, CAST(is_top AS SIGNED) AS is_top,a.create_date,a.create_date,
  225. a.article_category_id,a.hits,a.image_path,a.title,a.link_url,
  226. a.min_content,ac.path,ac.language')
  227. ->leftJoin('bit_article_category ac', 'a.article_category_id = ac.id')
  228. ->andWhere(['a.article_category_id' => $article->article_category_id])
  229. ->andWhere(['ac.language' => 0])
  230. ->andWhere(['a.is_publication' => 1])
  231. ->andWhere(['>', 'a.create_date', $article->create_date])
  232. ->orderBy(['a.create_date' => SORT_ASC])
  233. ->limit(1);
  234. $rs = $query->asArray()->one();
  235. if (!empty($rs) && count($rs) > 0) {
  236. return $rs;
  237. }
  238. return null;
  239. }
  240. private function getPreviousArticle(Article $article)
  241. {
  242. $query = Article::find()->alias('a')
  243. ->select('a.id,CAST(is_publication AS SIGNED) AS is_publication, CAST(is_recommend AS SIGNED) AS is_recommend, CAST(is_top AS SIGNED) AS is_top,a.create_date,a.create_date,
  244. a.article_category_id,a.hits,a.image_path,a.title,a.link_url,
  245. a.min_content,
  246. ac.path,ac.language')
  247. ->leftJoin('bit_article_category ac', 'a.article_category_id = ac.id')
  248. ->andWhere(['a.article_category_id' => $article->article_category_id])
  249. ->andWhere(['ac.language' => 0])
  250. ->andWhere(['a.is_publication' => 1])
  251. ->andWhere(['<', 'a.create_date', $article->create_date])
  252. ->orderBy(['a.create_date' => SORT_DESC])
  253. ->limit(1);
  254. $rs = $query->asArray()->one();
  255. if (!empty($rs) && count($rs) > 0) {
  256. return $rs;
  257. }
  258. return null;
  259. }
  260. private function getRelationArticle(Article $article)
  261. {
  262. $ids = [];
  263. $next = $this->getNextArticle($article);
  264. $previous = $this->getPreviousArticle($article);
  265. if (!empty($next)) {
  266. $ids[] = $next['id'];
  267. }
  268. if (!empty($previous)) {
  269. $ids[] = $previous['id'];
  270. }
  271. $query = Article::find()->alias('a')
  272. ->select('a.id,CAST(is_publication AS SIGNED) AS is_publication, CAST(is_recommend AS SIGNED) AS is_recommend, CAST(is_top AS SIGNED) AS is_top,a.create_date,a.create_date,
  273. a.article_category_id,a.hits,a.image_path,a.title,a.link_url,
  274. a.min_content,
  275. ac.path,ac.language')
  276. ->leftJoin('bit_article_category ac', 'a.article_category_id = ac.id')
  277. ->andWhere(['a.article_category_id' => $article->article_category_id])
  278. ->andWhere(['<>', 'a.id', $article->id])
  279. ->andWhere(['not in', 'a.id', $ids])
  280. ->andWhere(['ac.language' => 0])
  281. ->andWhere(['a.is_publication' => 1])
  282. ->andWhere(['<', 'a.create_date', $article->create_date])
  283. ->orderBy(['a.create_date' => SORT_DESC])
  284. ->limit(4);
  285. $rs = $query->asArray()->all();
  286. if (!empty($rs) && count($rs) > 0) {
  287. return $rs;
  288. }
  289. return null;
  290. }
  291. /**
  292. * 获取不同分类的文章列表
  293. */
  294. public function actionArticleList()
  295. {
  296. $request = \Yii::$app->getRequest()->get();
  297. $data['id'] = (int)$request['id'];
  298. $data['pageNumber'] = isset($request['pageNumber']) ? (int)($request['pageNumber']) : 1;
  299. $data['pageSize'] = isset($request['pageSize']) ? (int)($request['pageSize']) : 20;
  300. $data['orderBy'] = isset($request['orderBy']) ? trim($request['orderBy']) : 'create_date';
  301. $data['order'] = isset($request['order']) ? trim($request['order']) : 'desc';
  302. $data['keyword'] = isset($request['keyword']) ? trim($request['keyword']) : '';
  303. $data['searchBy'] = isset($request['searchBy']) ? trim($request['searchBy']) : 'title';
  304. $data['is_publication'] = isset($request['is_publication']) ? intval($request['is_publication']) : null;
  305. $data = ValidatorHelper::validateData($data, [
  306. ['pageNumber', 'integer', 'min' => 1],
  307. ['pageSize', 'integer', 'min' => 1],
  308. ['orderBy', 'string'],
  309. ], $errors);
  310. if ($data == false) {
  311. return $this->outJson(0, '', $errors);
  312. }
  313. $query = Article::find()
  314. ->select(['*', 'CONVERT(is_publication, SIGNED) AS is_publication', 'CONVERT(is_recommend, SIGNED) AS is_recommend', 'CONVERT(is_top, SIGNED) AS is_top'])
  315. ->where(['article_category_id' => $data['id']])
  316. ->with('category');
  317. // 有逗号隔开的情况,比如is_top asc, create_date desc
  318. if (strpos($data['orderBy'], ',') !== false) {
  319. $query->orderBy($data['orderBy']);
  320. } else {
  321. $query->orderBy($data['orderBy'].' '.$data['order']);
  322. }
  323. // 按标题搜索
  324. if ($data['searchBy'] == 'title' && !empty($data['keyword'])) {
  325. $query->andFilterWhere(['like', 'title', $data['keyword']]);
  326. }
  327. // 是否发布
  328. if ($data['is_publication'] !== null) {
  329. $query->andFilterWhere(['=', 'is_publication', $data['is_publication']]);
  330. }
  331. $result = PaginationHelper::queryPage($query, $data['pageNumber'], $data['pageSize']);
  332. return $this->outJson(1, $result);
  333. }
  334. /**
  335. * 保存文章
  336. */
  337. public function actionArticleSave()
  338. {
  339. $request = \Yii::$app->getRequest()->post();
  340. $id = isset($request['id']) ? (int)$request['id'] : '';
  341. if ($id) {
  342. $model = Article::findOne(['id' => $id]);
  343. $model->modify_date = date('Y-m-d H:i:s', strtotime($request['modify_date']));
  344. } else {
  345. $model = new Article();
  346. $model->create_date = date('Y-m-d H:i:s', strtotime($request['create_date']));
  347. $model->up = 0;
  348. $model->down = 0;
  349. $model->image_path = isset($request['image_path']) ? $request['image_path'] : null;
  350. }
  351. $model->article_category_id = (int)$request['article_category_id'];
  352. $model->modifydatea = date('Y-m-d H:i:s', strtotime($request['modifydatea']));
  353. $model->createdatea = date('Y-m-d H:i:s', strtotime($request['createdatea']));
  354. $model->setAttributes($request);
  355. if ($model->save()) {
  356. return $this->outJson(1, $model->getAttributes());
  357. } else {
  358. return $this->outJson(0, [], $model->hasErrors());
  359. }
  360. }
  361. /**
  362. * 获取文章详情
  363. */
  364. public function actionAdminArticleDetail()
  365. {
  366. $articleId = \Yii::$app->request->get('id');
  367. $article = Article::find()->select(['*', 'CONVERT(is_publication, SIGNED) AS is_publication', 'CONVERT(is_recommend, SIGNED) AS is_recommend', 'CONVERT(is_top, SIGNED) AS is_top'])->with('category')->where(['id' => $articleId])->asArray()->one();
  368. return $this->outJson(1, $article);
  369. }
  370. /**
  371. * 删除文章(批量)
  372. */
  373. public function actionArticleDelete()
  374. {
  375. $ids = \Yii::$app->request->post('ids');
  376. $rs = Article::deleteAll(['in', 'id', $ids]);
  377. return $this->outJson(1, $rs);
  378. }
  379. }