Special.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\wap\model\special;
  12. use app\wap\model\special\SpecialSource;
  13. use app\wap\model\store\StoreOrder;
  14. use app\wap\model\store\StorePink;
  15. use app\wap\model\user\User;
  16. use basic\ModelBasic;
  17. use service\SystemConfigService;
  18. use think\Url;
  19. use traits\ModelTrait;
  20. use think\Db;
  21. use app\wap\model\live\LiveStudio;
  22. use app\wap\model\live\LivePlayback;
  23. use app\wap\model\special\LearningRecords;
  24. use app\wap\model\special\SpecialSubject;
  25. use app\wap\model\material\DataDownload;
  26. /**专题 model
  27. * Class Special
  28. * @package app\wap\model\special
  29. */
  30. class Special extends ModelBasic
  31. {
  32. use ModelTrait;
  33. public function profile()
  34. {
  35. return $this->hasOne('SpecialContent', 'special_id', 'id')->field('content,is_try,try_content');
  36. }
  37. public function singleProfile()
  38. {
  39. return $this->hasOne('SpecialContent', 'special_id', 'id')->field('link,videoId,is_try,try_time,try_content');
  40. }
  41. //动态赋值
  42. public static function getPinkStrarTimeAttr($value)
  43. {
  44. return $value ? date('Y-m-d H:i:s', $value) : '';
  45. }
  46. public static function getPinkEndTimeAttr($value)
  47. {
  48. return $value ? date('Y-m-d H:i:s', $value) : '';
  49. }
  50. public static function getAddTimeAttr($value)
  51. {
  52. return date('Y-m-d H:i:s', $value);
  53. }
  54. public static function getBannerAttr($value)
  55. {
  56. return is_string($value) ? json_decode($value, true) : $value;
  57. }
  58. public static function getLabelAttr($value)
  59. {
  60. return is_string($value) ? json_decode($value, true) : $value;
  61. }
  62. /**
  63. * 设置专题显示条件
  64. * @param string $alias 别名
  65. * @param null $model model
  66. * @param bool $isAL 是否起别名,默认执行
  67. * @return $this
  68. */
  69. public static function PreWhere($alias = '', $model = null, $isAL = false)
  70. {
  71. self::setPinkSpecial();
  72. if (is_null($model)) $model = new self();
  73. if ($alias) {
  74. $isAL || $model = $model->alias($alias);
  75. $alias .= '.';
  76. }
  77. return $model->where(["{$alias}is_del" => 0, "{$alias}is_show" => 1, "{$alias}status" => 1]);
  78. }
  79. /**
  80. * 获取拼团详情页的专题详情和分享连接
  81. * @param string $order_id 订单id
  82. * @param int $pinkId 当前拼团id
  83. * @param int $uid 当前用户id
  84. * @return array
  85. * */
  86. public static function getPinkSpecialInfo($order_id, $pinkId, $uid)
  87. {
  88. $special = self::PreWhere()->where('id', StoreOrder::where('order_id', $order_id)->value('cart_id'))
  89. ->field(['image', 'title', 'abstract', 'money', 'label', 'id', 'is_light', 'light_type', 'is_mer_visible', 'is_pink', 'pink_money'])->find();
  90. if (!$special) return [];
  91. $special['image'] = get_oss_process($special['image'], 4);
  92. if ($special['is_light']) {
  93. $special['link'] = SystemConfigService::get('site_url') . Url::build('special/single_details') . '?id=' . $special['id'] . '&pinkId=' . $pinkId . '&partake=1#partake';
  94. } else {
  95. $special['link'] = SystemConfigService::get('site_url') . Url::build('special/details') . '?id=' . $special['id'] . '&pinkId=' . $pinkId . '&partake=1#partake';
  96. }
  97. $special['abstract'] = self::HtmlToMbStr($special['abstract']);
  98. return $special;
  99. }
  100. /**
  101. * 设置拼团到时间的专题
  102. * */
  103. public static function setPinkSpecial()
  104. {
  105. self::where('pink_strar_time', '<', time())->where('pink_end_time', '<', time())->update([
  106. 'is_pink' => 0,
  107. 'pink_strar_time' => 0,
  108. 'pink_end_time' => 0
  109. ]);
  110. }
  111. /**
  112. * 获取单个专题的详细信息,拼团信息,拼团用户信息
  113. * @param $uid 用户id
  114. * @param $id 专题id
  115. * @param $pinkId 拼团id
  116. * */
  117. public static function getOneSpecial($uid, $id)
  118. {
  119. $special = self::PreWhere()->where('is_light', 0)->find($id);
  120. if (!$special) return self::setErrorInfo('您要查看的专题不存在!');
  121. if ($special->is_show == 0) return self::setErrorInfo('您要查看的专题已下架!');
  122. $title = $special->title;
  123. if ($uid) {
  124. $special->collect = self::getDb('special_relation')->where(['link_id' => $id, 'type' => 0, 'uid' => $uid, 'category' => 1])->count() ? true : false;
  125. } else {
  126. $special->collect = false;
  127. }
  128. $special->content = htmlspecialchars_decode($special->profile->content);
  129. $special->profile->content = '';
  130. $swiperlist = json_encode($special->banner);
  131. $special = json_encode($special->toArray());
  132. return compact('swiperlist', 'special', 'title');
  133. }
  134. /**获取单个轻专题
  135. * @param $uid
  136. * @param $id
  137. * @return array|bool
  138. * @throws \think\Exception
  139. * @throws \think\db\exception\DataNotFoundException
  140. * @throws \think\db\exception\ModelNotFoundException
  141. * @throws \think\exception\DbException
  142. */
  143. public static function getSingleOneSpecial($uid, $id)
  144. {
  145. $special = self::PreWhere()->where('is_light', 1)->find($id);
  146. if (!$special) return self::setErrorInfo('您要查看的专题不存在!');
  147. if ($special->is_show == 0) return self::setErrorInfo('您要查看的专题已下架!');
  148. $title = $special->title;
  149. $special->abstract = htmlspecialchars_decode($special->abstract);
  150. if ($uid) {
  151. $special->collect = self::getDb('special_relation')->where(['link_id' => $id, 'type' => 0, 'uid' => $uid, 'category' => 1])->count() ? true : false;
  152. } else {
  153. $special->collect = false;
  154. }
  155. $special->profile = $special->profile;
  156. $special = json_encode($special->toArray());
  157. return compact('special', 'title');
  158. }
  159. /**获取轻专题内容
  160. * @param $id
  161. * @return array|bool
  162. * @throws \think\Exception
  163. * @throws \think\db\exception\DataNotFoundException
  164. * @throws \think\db\exception\ModelNotFoundException
  165. * @throws \think\exception\DbException
  166. */
  167. public static function getSingleImgSpecialContent($id)
  168. {
  169. $special = self::PreWhere()->where('is_light', 1)->find($id);
  170. if (!$special) return self::setErrorInfo('您要查看的专题不存在!');
  171. if ($special->is_show == 0) return self::setErrorInfo('您要查看的专题已下架!');
  172. $data['title'] = $special->title;
  173. $data['money'] = $special->money;
  174. $data['pay_type'] = $special->pay_type;
  175. $data['member_money'] = $special->member_money;
  176. $data['member_pay_type'] = $special->member_pay_type;
  177. $data['image'] = $special->image;
  178. $data['profile'] = $special->profile;
  179. $data['content'] = htmlspecialchars_decode($special->profile->content);
  180. unset($special['profile']['content']);
  181. return $data;
  182. }
  183. /**获取轻专题内容
  184. * @param $id
  185. * @return array|bool
  186. * @throws \think\Exception
  187. * @throws \think\db\exception\DataNotFoundException
  188. * @throws \think\db\exception\ModelNotFoundException
  189. * @throws \think\exception\DbException
  190. */
  191. public static function getSingleSpecialContent($id)
  192. {
  193. $special = self::PreWhere()->where('is_light', 1)->find($id);
  194. if (!$special) return self::setErrorInfo('您要查看的专题不存在!');
  195. if ($special->is_show == 0) return self::setErrorInfo('您要查看的专题已下架!');
  196. $data['title'] = $special->title;
  197. $data['abstract'] = $special->abstract;
  198. $data['light_type'] = $special->light_type;
  199. $data['image'] = $special->image;
  200. $data['money'] = $special->money;
  201. $data['pay_type'] = $special->pay_type;
  202. $data['member_money'] = $special->member_money;
  203. $data['member_pay_type'] = $special->member_pay_type;
  204. $data['singleProfile'] = $special->singleProfile;
  205. return $data;
  206. }
  207. /**
  208. * 我的课程
  209. * @param int $active 1=购买的课程,0=赠送的课程
  210. * @param int $page 页码
  211. * @param int $limit 每页显示条数
  212. * @param int $uid 用户uid
  213. * @return array
  214. * */
  215. public static function getMyGradeList($page, $limit, $uid, $is_member, $active = 0)
  216. {
  217. $model = self::PreWhere('a')->join('SpecialBuy s', 'a.id=s.special_id')->where('s.is_del', 0)->group('s.special_id')
  218. ->order('a.sort desc,s.add_time desc');
  219. $list = $model->field('a.*,a.type as types,s.*')->page($page, $limit)->select();
  220. $list = count($list) > 0 ? $list->toArray() : [];
  221. foreach ($list as &$item) {
  222. $item['image'] = get_oss_process($item['image'], 4);
  223. if (is_string($item['label'])) $item['label'] = json_decode($item['label'], true);
  224. $id = $item['special_id'];
  225. $item['s_id'] = $id;
  226. $item['count'] = self::numberChapters($item['types'], $item['s_id']);
  227. if ($item['is_light']) {
  228. $item['type'] = self::lightType($item['light_type']);
  229. }
  230. }
  231. $page += 1;
  232. return compact('list', 'page');
  233. }
  234. /**
  235. * 我的收藏
  236. * @param int $type 1=收藏,0=我的购买
  237. * @param int $page 页码
  238. * @param int $limit 每页显示条数
  239. * @param int $uid 用户uid
  240. * @return array
  241. * */
  242. public static function getGradeList($page, $limit, $uid, $is_member, $active = 0)
  243. {
  244. if ($active) {
  245. $model = DataDownload::PreWhere('a')->where('s.uid', $uid)->where('s.type', 1)->join('__SPECIAL_RELATION__ s', 'a.id=s.link_id');
  246. $list = $model->order('a.sort desc')->field('a.*')->page($page, $limit)->select();
  247. } else {
  248. $model = self::PreWhere('a')->where('s.uid', $uid)->where('s.type', 0)->join('__SPECIAL_RELATION__ s', 'a.id=s.link_id');
  249. if (!$is_member) $model = $model->where(['a.is_mer_visible' => 0]);
  250. $list = $model->order('a.sort desc')->field('a.*,a.type as types')->page($page, $limit)->select();
  251. }
  252. $list = count($list) > 0 ? $list->toArray() : [];
  253. foreach ($list as &$item) {
  254. if (!$active) {
  255. $item['image'] = get_oss_process($item['image'], 4);
  256. if (is_string($item['label'])) $item['label'] = json_decode($item['label'], true);
  257. $id = $item['id'];
  258. $item['s_id'] = $id;
  259. $item['count'] = self::numberChapters($item['types'], $item['s_id']);
  260. if ($item['is_light']) {
  261. $item['type'] = self::lightType($item['light_type']);
  262. }
  263. }
  264. }
  265. $page += 1;
  266. return compact('list', 'page');
  267. }
  268. /**
  269. * 获取某个专题的详细信息
  270. * @param int $id 专题id
  271. * @return array
  272. * */
  273. public static function getSpecialInfo($id)
  274. {
  275. $special = self::PreWhere()->find($id);
  276. if (!$special) return self::setErrorInfo('没有找到此专题');
  277. $special->abstract = self::HtmlToMbStr($special->abstract);
  278. return $special->toArray();
  279. }
  280. /**
  281. * 获取推广专题列表
  282. * @param array $where 查询条件
  283. * @param int $uid 用户uid
  284. * @return array
  285. * */
  286. public static function getSpecialSpread($where, $is_member)
  287. {
  288. $store_brokerage_ratio = SystemConfigService::get('store_brokerage_ratio');
  289. $store_brokerage_ratio = bcdiv($store_brokerage_ratio, 100, 2);
  290. $ids = SpecialSubject::where('a.is_show', 1)->alias('a')->join('__SPECIAL__ s', 's.subject_id=a.id')->column('a.id');
  291. $subjectIds = [];
  292. foreach ($ids as $item) {
  293. if (self::PreWhere()->where('subject_id', $item)->count()) array_push($subjectIds, $item);
  294. }
  295. $model = SpecialSubject::where('is_show', 1)->order('sort desc')->field('id,name');
  296. if ($where['grade_id']) $model = $model->where('grade_id', $where['grade_id']);
  297. $list = $model->where('id', 'in', $subjectIds)->page((int)$where['page'], (int)$where['limit'])->select();
  298. $data = count($list) ? $list->toArray() : [];
  299. foreach ($data as &$item) {
  300. $itm = self::PreWhere()->where('subject_id', $item['id'])->field(['image', 'id', 'is_mer_visible', 'title', 'money']);
  301. if (!$is_member) $itm = $itm->where(['is_mer_visible' => 0]);
  302. $item['list'] = $itm->order('sort desc')->select();
  303. if (count($item['list'])) $item['list'] = $item['list']->toArray();
  304. foreach ($item['list'] as &$value) {
  305. $value['image'] = get_oss_process($value['image'], 4);
  306. if ($value['money'] > 0) $value['spread_money'] = bcmul($value['money'], $store_brokerage_ratio, 2);
  307. else $value['spread_money'] = 0;
  308. }
  309. }
  310. $page = (int)$where['page'] + 1;
  311. return compact('data', 'page');
  312. }
  313. /**
  314. * 设置查询条件
  315. * @param $where
  316. * @return $this
  317. */
  318. public static function setWhere($where)
  319. {
  320. if ($where['type']) {
  321. $model = self::PreWhere('a');
  322. if ($where['subject_id'] && $where['grade_id']) {
  323. $model = $model->where('a.subject_id', $where['subject_id']);
  324. }
  325. if ($where['search']) {
  326. $model = $model->where('a.title', 'LIKE', "%$where[search]%");
  327. }
  328. if (!$where['is_member']) $model = $model->where(['a.is_mer_visible' => 0]);
  329. return $model->order('a.sort desc,a.id desc')
  330. ->join('special_record r', 'r.special_id = a.id')
  331. ->group('a.id')->where('uid', $where['uid']);
  332. } else {
  333. $model = self::PreWhere();
  334. if ($where['grade_id'] == 64) {
  335. if ($where['subject_id'] == 65) {
  336. $model = $model->where('isnew', 1);
  337. } elseif ($where['subject_id'] == 66) {
  338. $model = $model->where('ishot', 1);
  339. } else {
  340. $model = $model->where('ishot|isnew', 1);
  341. }
  342. } else {
  343. if ($where['subject_id'] && $where['grade_id'] > 0) {
  344. $model = $model->where('subject_id', $where['subject_id']);
  345. } else if ($where['subject_id'] == 0 && $where['grade_id'] > 0) {
  346. $subject_ids = SpecialSubject::subjectId($where['grade_id']);
  347. $model = $model->where('subject_id', 'in', $subject_ids);
  348. }
  349. }
  350. if ($where['search']) {
  351. $model = $model->where('title|abstract', 'LIKE', "%$where[search]%");
  352. }
  353. if (!$where['is_member']) $model = $model->where(['is_mer_visible' => 0]);
  354. return $model->order('sort desc,id desc');
  355. }
  356. }
  357. /**
  358. * 获取专题列表
  359. * @param $where
  360. * @return mixed
  361. */
  362. public static function getSpecialList($where)
  363. {
  364. if ($where['type']) {
  365. $alias = 'a.';
  366. $field = [$alias . 'id', $alias . 'fake_sales', $alias . 'browse_count', $alias . 'image', $alias . 'is_light', $alias . 'light_type', $alias . 'is_mer_visible', $alias . 'title', $alias . 'type', $alias . 'money', $alias . 'pink_money', $alias . 'is_pink', $alias . 'subject_id', $alias . 'label', 'r.number'];
  367. } else {
  368. $field = ['browse_count', 'image', 'title', 'type', 'is_light', 'light_type', 'is_mer_visible', 'money', 'pink_money', 'is_pink', 'subject_id', 'label', 'id', 'fake_sales'];
  369. }
  370. $list = self::setWhere($where)
  371. ->field($field)
  372. ->page($where['page'], $where['limit'])
  373. ->select();
  374. $list = count($list) ? $list->toArray() : [];
  375. foreach ($list as &$item) {
  376. $item['count'] = self::numberChapters($item['type'], $item['id']);
  377. $count = self::learning_records($item['id']);
  378. $item['browse_count'] = processingData(bcadd($count, $item['fake_sales'], 0));
  379. if ($item['is_light']) {
  380. $item['type'] = self::lightType($item['light_type']);
  381. }
  382. }
  383. return $list;
  384. }
  385. /**讲师名下课程
  386. * @return array
  387. * @throws \think\db\exception\DataNotFoundException
  388. * @throws \think\db\exception\ModelNotFoundException
  389. * @throws \think\exception\DbException
  390. */
  391. public static function getLecturerSpecialList($mer_id = 0, $page = 1, $limit = 10, $id= 0)
  392. {
  393. if ($mer_id || $id) {
  394. $field = ['browse_count', 'image', 'title', 'type', 'money', 'pink_money', 'is_light', 'light_type', 'is_mer_visible', 'is_pink', 'subject_id', 'label', 'id', 'is_show', 'is_del', 'lecturer_id', 'mer_id'];
  395. $model = self::PreWhere();
  396. if ($id) {
  397. $model = $model->where(['lecturer_id' => $id])->order('sort desc,id desc');
  398. } else {
  399. $model = $model->where(['mer_id' => $mer_id])->order('sort desc,id desc');
  400. }
  401. $list = $model->field($field)->page($page, $limit)->select();
  402. $list = count($list) ? $list->toArray() : [];
  403. } else {
  404. $list = [];
  405. }
  406. return $list;
  407. }
  408. /**拼团专题
  409. * @param int $page
  410. * @param int $limit
  411. */
  412. public static function getPinkSpecialList($page = 1, $limit = 10)
  413. {
  414. $field = ['browse_count', 'image', 'is_light', 'light_type', 'is_mer_visible', 'title', 'type', 'money', 'pink_money', 'is_pink', 'subject_id', 'label', 'id', 'is_show', 'is_del', 'lecturer_id', 'pink_number'];
  415. $model = self::PreWhere();
  416. $model = $model->where(['is_pink' => 1])->order('sort desc,id desc');
  417. $list = $model->field($field)->page($page, $limit)->select();
  418. $list = count($list) ? $list->toArray() : [];
  419. foreach ($list as &$item) {
  420. $item['count'] = StorePink::where(['status' => 2, 'cid' => $item['id']])->count();
  421. }
  422. return $list;
  423. }
  424. /**专题下章节数量
  425. * @param int $type
  426. * @param int $id
  427. * @return int|string
  428. * @throws \think\Exception
  429. * @throws \think\db\exception\DataNotFoundException
  430. * @throws \think\db\exception\ModelNotFoundException
  431. * @throws \think\exception\DbException
  432. */
  433. public static function numberChapters($type = 0, $id = 0)
  434. {
  435. $count = 0;
  436. if ($type != 5 && $type != 4) {
  437. $specialSourceId = SpecialSource::getSpecialSource($id);
  438. if ($specialSourceId) $count = count($specialSourceId);
  439. } else if ($type == 5) {
  440. $specialSourceId = SpecialSource::getSpecialSource($id);
  441. if (count($specialSourceId)) {
  442. $specialSource = $specialSourceId->toArray();
  443. foreach ($specialSource as $key => $value) {
  444. $specialSourcetaskId = SpecialSource::getSpecialSource($value['source_id']);
  445. if (count($specialSourcetaskId) == 0) {
  446. $is_light = self::PreWhere()->where('id', $value['source_id'])->value('is_light');
  447. if ($is_light) {
  448. $count = bcadd($count, 1, 0);
  449. }
  450. } else {
  451. $count = bcadd($count, count($specialSourcetaskId), 0);
  452. }
  453. }
  454. }
  455. $count = (int)$count;
  456. } else if ($type == 4) {
  457. $liveStudio = LiveStudio::where(['special_id' => $id])->find();
  458. if (!$liveStudio) return $count = 0;
  459. if (!$liveStudio['stream_name']) return $count = 0;
  460. if ($liveStudio['is_playback'] == 1) {
  461. $where['stream_name'] = $liveStudio['stream_name'];
  462. $where['start_time'] = '';
  463. $where['end_time'] = '';
  464. $count = LivePlayback::setUserWhere($where)->count();
  465. }
  466. }
  467. return $count;
  468. }
  469. /**轻专题 类型
  470. * @param $light_type
  471. * @return int
  472. */
  473. public static function lightType($light_type)
  474. {
  475. switch ($light_type) {
  476. case 1:
  477. $type = 1;
  478. break;
  479. case 2:
  480. $type = 2;
  481. break;
  482. case 3:
  483. $type = 3;
  484. break;
  485. }
  486. return $type;
  487. }
  488. /**获得专题真实学习人数
  489. * @param int $special_id
  490. * @return int
  491. */
  492. public static function learning_records($special_id = 0)
  493. {
  494. $uids = LearningRecords::where(['special_id' => $special_id])->column('uid');
  495. $uids = array_unique($uids);
  496. return count($uids);
  497. }
  498. /**
  499. * 获取单独分销设置
  500. */
  501. public static function getIndividualDistributionSettings($id = 0)
  502. {
  503. $data = self::where('id', $id)->field('is_alone,brokerage_ratio,brokerage_two')->find();
  504. if ($data) return $data;
  505. else return [];
  506. }
  507. }