AliyunLive.php 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173
  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\merchant\controller\live;
  12. use app\merchant\controller\AuthController;
  13. use app\merchant\model\live\LiveGoods;
  14. use app\merchant\model\live\LiveGift;
  15. use app\merchant\model\live\LiveReward;
  16. use app\merchant\model\order\StoreOrder as StoreOrderModel;
  17. use app\merchant\model\live\LiveBarrage;
  18. use app\merchant\model\live\LiveHonouredGuest;
  19. use app\merchant\model\live\LiveStudio;
  20. use app\merchant\model\live\LiveUser;
  21. use app\merchant\model\live\LiveAudit;
  22. use app\merchant\model\live\LivePlayback;
  23. use app\merchant\model\special\Special as SpecialModel;
  24. use app\merchant\model\special\SpecialSubject;
  25. use app\merchant\model\special\SpecialTask;
  26. use app\merchant\model\user\User;
  27. use app\merchant\model\merchant\MerchantBill;
  28. use app\wap\model\user\WechatUser;
  29. use service\JsonService as Json;
  30. use service\SystemConfigService;
  31. use service\WechatTemplateService;
  32. use think\Exception;
  33. use service\FormBuilder as Form;
  34. use Api\AliyunLive as ApiAliyunLive;
  35. use think\Session;
  36. use think\Url;
  37. use \GatewayWorker\Lib\Gateway;
  38. use app\wap\model\routine\RoutineTemplate;
  39. use app\wap\model\wap\SmsTemplate;
  40. use app\merchant\model\merchant\Merchant;
  41. use app\index\controller\PushJob;
  42. /**直播
  43. * Class AliyunLive
  44. * @package app\admin\controller\live
  45. */
  46. class AliyunLive extends AuthController
  47. {
  48. /**
  49. * 阿里云直播句柄
  50. * @var \Api\AliyunLive
  51. */
  52. protected $aliyunLive;
  53. protected function _initialize()
  54. {
  55. parent::_initialize();
  56. $this->aliyunLive = \Api\AliyunLive::instance([
  57. 'AccessKey' => SystemConfigService::get('accessKeyId'),
  58. 'AccessKeySecret' => SystemConfigService::get('accessKeySecret'),
  59. 'OssEndpoint' => SystemConfigService::get('aliyun_live_end_point'),
  60. 'OssBucket' => SystemConfigService::get('aliyun_live_oss_bucket'),
  61. 'appName' => SystemConfigService::get('aliyun_live_appName'),
  62. 'payKey' => SystemConfigService::get('aliyun_live_play_key'),
  63. 'key' => SystemConfigService::get('aliyun_live_push_key'),
  64. 'playLike' => SystemConfigService::get('aliyun_live_playLike'),
  65. 'rtmpLink' => SystemConfigService::get('aliyun_live_rtmpLink'),
  66. ]);
  67. }
  68. /**
  69. * 直播间管理
  70. * */
  71. public function index()
  72. {
  73. $this->assign([
  74. 'special_list' => SpecialModel::where('type', SPECIAL_LIVE)->where(['is_del' => 0])->field(['id', 'title'])->select()->toArray(),
  75. 'type' => $this->request->param('type', 1),
  76. ]);
  77. return $this->fetch();
  78. }
  79. /**
  80. * 快速设置直播的某个字段的值
  81. * @param string $field 键值
  82. * @param string $value 值
  83. * @param int $id 直播id
  84. * @return json
  85. * */
  86. public function set_live_value($field = '', $value = '', $id = 0)
  87. {
  88. if (!$field || !$id) return Json::fail('缺少参数');
  89. $value = str_replace('免密', '', $value);
  90. $res = parent::getDataModification('studio', $id, $field, $value);
  91. if ($res)
  92. return Json::successful('修改成功');
  93. else
  94. return Json::fail('修改失败');
  95. }
  96. /**
  97. * 编辑直播间
  98. * */
  99. public function update_live($id = 0)
  100. {
  101. if (!$id) return $this->failed('缺少参数');
  102. $liveInfo = LiveStudio::get($id);
  103. if (!$liveInfo) return $this->failed('未查到直播间信息');
  104. $f[] = Form::input('stream_name', '直播间号:', $liveInfo->getData('stream_name'))->disabled(true);
  105. $f[] = Form::input('live_title', '直播间标题:', $liveInfo->getData('live_title'));
  106. $f[] = Form::frameImageOne('live_image', '直播封面:', Url::build('admin/widget.images/index', array('fodder' => 'live_image')), $liveInfo->getData('live_image'))->icon('image')->width('100%')->height('500px');
  107. $f[] = Form::textarea('live_introduction', '直播间简介:', $liveInfo->getData('live_introduction'));
  108. $f[] = Form::number('online_num', '虚拟在线人数:', $liveInfo->getData('online_num'))->min(0);
  109. $f[] = Form::number('sort', '排序', $liveInfo->getData('sort'))->min(0);
  110. $f[] = Form::radio('is_remind', '开播提醒:', $liveInfo->getData('is_remind'))->options([
  111. ['value' => 1, 'label' => '是'],
  112. ['value' => 0, 'label' => '否'],
  113. ]);
  114. $f[] = Form::number('remind_time', '开播前提醒时间(分):', $liveInfo->getData('remind_time'));
  115. $f[] = Form::radio('is_recording', '自动录制:', $liveInfo->getData('is_recording'))->options([
  116. ['value' => 1, 'label' => '是'],
  117. ['value' => 0, 'label' => '否'],
  118. ]);
  119. $f[] = Form::radio('is_playback', '回放:', $liveInfo->getData('is_playback'))->options([
  120. ['value' => 1, 'label' => '是'],
  121. ['value' => 0, 'label' => '否'],
  122. ]);
  123. $form = Form::make_post_form('修改直播间', $f, Url::build('save_live', array('id' => $id)), 2);
  124. $this->assign(compact('form'));
  125. return $this->fetch('public/form-builder');
  126. }
  127. /**
  128. * 修改直播间
  129. * @param int $id
  130. * @return json
  131. * */
  132. public function save_live($id = 0)
  133. {
  134. if (!$id) return Json::fail('缺少参数');
  135. $data = parent::postMore([
  136. ['live_title', ''],
  137. ['live_image', ''],
  138. ['live_introduction', ''],
  139. ['online_num', 0],
  140. ['sort', 0],
  141. ['is_remind', 0],
  142. ['remind_time', 0],
  143. ['is_recording', 0],
  144. ['is_playback', 0],
  145. ]);
  146. if (!$data['live_title']) return Json::fail('直播间标题不能为空');
  147. if (!$data['live_introduction']) return Json::fail('直播间简介不能为空');
  148. if ($data['is_remind'] && !$data['remind_time']) return Json::fail('请输入直播前提醒时间!');
  149. if (LiveStudio::edit($data, $id))
  150. return Json::successful('修改成功');
  151. else
  152. return Json::fail('修改失败或者您没有修改内容');
  153. }
  154. /**
  155. * 直播间用户管理
  156. * @param int $id
  157. * */
  158. public function live_user($id = 0)
  159. {
  160. if (!$id) return $this->failed('缺少参数');
  161. $liveInfo = LiveStudio::get($id);
  162. if (!$liveInfo) return $this->failed('未查到直播间');
  163. $this->assign([
  164. 'stream_name' => $liveInfo->stream_name,
  165. 'live_id' => $id
  166. ]);
  167. return $this->fetch();
  168. }
  169. /**
  170. * 获取直播间用户列表
  171. * */
  172. public function get_live_user_list()
  173. {
  174. $where = parent::getMore([
  175. ['live_id', 0],
  176. ['page', 0],
  177. ['limit', 20],
  178. ['nickname', ''],
  179. ['start_time', ''],
  180. ['end_time', ''],
  181. ]);
  182. if (!$where['live_id']) return Json::fail('缺少参数');
  183. return Json::successlayui(LiveUser::getLiveUserList($where));
  184. }
  185. /**
  186. * 设置直播用户
  187. * @param string $field
  188. * @param string $id
  189. * @param string $value
  190. */
  191. public function set_live_user_value($field = '', $id = '', $value = '')
  192. {
  193. if (!$field || !$id) return Json::fail('缺少参数');
  194. $res = parent::getDataModification('live_user', $id, $field, $value);
  195. if ($res)
  196. return Json::successful('修改成功');
  197. else
  198. return Json::fail('修改失败');
  199. }
  200. /**礼物
  201. * @param string $field
  202. * @param string $id
  203. * @param string $value
  204. */
  205. public function set_live_gift_value($field = '', $id = '', $value = '')
  206. {
  207. if (!$field || !$id) return Json::fail('缺少参数');
  208. $res = parent::getDataModification('live_gift', $id, $field, $value);
  209. if ($res)
  210. return Json::successful('修改成功');
  211. else
  212. return Json::fail('修改失败');
  213. }
  214. /**
  215. * 禁止发言
  216. */
  217. public function live_no_speaking($id)
  218. {
  219. if (!$id) return $this->failed('缺少参数');
  220. $liveInfo = LiveUser::get($id);
  221. if (!$liveInfo) return $this->failed('未查到直播间信息');
  222. $f[] = Form::radio('is_ban', '是否禁言', $liveInfo->getData('is_ban'))->options([
  223. ['value' => 1, 'label' => '是'],
  224. ['value' => 0, 'label' => '否'],
  225. ]);
  226. $f[] = Form::number('ban_time', '禁言时间:分');
  227. $form = Form::make_post_form('禁止发言', $f, Url::build('save_no_speaking', array('id' => $id)), 2);
  228. $this->assign(compact('form'));
  229. return $this->fetch('public/form-builder');
  230. }
  231. public function save_no_speaking($id = 0)
  232. {
  233. if (!$id) return Json::fail('缺少参数');
  234. $data = parent::postMore([
  235. ['is_ban', 0],
  236. ['ban_time', 0]
  237. ]);
  238. if ($data['is_ban']) {
  239. $workerman = \think\Config::get('workerman.channel', []);
  240. Gateway::$registerAddress = $workerman['ip'] . ':' . $workerman['port'];
  241. $uid = LiveUser::where('id', $id)->value('uid');
  242. if (Gateway::isUidOnline($uid)) {
  243. Gateway::sendToUid($uid, json_encode([
  244. 'type' => 'ban',
  245. 'value' => 1
  246. ]));
  247. }
  248. }
  249. if ($data['is_ban'] && $data['ban_time'] <= 0) return Json::fail('请输入禁言时间');
  250. $data['ban_time'] = bcadd(time(), bcmul($data['ban_time'], 60, 0), 0);
  251. if (LiveUser::edit($data, $id)) {
  252. return Json::successful('修改成功');
  253. } else {
  254. return Json::fail('修改失败');
  255. }
  256. }
  257. /**
  258. * 禁止进入
  259. */
  260. public function live_no_entry($id)
  261. {
  262. if (!$id) return $this->failed('缺少参数');
  263. $liveInfo = LiveUser::get($id);
  264. if (!$liveInfo) return $this->failed('未查到直播间信息');
  265. $f[] = Form::radio('is_open_ben', '是否禁止进入直播间', $liveInfo->getData('is_open_ben'))->options([
  266. ['value' => 1, 'label' => '是'],
  267. ['value' => 0, 'label' => '否'],
  268. ]);
  269. $f[] = Form::number('open_ben_time', '禁止时间:分');
  270. $form = Form::make_post_form('禁止进入', $f, Url::build('save_no_entry', array('id' => $id)), 2);
  271. $this->assign(compact('form'));
  272. return $this->fetch('public/form-builder');
  273. }
  274. public function save_no_entry($id = 0)
  275. {
  276. if (!$id) return Json::fail('缺少参数');
  277. $data = parent::postMore([
  278. ['is_open_ben', 0],
  279. ['open_ben_time', 0]
  280. ]);
  281. if ($data['is_open_ben'] && $data['open_ben_time'] <= 0) return Json::fail('请输入禁止时间');
  282. $data['open_ben_time'] = bcadd(time(), bcmul($data['open_ben_time'], 60, 0), 0);
  283. if (LiveUser::edit($data, $id)) {
  284. return Json::successful('修改成功');
  285. } else {
  286. return Json::fail('修改失败');
  287. }
  288. }
  289. /**
  290. * 直播间管理
  291. */
  292. public function get_live_list()
  293. {
  294. $where = parent::getMore([
  295. ['stream_name', ''],
  296. ['start_time', ''],
  297. ['end_time', ''],
  298. ['page', 1],
  299. ['limit', 20],
  300. ['special_id', 0],
  301. ]);
  302. $where['mer_id'] = $this->merchantId;
  303. return Json::successlayui(LiveStudio::getLiveList($where));
  304. }
  305. /**
  306. * 直播专题列表
  307. * @param int $subject_id
  308. * @return mixed
  309. */
  310. public function special_live()
  311. {
  312. $special_type = $this->request->param("special_type");
  313. if (!$special_type || !is_numeric($special_type)) return $this->failed('专题类型参数缺失');
  314. $subjectlist = SpecialSubject::specialCategoryAll();
  315. $this->assign([
  316. 'type' => 1,
  317. 'special_type' => $special_type,
  318. 'special_title' => SPECIAL_TYPE[$special_type],
  319. 'subject_list' => $subjectlist,
  320. 'is_live' => 1,
  321. ]);
  322. return $this->fetch();
  323. }
  324. /**
  325. * 获取直播推流地址
  326. * @param int $id
  327. * @throws \think\db\exception\DataNotFoundException
  328. * @throws \think\db\exception\ModelNotFoundException
  329. * @throws \think\exception\DbException
  330. */
  331. public function go_live($id = 0)
  332. {
  333. if (!$id) return Json::fail('缺少参数');
  334. $specialInfo = SpecialModel::get($id);
  335. if (!$specialInfo) return Json::fail('直播专题暂未查到');
  336. if ($specialInfo->type != SPECIAL_LIVE) return Json::fail('此专题不授予直播专题,无法获取推流地址!');
  337. $liveInfo = LiveStudio::where('special_id', $specialInfo->id)->find();
  338. if (!$liveInfo) return Json::fail('没有查到此直播间');
  339. if ($liveInfo->is_del) return Json::fail('直播间已删除无法推流');
  340. $url = $this->aliyunLive->getPushSteam($liveInfo->stream_name);
  341. return Json::successful($url);
  342. }
  343. /**直播审核
  344. * @return mixed
  345. */
  346. public function live_audit()
  347. {
  348. return $this->fetch();
  349. }
  350. /**
  351. * 审核列表
  352. */
  353. public function get_live_audit_list()
  354. {
  355. $where = parent::getMore([
  356. ['page', 1],
  357. ['limit', 20],
  358. ['store_name', ''],
  359. ]);
  360. $where['mer_id'] = $this->merchantId;
  361. return Json::successlayui(LiveAudit::liveExamineList($where));
  362. }
  363. public function is_audit($id)
  364. {
  365. $audit = LiveAudit::where('special_id', $id)->where('live_end_time', '>=', time())->find();
  366. if ($audit) {
  367. $status = $audit['status'];
  368. } else {
  369. $status = -2;
  370. }
  371. return Json::successful(['status' => $status]);
  372. }
  373. /**
  374. * 直播审核
  375. */
  376. public function edit_audit($id)
  377. {
  378. if (!$id) return $this->failed('缺少参数');
  379. $audit = LiveAudit::where('id', $id)->find();
  380. if (!$audit) return $this->failed('未查到信息');
  381. $audit->live_strar_time = date('Y-m-d H:i:s', $audit->live_strar_time);
  382. $audit->live_end_time = date('Y-m-d H:i:s', $audit->live_end_time);
  383. $f[] = Form::input('stream_name', '直播间号', $audit->stream_name)->disabled(1);
  384. $f[] = Form::input('live_title', '直播间标题', $audit->live_title)->disabled(1);
  385. $f[] = Form::dateTimeRange('live_broadcast_time', '直播时间', $audit->live_strar_time, $audit->live_end_time);
  386. $form = Form::make_post_form('直播审核', $f, Url::build('update_live_audit', array('id' => $id)), 3);
  387. $this->assign(compact('form'));
  388. return $this->fetch('public/form-builder');
  389. }
  390. public function update_live_audit($id = 0)
  391. {
  392. if (!$id) return Json::fail('缺少参数');
  393. $data = parent::postMore([
  394. ['live_broadcast_time', []],
  395. ]);
  396. if ($data['live_broadcast_time'][0] == '' || $data['live_broadcast_time'][1] == '') return Json::fail('请设置拼团时间');
  397. if (is_array($data['live_broadcast_time']) && isset($data['live_broadcast_time'][0]) && $data['live_broadcast_time'][1]) {
  398. $data['live_strar_time'] = strtotime($data['live_broadcast_time'][0]);
  399. $data['live_end_time'] = strtotime($data['live_broadcast_time'][1]);
  400. }
  401. unset($data['live_broadcast_time']);
  402. $data['status'] = $this->isAudit == 1 ? 0 : 1;
  403. if (LiveAudit::set($data)) {
  404. return Json::successful('修改成功');
  405. } else {
  406. return Json::fail('修改失败');
  407. }
  408. }
  409. /**
  410. * 直播审核
  411. */
  412. public function audit($id)
  413. {
  414. if (!$id) return $this->failed('缺少参数');
  415. $liveInfo = LiveStudio::where('special_id', $id)->find();
  416. if (!$liveInfo) return $this->failed('未查到直播间信息');
  417. $f[] = Form::input('stream_name', '直播间号', $liveInfo->stream_name)->disabled(1);
  418. $f[] = Form::input('live_title', '直播间标题', $liveInfo->live_title)->disabled(1);
  419. $f[] = Form::dateTimeRange('live_broadcast_time', '直播时间', 0, 0);
  420. $form = Form::make_post_form('直播审核', $f, Url::build('set_live_audit', array('id' => $id)), 3);
  421. $this->assign(compact('form'));
  422. return $this->fetch('public/form-builder');
  423. }
  424. public function set_live_audit($id = 0)
  425. {
  426. if (!$id) return Json::fail('缺少参数');
  427. $data = parent::postMore([
  428. ['live_broadcast_time', []],
  429. ]);
  430. if ($data['live_broadcast_time'][0] == '' || $data['live_broadcast_time'][1] == '') return Json::fail('请设置拼团时间');
  431. if (is_array($data['live_broadcast_time']) && isset($data['live_broadcast_time'][0]) && $data['live_broadcast_time'][1]) {
  432. $data['live_strar_time'] = strtotime($data['live_broadcast_time'][0]);
  433. $data['live_end_time'] = strtotime($data['live_broadcast_time'][1]);
  434. }
  435. $liveInfo = LiveStudio::where('special_id', $id)->find();
  436. unset($data['live_broadcast_time']);
  437. $data['stream_name'] = $liveInfo->stream_name;
  438. $data['live_title'] = $liveInfo->live_title;
  439. $data['live_image'] = $liveInfo->live_image;
  440. $data['live_id'] = $liveInfo->id;
  441. $data['special_id'] = $liveInfo->special_id;
  442. $data['mer_id'] = $this->merchantId;
  443. $data['status'] = $this->isAudit == 1 ? 0 : 1;
  444. $data['add_time'] = time();
  445. if (LiveAudit::set($data)) {
  446. return Json::successful('添加成功');
  447. } else {
  448. return Json::fail('添加失败');
  449. }
  450. }
  451. /**
  452. * 直播消息提醒
  453. * @param int $id
  454. * @throws \think\db\exception\DataNotFoundException
  455. * @throws \think\db\exception\ModelNotFoundException
  456. * @throws \think\exception\DbException
  457. */
  458. public function send_remind($id = 0)
  459. {
  460. if (!$id) return Json::fail('缺少参数');
  461. $specialInfo = SpecialModel::get($id);
  462. if (!$specialInfo) return Json::fail('直播专题暂未查到,无法进行提醒');
  463. $liveInfo = LiveStudio::where('special_id', $specialInfo->id)->find();
  464. if (!$liveInfo) return Json::fail('没有查到此直播间,无法提醒');
  465. if ($liveInfo->is_del) return Json::fail('直播间已删除无法提醒');
  466. $liveInfo = $liveInfo->toArray();
  467. if ($liveInfo['is_reminded'] == 0) {
  468. LiveStudio::where('id', $liveInfo['id'])->update(['is_reminded' => 1]);
  469. }
  470. if ($specialInfo['pay_type'] == 1 && $specialInfo['member_pay_type'] == 1) {
  471. $orderList = StoreOrderModel::where(['cart_id' => $id, 'type' => 0])->column("uid");
  472. } elseif ($specialInfo['pay_type'] == 1 && $specialInfo['member_pay_type'] == 0) {
  473. $order = StoreOrderModel::where(['cart_id' => $id, 'type' => 0])->column("uid");
  474. $user = User::where('is_h5user', 0)->where('level', 1)->column("uid");
  475. $orderList = array_merge($order, $user);
  476. } else {
  477. $orderList = User::where('is_h5user', 0)->column("uid");
  478. }
  479. if (!$orderList) {
  480. return Json::fail('暂无合适用户,无需提醒');
  481. }
  482. $site_url = SystemConfigService::get('site_url');
  483. $orderList = array_unique($orderList);
  484. $data['id'] = $id;
  485. $data['site_url'] = $site_url;
  486. $data['live_title'] = $specialInfo['title'];
  487. $data['start_play_time'] = $liveInfo['start_play_time'];
  488. foreach ($orderList as $k => $v) {
  489. $data['uid'] = $v;
  490. PushJob::actionWithDoPinkJob($data, 'doLiveStudioJob');
  491. }
  492. return Json::successful("发送成功");
  493. }
  494. /**
  495. * 获取专题直播列表
  496. */
  497. public function special_list()
  498. {
  499. $where = parent::getMore([
  500. ['subject_id', 0],
  501. ['page', 1],
  502. ['limit', 20],
  503. ['store_name', ''],
  504. ['title', ''],
  505. ['start_time', ''],
  506. ['end_time', ''],
  507. ['order', ''],
  508. ['is_show', ''],
  509. ['special_type', 4],
  510. ['status', ''],
  511. ]);
  512. if (isset($where['special_type'])) {
  513. $where['type'] = $where['special_type'];
  514. }
  515. $where['mer_id'] = $this->merchantId;
  516. $special_list = SpecialModel::getSpecialList($where);
  517. return Json::successlayui($special_list);
  518. }
  519. /**
  520. * 删除专题和直播间
  521. * @param int $id
  522. * @throws \think\db\exception\DataNotFoundException
  523. * @throws \think\db\exception\ModelNotFoundException
  524. * @throws \think\exception\DbException
  525. */
  526. public function delete($id = 0)
  527. {
  528. if (!$id) return Json::fail('缺少参数');
  529. $specialInfo = SpecialModel::get($id);
  530. if (!$specialInfo) return Json::fail('查找的专题不存在');
  531. if ($specialInfo->is_del) return Json::fail('专题已经删除');
  532. $liveInfo = LiveStudio::where(['special_id' => $id])->find();
  533. if (!$liveInfo) return Json::fail('删除的专题直播不存在');
  534. if ($liveInfo->is_del) return Json::fail('直播间已删除');
  535. $specialInfo->is_del = 1;
  536. $liveInfo->is_del = 1;
  537. if ($specialInfo->save() && $liveInfo->save()) {
  538. return Json::successful('删除成功');
  539. } else {
  540. return Json::fail('删除失败');
  541. }
  542. }
  543. public function recommend($id = 0)
  544. {
  545. if (!$id) return Json::fail('缺少参数');
  546. $specialInfo = SpecialModel::get($id);
  547. if (!$specialInfo) return Json::fail('专题不存在');
  548. Session::set('live_one_id', $id, 'wap');
  549. return Json::successful('推荐成功');
  550. }
  551. /**
  552. * 嘉宾列表
  553. * @param $live_id
  554. * @return mixed
  555. */
  556. public function guest_list($live_id = 0)
  557. {
  558. $this->assign('live_id', $live_id);
  559. return $this->fetch();
  560. }
  561. /**
  562. * 添加嘉宾
  563. * @param int $live_id
  564. * @return mixed|void
  565. * @throws \FormBuilder\exception\FormBuilderException
  566. * @throws \think\db\exception\DataNotFoundException
  567. * @throws \think\db\exception\ModelNotFoundException
  568. * @throws \think\exception\DbException
  569. */
  570. public function user($live_id = 0)
  571. {
  572. $this->assign('live_id', $live_id);
  573. return $this->fetch();
  574. }
  575. /**
  576. * 获取用户列表
  577. */
  578. public function user_list()
  579. {
  580. $where = parent::getMore([
  581. ['page', 1],
  582. ['limit', 20],
  583. ['nickname', ''],
  584. ['status', ''],
  585. ['pay_count', ''],
  586. ['is_promoter', ''],
  587. ['order', ''],
  588. ['data', ''],
  589. ['country', ''],
  590. ['province', ''],
  591. ['city', ''],
  592. ['user_time_type', ''],
  593. ['user_time', ''],
  594. ['sex', ''],
  595. ]);
  596. return Json::successlayui(User::add_get_user_list($where));
  597. }
  598. /**
  599. * 添加嘉宾
  600. * @param int $live_id
  601. */
  602. public function save_guest($uid = 0, $live_id = 0, $type = 0)
  603. {
  604. if (!$live_id) return Json::fail('缺少直播间id');
  605. if (!$uid) return Json::fail('请选择用户');
  606. if ($type === '') return Json::fail('请选择类型');
  607. if ($type && LiveHonouredGuest::be(['live_id' => $live_id, 'type' => 1])) return Json::fail('讲师只能添加一个');
  608. $data['uid'] = $uid;
  609. $data['type'] = $type;
  610. $data['live_id'] = $live_id;
  611. $data['nickname'] = User::where('uid', $uid)->value('nickname');
  612. $data['add_time'] = time();
  613. if (LiveHonouredGuest::set($data))
  614. return Json::successful('添加成功');
  615. else
  616. return Json::fail('添加失败');
  617. }
  618. /**
  619. * 获取嘉宾列表
  620. */
  621. public function get_guest_list()
  622. {
  623. $where = parent::getMore([
  624. ['live_id', 0],
  625. ['nickname', ''],
  626. ['page', 1],
  627. ['limit', 20],
  628. ]);
  629. return Json::successlayui(LiveHonouredGuest::getGuestList($where));
  630. }
  631. /**
  632. * 删除嘉宾
  633. * @param int $id
  634. */
  635. public function del_guest($id = 0)
  636. {
  637. if (!$id) return Json::fail('缺少参数');
  638. if (LiveHonouredGuest::del($id))
  639. return Json::successful('删除成功');
  640. else
  641. return Json::fail('删除失败');
  642. }
  643. /**
  644. * 回放设置和下载列表
  645. * @param int $special_id
  646. * @return mixed|void
  647. * @throws \think\db\exception\DataNotFoundException
  648. * @throws \think\db\exception\ModelNotFoundException
  649. * @throws \think\exception\DbException
  650. */
  651. public function download_list($special_id = 0)
  652. {
  653. if (!$special_id) return $this->failed('缺少参数');
  654. $specialInfo = SpecialModel::get($special_id);
  655. if (!$specialInfo) return $this->failed('查找的专题不存在');
  656. if ($specialInfo->is_del) return $this->failed('专题已经删除');
  657. $liveInfo = LiveStudio::where(['special_id' => $special_id])->find();
  658. if (!$liveInfo) return $this->failed('直播不存在!');
  659. $livePlayBack = LivePlayback::where(['stream_name' => $liveInfo->stream_name, 'is_record' => 1])->find();
  660. $this->assign([
  661. 'stream_name' => $liveInfo->stream_name,
  662. 'record_id' => $livePlayBack ? $livePlayBack->RecordId : 0,
  663. 'is_playback' => 1
  664. ]);
  665. return $this->fetch();
  666. }
  667. /**
  668. * 获取直播间下的录制内容
  669. * @param string $record_id
  670. * @param string $stream_name
  671. * @param string $start_time
  672. * @param string $end_time
  673. * @param int $page
  674. * @param int $limit
  675. */
  676. public function get_live_record()
  677. {
  678. $start_time = $this->request->param('syn_start_time');
  679. $end_time = $this->request->param('syn_end_time');
  680. $stream_name = $this->request->param('stream_name');
  681. $record_id = $this->request->param('record_id');
  682. if (!$stream_name) return Json::fail('缺少直播间id');
  683. $aliyunLive = $this->aliyunLive;
  684. $beginToday = mktime(0, 0, 0, date('m'), date('d') - 3, date('Y'));
  685. if ($start_time && $end_time) {
  686. $start_time = strtotime($start_time);
  687. $end_time = strtotime($end_time);
  688. if ($start_time > $end_time) return Json::fail('开始时间不能大于结束时间');
  689. $time = bcsub($end_time, $start_time, 0) / 86400;
  690. if ($time > 4) return Json::fail('开始和结束的时间不能间隔4天');
  691. }
  692. try {
  693. $res = $aliyunLive->queryLiveRecordFiles(
  694. $stream_name,
  695. $start_time ? ApiAliyunLive::setTimeFormat($start_time) : ApiAliyunLive::setTimeFormat($beginToday),
  696. $end_time ? ApiAliyunLive::setTimeFormat($end_time) : ApiAliyunLive::setTimeFormat(time()),
  697. 1,
  698. 10
  699. );
  700. $data = [];
  701. $count = 0;
  702. if ($res) {
  703. if (isset($res['RecordIndexInfoList']['RecordIndexInfo'])) {
  704. foreach ($res['RecordIndexInfoList']['RecordIndexInfo'] as $item) {
  705. LivePlayback::livePlaybackAdd($item);
  706. $data [] = [
  707. 'StreamName' => $item['StreamName'],
  708. 'RecordId' => $item['RecordId'],
  709. 'playback_record_id' => $record_id,
  710. 'RecordUrl' => $item['RecordUrl'],
  711. 'StartTime' => $item['StartTime'],
  712. 'EndTime' => $item['EndTime'],
  713. ];
  714. }
  715. }
  716. if (isset($res['TotalNum'])) $count = $res['TotalNum'];
  717. return Json::successlayui($count, $data);
  718. } else {
  719. return Json::fail('未拉取到直播回放');
  720. }
  721. } catch (Exception $exception) {
  722. return Json::fail($exception->getMessage());
  723. }
  724. }
  725. /**回放列表
  726. * @param string $stream_name
  727. * @param string $start_time
  728. * @param string $end_time
  729. * @param int $page
  730. * @param int $limit
  731. */
  732. public function get_live_record_list()
  733. {
  734. $where = parent::getMore([
  735. ['page', 1],
  736. ['limit', 20],
  737. ['stream_name', ''],
  738. ['start_time', ''],
  739. ['end_time', ''],
  740. ]);
  741. $data = LivePlayback::getLivePlaybackList($where);
  742. return Json::successlayui($data);
  743. }
  744. /**
  745. * 删除直播回放
  746. */
  747. public function delete_live_playback($id = 0)
  748. {
  749. $res = parent::getDataModification('play_back', $id, 'is_del', 1);
  750. if ($res) {
  751. return Json::successful('删除成功');
  752. } else {
  753. return Json::fail('删除失败');
  754. }
  755. }
  756. /**设置显示
  757. * @param string $is_show
  758. * @param string $id
  759. */
  760. public function set_show($is_show = '', $id = '')
  761. {
  762. ($is_show == '' || $id == '') && Json::fail('缺少参数');
  763. $res = parent::getDataModification('play_back', $id, 'is_show', (int)$is_show);
  764. if ($res) {
  765. return Json::successful($is_show == 1 ? '显示成功' : '隐藏成功');
  766. } else {
  767. return Json::fail($is_show == 1 ? '显示失败' : '隐藏失败');
  768. }
  769. }
  770. /**
  771. * 设置某个字段
  772. * @param int $stream_name
  773. * @param string $field
  774. * @param string $value
  775. */
  776. public function set_playback_value($field = '', $id = 0, $value = '')
  777. {
  778. if (!$id || !$field) return Json::fail('缺少参数');
  779. $res = parent::getDataModification('play_back', $id, $field, $value);
  780. if ($res)
  781. return Json::successful('编辑成功');
  782. else
  783. return Json::fail('编辑失败');
  784. }
  785. /**
  786. * 设置某个字段
  787. * @param int $stream_name
  788. * @param string $field
  789. * @param string $value
  790. */
  791. public function set_value($stream_name = 0, $field = '', $value = '')
  792. {
  793. if (!$stream_name || !$field) return Json::fail('缺少参数');
  794. $res = LiveStudio::where('stream_name', $stream_name)->update([$field => $value]);
  795. if ($res)
  796. return Json::successful('设置成功');
  797. else
  798. return Json::fail('设置失败');
  799. }
  800. public function set_record($stream_name = 0, $record_id = 0, $field = '', $value = '')
  801. {
  802. if (!$stream_name || !$record_id || !$field) return Json::fail('缺少参数');
  803. $res = LivePlayback::where(['stream_name' => $stream_name, 'RecordId' => $record_id])->update([$field => $value]);
  804. if ($value == 1) {
  805. LiveStudio::where(['stream_name' => $stream_name])->update(['playback_record_id' => $record_id, 'is_playback' => 1]);
  806. LivePlayback::where(['stream_name' => $stream_name])->where('RecordId', "neq", $record_id)->update([$field => 0]);
  807. } else {
  808. LiveStudio::where(['stream_name' => $stream_name])->update(['playback_record_id' => "", 'is_playback' => 0]);
  809. }
  810. if ($res)
  811. return Json::successful('设置成功');
  812. else
  813. return Json::fail('设置失败');
  814. }
  815. /**
  816. * 直播回放
  817. * @param string $record_url
  818. * @return mixed|void
  819. */
  820. public function live_record_look($record_url = '')
  821. {
  822. if (!$record_url) return $this->failed('缺少回放地址');
  823. $this->assign('record_url', $record_url);
  824. return $this->fetch();
  825. }
  826. /**
  827. * 下载引导页面
  828. * @param string $record_url
  829. * @return mixed|void
  830. */
  831. public function download($record_url = '')
  832. {
  833. if (!$record_url) return $this->failed('缺少回放地址');
  834. $this->assign('record_url', $record_url);
  835. return $this->fetch();
  836. }
  837. /**
  838. * 评论页面
  839. * @param int $special_id
  840. * @return mixed|void
  841. * @throws \think\db\exception\DataNotFoundException
  842. * @throws \think\db\exception\ModelNotFoundException
  843. * @throws \think\exception\DbException
  844. */
  845. public function comment_list($special_id = 0)
  846. {
  847. if (!$special_id) return $this->failed('缺少参数');
  848. $specialInfo = SpecialModel::get($special_id);
  849. if (!$specialInfo) return $this->failed('查找的专题不存在');
  850. if ($specialInfo->is_del) return $this->failed('专题已经删除');
  851. $liveInfo = LiveStudio::where(['special_id' => $special_id])->find();
  852. if (!$liveInfo) return $this->failed('直播不存在!');
  853. if ($liveInfo->is_del) return $this->failed('直播间已删除!');
  854. $this->assign('live_id', $liveInfo->id);
  855. return $this->fetch();
  856. }
  857. /**
  858. * 获取直播评论列表
  859. */
  860. public function get_live_comment_list()
  861. {
  862. $where = parent::getMore([
  863. ['live_id', 0],
  864. ['page', 1],
  865. ['limit', 20],
  866. ['nickname', ''],
  867. ['start_time', ''],
  868. ['end_time', ''],
  869. ]);
  870. if (!$where['live_id']) return Json::fail('缺少直播间id');
  871. return Json::successlayui(LiveBarrage::getLiveCommentList($where));
  872. }
  873. /**
  874. * 设置评论隐藏显示
  875. *
  876. * @return json
  877. */
  878. public function set_show_comment($is_show = '', $id = '')
  879. {
  880. ($is_show == '' || $id == '') && Json::fail('缺少参数');
  881. $res = LiveBarrage::where(['id' => $id])->update(['is_show' => (int)$is_show]);
  882. if ($res) {
  883. return Json::successful('设置成功');
  884. } else {
  885. return Json::fail('设置失败');
  886. }
  887. }
  888. /**
  889. * @param int $grade_id
  890. * @throws \think\db\exception\DataNotFoundException
  891. * @throws \think\db\exception\ModelNotFoundException
  892. * @throws \think\exception\DbException
  893. */
  894. public function get_subject_list($grade_id = 0)
  895. {
  896. if (!$grade_id) return Json::fail('缺少参数');
  897. $subjectlist = SpecialSubject::where(['grade_id' => $grade_id, 'is_show' => 1, 'is_del' => 0])->order('sort desc')->select();
  898. return Json::successful($subjectlist);
  899. }
  900. /**
  901. * @param int $subject_id
  902. * @throws \think\db\exception\DataNotFoundException
  903. * @throws \think\db\exception\ModelNotFoundException
  904. * @throws \think\exception\DbException
  905. */
  906. public function get_special_list($subject_id = false, $live_goods_list = false)
  907. {
  908. $where['is_show'] = 1;
  909. $where['is_del'] = 0;
  910. if ($subject_id) $where['subject_id'] = $subject_id;
  911. if (!$live_goods_list) {
  912. $dataList = $specialList = SpecialModel::where($where)->order('sort desc')->select();
  913. } else {
  914. $dataList = array();
  915. $specialList = SpecialModel::where($where)->whereIn('type', [1, 2, 3, 5])->order('type desc')->select();
  916. foreach ($specialList as $k => $v) {
  917. $dataList[$k]['value'] = $v['id'];
  918. $dataList[$k]['title'] = SPECIAL_TYPE[$v['type']] . "--" . $v['title'];
  919. }
  920. }
  921. return Json::successful($dataList);
  922. }
  923. /**直播推荐(课程)
  924. * @return mixed
  925. */
  926. public function live_goods($live_id = 0, $special_id = 0)
  927. {
  928. $this->assign(['live_id' => $live_id, 'special_id' => $special_id]);
  929. return $this->fetch();
  930. }
  931. /**添加直播的专题课程推荐
  932. * @param int $id
  933. * @param string $ids
  934. */
  935. public function add_live_special($special_id = 0, $ids = '', $type = 0)
  936. {
  937. if (!$special_id || !$ids) return Json::fail('参数错误');
  938. $res = LiveGoods::saveLiveGoods($ids, $special_id, $type);
  939. if ($res)
  940. return Json::successful('添加成功');
  941. else
  942. return Json::fail('添加失败');
  943. }
  944. /**直播推荐列表数据
  945. * @return mixed
  946. */
  947. public function live_goods_list($live_id = false)
  948. {
  949. $where = parent::getMore([
  950. ['page', 1],
  951. ['live_id', 0],
  952. ['store_name', ""],
  953. ['limit', 20],
  954. ['order', ''],
  955. ['is_show', ''],
  956. ]);
  957. if ($live_id) $where['live_id'] = $live_id;
  958. $where['mer_id'] = $this->merchantId;
  959. return Json::successlayui(LiveGoods::getLiveGoodsList($where));
  960. }
  961. /**直播推荐(商品)
  962. * @return mixed
  963. */
  964. public function live_store($live_id = 0, $special_id = 0)
  965. {
  966. $this->assign(['live_id' => $live_id, 'special_id' => $special_id]);
  967. return $this->fetch();
  968. }
  969. /**直播推荐列表数据
  970. * @return mixed
  971. */
  972. public function live_store_list($live_id = false)
  973. {
  974. $where = parent::getMore([
  975. ['page', 1],
  976. ['live_id', 0],
  977. ['store_name', ""],
  978. ['limit', 20],
  979. ['order', ''],
  980. ['is_show', ''],
  981. ]);
  982. if ($live_id) $where['live_id'] = $live_id;
  983. $where['mer_id'] = $this->merchantId;
  984. return Json::successlayui(LiveGoods::getLiveStoreProductList($where));
  985. }
  986. /**直播打赏
  987. * @return mixed
  988. */
  989. public function live_reward($live_id = 0)
  990. {
  991. $gold_info = SystemConfigService::more(['gold_name', 'gold_image']);
  992. $where['l.is_del'] = 0;
  993. $where['s.mer_id'] = $this->merchantId;
  994. $live_studio = LiveStudio::alias('l')->where($where)->join('__SPECIAL__ s', 'l.special_id = s.id')->field('l.id,l.live_title')->select();
  995. $live_studio = $live_studio ? $live_studio->toArray() : [];
  996. $this->assign("year", getMonth('y'));
  997. $this->assign("live_studio", json_encode($live_studio));
  998. $this->assign("gold_info", $gold_info);
  999. $this->assign("live_id", $live_id);
  1000. return $this->fetch();
  1001. }
  1002. /**
  1003. * 直播礼物列表
  1004. */
  1005. public function live_gift_list()
  1006. {
  1007. return Json::successlayui(LiveGift::liveGiftList());
  1008. }
  1009. /**直播礼物
  1010. * @throws \think\db\exception\DataNotFoundException
  1011. * @throws \think\db\exception\ModelNotFoundException
  1012. * @throws \think\exception\DbException
  1013. */
  1014. public function liveGiftList()
  1015. {
  1016. $data = LiveGift::order('sort DESC,id DESC')->select();
  1017. return Json::successful($data);
  1018. }
  1019. /**直播推荐列表数据
  1020. * @return mixed
  1021. */
  1022. public function live_reward_list()
  1023. {
  1024. $where = parent::getMore([
  1025. ['page', 1],
  1026. ['user_info', ""],
  1027. ['limit', 20],
  1028. ['order', ''],
  1029. ['live_id', 0],
  1030. ['gift_id', 0],
  1031. ['date', 0],
  1032. ]);
  1033. $where['mer_id'] = $this->merchantId;
  1034. return Json::successlayui(LiveReward::getLiveRewardList($where));
  1035. }
  1036. /**
  1037. * 获取头部订单金额等信息
  1038. * return json
  1039. */
  1040. public function getBadge()
  1041. {
  1042. $where = parent::postMore([
  1043. ['page', 1],
  1044. ['user_info', ''],
  1045. ['limit', 20],
  1046. ['order', ''],
  1047. ['live_id', 0],
  1048. ['gift_id', 0],
  1049. ['date', 0],
  1050. ]);
  1051. $where['mer_id'] = $this->merchantId;
  1052. return Json::successful(LiveReward::getBadge($where));
  1053. }
  1054. public function mer_live_reward()
  1055. {
  1056. $this->assign([
  1057. 'gold_name' => SystemConfigService::get("gold_name")
  1058. ]);
  1059. return $this->fetch();
  1060. }
  1061. /**
  1062. * 收益列表
  1063. */
  1064. public function mer_live_reward_list()
  1065. {
  1066. $where = parent::postMore([
  1067. ['page', 1],
  1068. ['limit', 20],
  1069. ['order', ''],
  1070. ['live_id', 0],
  1071. ]);
  1072. $where['mer_id'] = $this->merchantId;
  1073. return Json::successlayui(LiveReward::get_mer_live_reward_list($where));
  1074. }
  1075. /**直播收益提现
  1076. * @param $live_id
  1077. * @throws \think\db\exception\DataNotFoundException
  1078. * @throws \think\db\exception\ModelNotFoundException
  1079. * @throws \think\exception\DbException
  1080. */
  1081. public function rawal($live_id)
  1082. {
  1083. $where['mer_id'] = $this->merchantId;
  1084. $where['live_id'] = $live_id;
  1085. $data = LiveReward::get_mer_live_reward($where);
  1086. $total_price = $data['total_price'];
  1087. LiveReward::beginTrans();
  1088. $gold = Merchant::where('id', $this->merchantId)->field('gold_divide,gold_num')->find();
  1089. $gold_divide = $gold['gold_divide'];
  1090. $gold_divide = bcdiv($gold_divide, 100, 2);
  1091. $rawal = bcmul($total_price, $gold_divide, 0);
  1092. $res1 = false != Merchant::where('id', $this->merchantId)->setInc('gold_num', $rawal);
  1093. $gold_name = SystemConfigService::get("gold_name");
  1094. $res2 = false != MerchantBill::income('直播收益提现' . $gold_name, 0, $this->merchantId, 'gold_num', 'extract', $rawal, bcadd($gold['gold_num'], $rawal, 0), '直播收益提现' . floatval($rawal) . $gold_name);
  1095. $res = $res1 && $res2;
  1096. LiveReward::checkTrans($res);
  1097. if ($res) {
  1098. LiveReward::where('live_id', $live_id)->update(['is_extract' => 1]);
  1099. return Json::successful('提现成功');
  1100. } else {
  1101. return Json::fail('提现失败');
  1102. }
  1103. }
  1104. }