You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
yanzong/app/store/model/wxapp/LiveRoom.php

237 lines
8.2 KiB

11 months ago
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\model\wxapp;
use app\store\model\wxapp\Setting as WxappSettingModel;
use app\common\model\wxapp\LiveRoom as LiveRoomModel;
use app\common\library\wechat\live\Room as LiveRoomApi;
use cores\exception\BaseException;
/**
* 微信小程序直播间模型
* Class LiveRoom
* @package app\store\model\wxapp
*/
class LiveRoom extends LiveRoomModel
{
/**
* 获取直播间列表
* @param string $search
* @return \think\Paginator
* @throws \think\db\exception\DbException
*/
public function getList(string $search = ''): \think\Paginator
{
// 查询对象
$query = $this->getNewQuery();
// 检索查询条件
!empty($search) && $query->where('room_name|anchor_name', 'like', "%{$search}%");
// 查询直播间列表
return $query->where('is_delete', '=', 0)
->order(['is_top' => 'desc', 'live_status' => 'asc', 'create_time' => 'desc'])
->paginate(15);
}
/**
* 设置直播间置顶状态
* @param int $isTop
* @return bool|false
*/
public function setIsTop(int $isTop): bool
{
return $this->save(['is_top' => $isTop]);
}
/**
* 刷新直播间列表(同步微信api)
* 每次拉取上限100条数据
* @return bool
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function refreshLiveList(): bool
{
// 获取微信api最新直播间列表信息
$originRoomList = $this->getOriginRoomList();
// 获取微信直播间的房间id集
$originRoomIds = $this->getOriginRoomIds($originRoomList);
// 已存储的所有房间id集
$localRoomIds = $this->getLocalRoomIds();
// 同步新增直播间
$this->refreshLiveNew($localRoomIds, $originRoomIds, $originRoomList);
// 同步删除直播间
$this->refreshLiveRemove($localRoomIds, $originRoomIds);
// 同步更新直播间
$this->refreshLiveUpdate($localRoomIds, $originRoomIds, $originRoomList);
return true;
}
/**
* 获取微信api最新直播间列表信息
* @return array
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getOriginRoomList(): array
{
// 小程序配置信息
$wxConfig = WxappSettingModel::getConfigBasic();
// 请求api数据
$LiveRoomApi = new LiveRoomApi($wxConfig['app_id'], $wxConfig['app_secret']);
$response = $LiveRoomApi->getLiveRoomList();
empty($response) && throwError('直播房间列表API请求失败:' . $LiveRoomApi->getError());
// 格式化返回的列表数据
$originRoomList = [];
foreach ($response['room_info'] as $item) {
$originRoomList[$item['roomid']] = $item;
}
return $originRoomList;
}
/**
* 获取微信直播间的房间id集
* @param array $originRoomList
* @return array
*/
private function getOriginRoomIds(array $originRoomList): array
{
$originRoomIds = [];
foreach ($originRoomList as $item) {
$originRoomIds[] = $item['roomid'];
}
return $originRoomIds;
}
/**
* 获取数据库中已存在的roomid
* @return array
*/
private function getLocalRoomIds(): array
{
return $this->where('is_delete', '=', 0)->column('room_id', 'id');
}
/**
* 同步新增直播间
* @param array $localRoomIds 本地直播间id集
* @param array $originRoomIds 最新直播间id集
* @param array $originRoomList 最新直播间列表
* @return void
*/
private function refreshLiveNew(array $localRoomIds, array $originRoomIds, array $originRoomList): void
{
// 需要新增的直播间ID
$newLiveRoomIds = array_values(array_diff($originRoomIds, $localRoomIds));
if (empty($newLiveRoomIds)) {
return;
}
// 整理新增数据
$saveData = [];
foreach ($newLiveRoomIds as $roomId) {
$item = $originRoomList[$roomId];
$saveData[] = [
'room_id' => $roomId,
'room_name' => $item['name'],
'cover_img' => $item['cover_img'],
'share_img' => $item['share_img'],
'anchor_name' => $item['anchor_name'],
'start_time' => $item['start_time'],
'end_time' => $item['end_time'],
'live_status' => $item['live_status'],
'store_id' => self::$storeId,
];
}
// 批量新增直播间
$this->addAll($saveData) !== false;
}
/**
* 同步更新直播间
* @param array $localRoomIds 本地直播间id集
* @param array $originRoomIds 最新直播间id集
* @param array $originRoomList 最新直播间列表
* @return void
*/
private function refreshLiveUpdate(array $localRoomIds, array $originRoomIds, array $originRoomList): void
{
// 需要新增的直播间ID
$updatedLiveRoomIds = array_values(array_intersect($originRoomIds, $localRoomIds));
if (empty($updatedLiveRoomIds)) {
return;
}
// 根据直播间id获取主键id
$idArr = $this->getLocalIdsByRoomIds($localRoomIds);
// 整理更新的数据
$saveData = [];
foreach ($updatedLiveRoomIds as $roomId) {
$item = $originRoomList[$roomId];
$saveData[] = [
'where' => ['id' => $idArr[$roomId]],
'data' => [
'room_id' => $roomId,
'room_name' => $item['name'],
'cover_img' => $item['cover_img'],
'share_img' => $item['share_img'],
'anchor_name' => $item['anchor_name'],
'start_time' => $item['start_time'],
'end_time' => $item['end_time'],
'live_status' => $item['live_status'],
'store_id' => self::$storeId,
]
];
}
// 批量更新直播间
$this->updateAll($saveData);
}
/**
* 同步删除直播间
* @param array $localRoomIds 本地直播间id集
* @param array $originRoomIds 最新直播间id集
* @return void
*/
private function refreshLiveRemove(array $localRoomIds, array $originRoomIds): void
{
// 需要删除的直播间ID
$removedLiveRoomIds = array_values(array_diff($localRoomIds, $originRoomIds));
if (empty($removedLiveRoomIds)) {
return;
}
// 根据直播间id获取主键id
$removedIds = $this->getLocalIdsByRoomIds($localRoomIds, $removedLiveRoomIds);
// 批量删除直播间
self::destroy(array_values($removedIds));
}
/**
* 根据直播间ID获取主键ID
* @param array $localRoomIds
* @param array $searchRoomIds
* @return array
*/
private function getLocalIdsByRoomIds(array $localRoomIds, array $searchRoomIds = []): array
{
$data = [];
foreach ($localRoomIds as $id => $roomId) {
if (empty($searchRoomIds) || in_array($roomId, $searchRoomIds)) {
$data[$roomId] = $id;
}
}
return $data;
}
}