CategoryRepository.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. <?php
  2. /**
  3. * 分类.
  4. *
  5. * @author jim <jim458734573@gmail.com>
  6. * @date 2020-01-31 10:39:38
  7. */
  8. declare(strict_types=1);
  9. namespace App\Repositories;
  10. use App\Constants\CategoryConstant;
  11. use App\Model\CategoryModel;
  12. use App\Model\TypeModel;
  13. use App\Model\VideoModel;
  14. use App\Model\VideoPerfectModel;
  15. use App\Repositories\Utils\M3u8CacheRepository;
  16. use KZ2\Repositories\Model\Repository;
  17. use Psr\SimpleCache\CacheInterface;
  18. class CategoryRepository extends Repository
  19. {
  20. public function model()
  21. {
  22. return CategoryModel::class;
  23. }
  24. /**
  25. * 创建一个
  26. * @param array $setarr
  27. * @return \Hyperf\Database\Model\Builder|\Hyperf\Database\Model\Model
  28. */
  29. public function createOne(array $setarr)
  30. {
  31. $item = [
  32. 'name' => data_get($setarr, 'name', ''),
  33. 'alias_name' => strtolower(data_get($setarr, 'alias_name', '')),
  34. 'position' => strtolower(data_get($setarr, 'position', '')),
  35. 'squad' => data_get($setarr, 'squad', 1000),
  36. 't_color' => data_get($setarr, 't_color', ''),
  37. 'parent_id' => data_get($setarr, 'parent_id', 0),
  38. 'cover_pic' => data_get($setarr, 'cover_pic', ''),
  39. 'show_num' => intval(data_get($setarr, 'show_num', 10)),
  40. ];
  41. $obj = CategoryModel::query()->create($item);
  42. return $obj;
  43. }
  44. /**
  45. * 更新一个.
  46. * @param mixed $id
  47. * @param array $setarr
  48. * @return mixed|array
  49. */
  50. public function updateOne($id, array $setarr)
  51. {
  52. $resultInfo = [
  53. 'is_ok' => true,
  54. 'old' => null,
  55. 'new' => null,
  56. ];
  57. $item = CategoryModel::query()->where(['id' => $id])->firstOrFail();
  58. $resultInfo['old'] = clone $item;
  59. if (isset($setarr['name'])) {
  60. $item->name = $setarr['name'];
  61. }
  62. if (isset($setarr['alias_name'])) {
  63. $item->alias_name = strtolower($setarr['alias_name']);
  64. }
  65. if (isset($setarr['position'])) {
  66. $item->position = strtolower($setarr['position']);
  67. }
  68. if (isset($setarr['squad'])) {
  69. $item->squad = $setarr['squad'];
  70. }
  71. if (isset($setarr['t_color'])) {
  72. $item->t_color = $setarr['t_color'];
  73. }
  74. if (isset($setarr['parent_id'])) {
  75. $item->parent_id = $setarr['parent_id'];
  76. }
  77. if (isset($setarr['cover_pic'])) {
  78. $item->cover_pic = $setarr['cover_pic'];
  79. }
  80. if (isset($setarr['show_num'])) {
  81. $item->show_num = $setarr['show_num'];
  82. }
  83. $result = $item->save();
  84. if ($result) {
  85. $resultInfo['new'] = $item;
  86. if ($resultInfo['old']->alias_name != $item->alias_name) {
  87. $this->clearCategoryCacheByAlias($resultInfo['old']->alias_name);
  88. $this->clearCategoryCacheByAlias($item->alias_name);
  89. } else {
  90. $this->clearCategoryCacheByAlias($resultInfo['old']->alias_name);
  91. }
  92. if ($resultInfo['old']->postion != $item->position) {
  93. $this->clearCategoryCacheByPosition($resultInfo['old']->position);
  94. $this->clearCategoryCacheByPosition($item->position);
  95. } else {
  96. $this->clearCategoryCacheByPosition($resultInfo['old']->position);
  97. }
  98. $this->clearVideoCacheByAlias($resultInfo['old']->alias_name);
  99. } else {
  100. $resultInfo['is_ok'] = false;
  101. }
  102. return $resultInfo;
  103. }
  104. /**
  105. * 删除一个.
  106. * @param mixed $id
  107. * @return bool|int|mixed|null
  108. * @throws mixed|array
  109. */
  110. public function deleteOne($id)
  111. {
  112. $resultInfo = [
  113. 'is_ok' => true,
  114. 'old' => null,
  115. 'new' => null,
  116. ];
  117. $item = CategoryModel::query()->where(['id' => $id])->firstOrFail();
  118. $resultInfo['old'] = clone $item;
  119. $result = $item->delete();
  120. if ($result) {
  121. $this->clearCategoryCacheByAlias($resultInfo['old']->alias_name);
  122. $this->clearCategoryCacheByPosition($resultInfo['old']->position);
  123. $this->clearVideoCacheByAlias($resultInfo['old']->alias_name);
  124. } else {
  125. $resultInfo['is_ok'] = false;
  126. }
  127. return $resultInfo;
  128. }
  129. /**
  130. * 删除多个.
  131. * @param mixed $ids
  132. * @return array
  133. * @throws \Psr\SimpleCache\InvalidArgumentException
  134. */
  135. public function deleteMulti($ids)
  136. {
  137. $result = [
  138. 'total' => 0,
  139. 'success_ids' => [],
  140. 'fail_ids' => [],
  141. ];
  142. $arrIds = $ids;
  143. if (is_string($ids)) {
  144. $arrIds = [$ids];
  145. }
  146. $result['total'] = count($arrIds);
  147. if (!empty($arrIds)) {
  148. foreach ($arrIds as $id) {
  149. $item = CategoryModel::query()->where(['id' => $id])->first();
  150. if ($item) {
  151. $oldItem = clone $item;
  152. if ($item->delete()) {
  153. $result['success_ids'][] = $id;
  154. $this->clearCategoryCacheByAlias($oldItem->alias_name);
  155. $this->clearCategoryCacheByPosition($oldItem->position);
  156. $this->clearVideoCacheByAlias($oldItem->alias_name);
  157. }
  158. unset($oldItem);
  159. } else {
  160. $result['fail_ids'][] = $id;
  161. }
  162. }
  163. }
  164. return $result;
  165. }
  166. /**
  167. * 获取视频.
  168. * @param $categoryAliasName
  169. * @param int $num
  170. * @param null $position
  171. * @return array|mixed
  172. * @throws \Psr\SimpleCache\InvalidArgumentException
  173. */
  174. public function getVideos($categoryAliasName, $num = 10, $position = null)
  175. {
  176. if ($num > 200) {
  177. $num = 200;
  178. }
  179. $flagPosition = $position;
  180. if (is_null($position)) {
  181. $flagPosition = 'nullnull';
  182. }
  183. $cacheRepo = make(CacheInterface::class);
  184. $cacheTime = 24 * 60 * 60;
  185. $cacheKey = 'category:video:'. $categoryAliasName;
  186. $arrData = $cacheRepo->get($cacheKey, []);
  187. if (empty($arrData)) {
  188. $where = [
  189. 'category_alias_name' => $categoryAliasName,
  190. ];
  191. if (!is_null($position)) {
  192. $where['position'] = $position;
  193. }
  194. $arrData = [];
  195. $columns = ['id', 'title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'mu', 'comment', 'watch', 'resolution', 'duration'];
  196. $strColumns = implode(',', $columns);
  197. $tempItems = VideoModel::query()->with(['category:type.id as type_id,type.title','user', 'perfect'])->whereHas('perfect', function ($q) use ($categoryAliasName) {
  198. $q->where(['category_alias_name' => $categoryAliasName]);
  199. })->orderByDesc('created_at')->orderByDesc('id')->take($num)->get($columns);
  200. if ($tempItems->count()) {
  201. $tempItems = $tempItems->toArray();
  202. foreach ($tempItems as $v) {
  203. $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
  204. if (!empty($v['user'])) {
  205. $v['user']['avatar'] = !empty($v['user']['avatar']) ? M3u8CacheRepository::getImageUrl($v['user']['avatar']) : '';
  206. }
  207. if (!empty($v['category'])) {
  208. foreach ($v['category'] as $ck => $t) {
  209. unset($v['category'][$ck]['pivot']);
  210. }
  211. }
  212. $v['mu'] = ''; // 列表干掉m3u8地址.
  213. unset($v['perfect']);
  214. $arrData[] = $v;
  215. }
  216. }
  217. if (!empty($arrData)) {
  218. $cacheRepo->set($cacheKey, $arrData, $cacheTime);
  219. }
  220. }
  221. return $arrData;
  222. }
  223. /**
  224. * 查1个
  225. * @param $aliasName
  226. * @param false $isForce
  227. * @return array|mixed
  228. * @throws \Psr\SimpleCache\InvalidArgumentException
  229. */
  230. public function findOneByAlias($aliasName, $isForce = false)
  231. {
  232. $cacheRepo = make(CacheInterface::class);
  233. $cacheTime = 24 * 60 * 60;
  234. $cacheKey = 'category:detail:alias_name:'. $aliasName;
  235. $data = $cacheRepo->get($cacheKey, []);
  236. if (empty($data) || $isForce == true) {
  237. $obj = CategoryModel::query()->where(['alias_name' => $aliasName])->first();
  238. if (!empty($obj->id)) {
  239. $data = $obj->toArray();
  240. $cacheRepo->set($cacheKey, $data, $cacheTime);
  241. }
  242. }
  243. return $data;
  244. }
  245. /**
  246. * 查1个
  247. * @param $position
  248. * @param false $isForce
  249. * @return array|mixed
  250. * @throws \Psr\SimpleCache\InvalidArgumentException
  251. */
  252. public function findAllByPosition($position, $isForce = false)
  253. {
  254. $cacheRepo = make(CacheInterface::class);
  255. $cacheTime = 24 * 60 * 60;
  256. $cacheKey = 'category:lists:position:'. $position;
  257. $data = $cacheRepo->get($cacheKey, []);
  258. if (empty($data) || $isForce == true) {
  259. $lists = CategoryModel::query()->where(['position' => $position])
  260. ->orderByDesc('squad')
  261. ->orderByDesc('id')
  262. ->get();
  263. if ($lists->isNotEmpty()) {
  264. $data = $lists->toArray();
  265. $cacheRepo->set($cacheKey, $data, $cacheTime);
  266. }
  267. }
  268. return $data;
  269. }
  270. /**
  271. * 清除分类缓存.
  272. * @param $aliasName
  273. * @return bool
  274. * @throws \Psr\SimpleCache\InvalidArgumentException
  275. */
  276. public function clearCategoryCacheByAlias($aliasName)
  277. {
  278. $cacheRepo = make(CacheInterface::class);
  279. $cacheKey = 'category:detail:alias_name:'. $aliasName;
  280. $cacheRepo->delete($cacheKey);
  281. return true;
  282. }
  283. /**
  284. * 清除视频缓存.
  285. * @param $aliasName
  286. * @return bool
  287. * @throws \Psr\SimpleCache\InvalidArgumentException
  288. */
  289. public function clearVideoCacheByAlias($aliasName)
  290. {
  291. $cacheRepo = make(CacheInterface::class);
  292. $cacheKey = 'category:video:'. $aliasName;
  293. $cacheRepo->delete($cacheKey);
  294. return true;
  295. }
  296. /**
  297. * @param $position
  298. * @return bool
  299. * @throws \Psr\SimpleCache\InvalidArgumentException
  300. */
  301. public function clearCategoryCacheByPosition($position)
  302. {
  303. $cacheRepo = make(CacheInterface::class);
  304. $cacheKey = 'category:lists:position:'. $position;
  305. $cacheRepo->delete($cacheKey);
  306. return true;
  307. }
  308. /**
  309. * 推送到视频.
  310. * @param $aliasName
  311. * @param $ids
  312. * @return array
  313. */
  314. public function pushPerfectVideo($aliasName, $ids)
  315. {
  316. $result = [
  317. 'total' => 0,
  318. 'success_ids' => [],
  319. 'fail_ids' => [],
  320. ];
  321. $result['total'] = count($ids);
  322. foreach ($ids as $videoId) {
  323. $obj = VideoPerfectModel::query()->where(['category_alias_name' => $aliasName, 'video_id' => $videoId])->first();
  324. if (empty($obj)) {
  325. $setarr = [
  326. 'video_id' => $videoId,
  327. 'category_alias_name' => $aliasName,
  328. ];
  329. $saveStatus = VideoPerfectModel::query()->create($setarr);
  330. if ($saveStatus) {
  331. $result['success_ids'][] = $videoId;
  332. } else {
  333. $result['fail_ids'][] = $videoId;
  334. }
  335. } else {
  336. $result['fail_ids'][] = $videoId;
  337. }
  338. }
  339. $info = $this->findOneByAlias($aliasName);
  340. if (!empty($info)) {
  341. $this->clearCategoryCacheByPosition($info['position']);
  342. }
  343. $this->clearVideoCacheByAlias($aliasName);
  344. // make(VideoRepository::class)->clearAllLastestPagesCache();
  345. return $result;
  346. }
  347. /**
  348. * 剔除桶.
  349. * @param $ids
  350. * @return array
  351. * @throws \Psr\SimpleCache\InvalidArgumentException
  352. */
  353. public function popPerfectVideo($ids)
  354. {
  355. $result = [
  356. 'total' => 0,
  357. 'success_ids' => [],
  358. 'fail_ids' => [],
  359. ];
  360. $result['total'] = count($ids);
  361. $arrAlias = [];
  362. $arrPosition = [];
  363. foreach ($ids as $id) {
  364. $obj = VideoPerfectModel::query()->where(['id' => $id])->first();
  365. if (!empty($obj)) {
  366. if (!in_array($obj->category_alias_name, $arrAlias)) {
  367. $arrAlias[] = $obj->category_alias_name;
  368. }
  369. if (!in_array($obj->position, $arrPosition)) {
  370. $arrPosition[] = $obj->position;
  371. }
  372. $delStatus = $obj->delete();
  373. if ($delStatus) {
  374. $result['success_ids'][] = $id;
  375. } else {
  376. $result['fail_ids'][] = $id;
  377. }
  378. } else {
  379. $result['fail_ids'][] = $id;
  380. }
  381. }
  382. if ($arrAlias) {
  383. foreach ($arrAlias as $aliasName) {
  384. $this->clearVideoCacheByAlias($aliasName);
  385. }
  386. }
  387. if ($arrPosition) {
  388. foreach ($arrPosition as $position) {
  389. $this->clearCategoryCacheByPosition($position);
  390. }
  391. }
  392. // make(VideoRepository::class)->clearAllLastestPagesCache();
  393. return $result;
  394. }
  395. /**
  396. * 获取所有导航列表
  397. *
  398. * @return void
  399. */
  400. public function allCategory($type)
  401. {
  402. $cache = make(CacheInterface::class);
  403. $res = $cache->rememberForever(CategoryConstant::ALL_CATEGORY . $type, function() use ($type) {
  404. $columns = ['id','name', 'alias_name', 'parent_id'];
  405. $categoryParentData = CategoryModel::query()->where('parent_id', 0)->where('type', $type)->orderByDesc('squad')->get($columns);
  406. foreach ($categoryParentData as &$v) {
  407. $v['sub'] = CategoryModel::query()->where('parent_id', $v->id)->orderByDesc('squad')->get($columns);
  408. }
  409. return $categoryParentData;
  410. });
  411. return $res;
  412. }
  413. /**
  414. * 获取标签
  415. *
  416. * @param [type] $isHot
  417. * @param [type] $type
  418. * @return void
  419. */
  420. public function getTag($type, $isHot)
  421. {
  422. $cache = make(CacheInterface::class);
  423. $res = $cache->rememberForever(CategoryConstant::TAG_TYPE . $type . $isHot,function() use ($isHot, $type) {
  424. $query = TypeModel::query();
  425. if (!empty($isHot)) {
  426. $query = $query->where('is_hot', $isHot)->take(10);
  427. }
  428. $columns = ['id','title', 'cover', 'is_hot', 'description'];
  429. $data = $query->where(['type' => $type, 'status' => 1])->orderByDesc('sort')->orderByDesc('is_hot')->get($columns);
  430. foreach ($data as &$v) {
  431. $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
  432. }
  433. return $data;
  434. });
  435. return $res;
  436. }
  437. }