初始化

This commit is contained in:
2025-04-18 00:39:21 +08:00
commit 63dbaa16c8
52 changed files with 3448 additions and 0 deletions

1
app/.htaccess Normal file
View File

@@ -0,0 +1 @@
deny from all

22
app/AppService.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
declare (strict_types = 1);
namespace app;
use think\Service;
/**
* 应用服务类
*/
class AppService extends Service
{
public function register()
{
// 服务注册
}
public function boot()
{
// 服务启动
}
}

94
app/BaseController.php Normal file
View File

@@ -0,0 +1,94 @@
<?php
declare (strict_types = 1);
namespace app;
use think\App;
use think\exception\ValidateException;
use think\Validate;
/**
* 控制器基础类
*/
abstract class BaseController
{
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
return $v->failException(true)->check($data);
}
}

58
app/ExceptionHandle.php Normal file
View File

@@ -0,0 +1,58 @@
<?php
namespace app;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用内置的方式记录异常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
// 其他错误交给系统处理
return parent::render($request, $e);
}
}

8
app/Request.php Normal file
View File

@@ -0,0 +1,8 @@
<?php
namespace app;
// 应用请求对象类
class Request extends \think\Request
{
}

423
app/command/Lebo.php Normal file
View File

@@ -0,0 +1,423 @@
<?php
declare (strict_types = 1);
namespace app\command;
use Exception;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Cache;
use Curl\Curl;
use think\helper\Str;
use app\kernel\Lebolebo\Account;
use app\kernel\Lebolebo\Curriculum;
use Aria2;
class Lebo extends Command
{
private $aria2 = null;
private $completed = false;
protected function configure()
{
// 指令配置
$this->setName('course')
->setDescription('the course command');
}
protected function execute(Input $input, Output $output)
{
$this->aria2 = new Aria2('http://127.0.0.1:16800/jsonrpc','11223344');
$this->completed = false;
while($this->completed === false){
try {
$this->start();
} catch (\Exception $e) {
dump($e);
sleep(3);
}
}
dump('下载完成!');
// 指令输出
// $output->writeln('course');
}
private function start()
{
// $savepath = store_path() . '/lebolebo/';
$savepath = 'E:/lebolebo/';
$account = new Account();
$account_info = $account->login('13880615958','robo520');
if($account_info['code'] == 500){
dump($account_info['msg']);
exit;
}
$curl = new Curl();
$curr = new Curriculum();
$curr->setHeader('token',$account_info['data']['token']);
$course = $curr->list(0);
foreach ($course['data']['list'] as $list){
$c = $savepath . $list['courseName'];
is_dir($c) || mkdir($c,0755,true);
$detail = $curr->detail($list['id']);
$courseCover = $c . '/courseCover.png';
if($detail['data']['courseCover']){
$downloadurl = $detail['data']['courseCover'];
$check = $this->checkfile($downloadurl,$courseCover);
if(!$check && !is_file($courseCover)){
// $result = $curl->_fastDownload($downloadurl,$courseCover);
$this->aria2->addUri(
[$downloadurl],
['dir'=>$c,
'out'=>'courseCover.png'
]
);
// dump('封面下载结果:',$result);
// if($result){
// $this->complete($downloadurl,$courseCover);
// }
}
$txt = $courseCover . '-下载地址.txt';
$this->savetxt($txt,$downloadurl);
}
$d = $curr->courseUnitList($list['courseCode']);
$courseUnits = $d['data']['courseUnit'];
if($courseUnits === null){
continue;
}
foreach ($courseUnits as $courseUnit){
$courseUnitName = $c . '/' . str_ireplace('/','-',$courseUnit['courseUnitName']);
if(!is_dir($courseUnitName)){
dump('创建课程文件夹:' . $courseUnitName);
mkdir($courseUnitName,0755,true);
}
$selectByCourseUnits = $curr->selectByCourseUnits($courseUnit['courseCode'],$courseUnit['courseUnitCode']);
foreach ($selectByCourseUnits['data'] as $selectByCourseUnit){
$this->waiting();
$sessionName = $courseUnitName . '/' . $selectByCourseUnit['sessionName'];
if(!is_dir($sessionName)){
dump('创建课件文件夹:'.$sessionName);
mkdir($sessionName,0755,true);
}
$t = $curr->selectByCourseSessionCode($selectByCourseUnit['courseSessionCode']);
// 0: {type: 1, des: "PPT-HTML"}
// 1: {type: 2, des: "讲义"}
// 2: {type: 3, des: "课前预习"}
// 3: {type: 4, des: "测一测"}
// 4: {type: 5, des: "玩一玩"}
// 5: {type: 6, des: "试一试"}
// 6: {type: 9, des: "知识点"}
// 7: {type: 10, des: "名人名言"}
// 8: {type: 11, des: "录播课"}
// 9: {type: 13, des: "教辅"}
// 10: {type: 14, des: "备课"}
// 11: {type: 15, des: "课程内容"}
// 12: {type: 16, des: "课后拓展"}
// 13: {type: 18, des: "素养目标"}
$ts = $t['data'];
foreach ($ts as $kk ){
switch ($kk['resourceType']) {
case '1':// PPT-HTML
if(!isset($kk['content'])){
continue;
}
$filename = $kk['content']['fileName'];
$downloadurl = $kk['content']['fileUrl'];
$file = $sessionName . '/' . $filename;
// 保存下载地址
$txt = "{$file}-下载地址.txt";
$this->savetxt($txt,$downloadurl);
$check = $this->checkfile($downloadurl,$file);
if(!$check && !is_file($file)){
dump('下载PPT' . $file);
// $result = $curl->_fastDownload($downloadurl,$file);
// dump('PPT下载结果',$result);
// if($result){
// $this->complete($downloadurl,$file);
// }
$this->aria2->addUri(
[$downloadurl],
['dir'=>$sessionName,
'out'=>$filename]
);
}else if($check && !is_file($file)){
if(is_file($check)){
try {
copy($check,$file);
} catch (Exception $e) {
dump('文件拷贝失败:',$e);
exit;
}
}else{
dump('下载PPT' . $file);
// $result = $curl->_fastDownload($downloadurl,$file);
// dump('PPT下载结果',$result);
// if($result){
// $this->complete($downloadurl,$file);
// }
$this->aria2->addUri(
[$downloadurl],
['dir'=>$sessionName,
'out'=>$filename]
);
}
dump('跳过PPT' . $file);
}else{
dump('PPT文件已存在' . $file);
$this->complete($downloadurl,$file);
}
break;
case '2':
break;
case '3':
break;
case '4':
break;
case '5':
break;
case '6':
// 试一试
$shiyishi = $sessionName . '/试一试/';
if(!is_dir($shiyishi)){
mkdir($shiyishi,0755,true);
}
$questions = $kk['content']['questions'];
if(!is_array($questions))break;
foreach ($questions as $key => $question) {
$filename = $question['fileName'];
$downloadurl = $question['fileUrl'];
$file = $shiyishi . $filename;
// 保存文件下载地址
$txt = "{$file}-下载地址.txt";
$this->savetxt($txt,$downloadurl);
$check = $this->checkfile($downloadurl,$file);
if(!$check && !is_file($file)){
// $result = $curl->_fastDownload($downloadurl,$file);
// dump('试一试下载结果:',$result);
// if($result){
// $this->complete($downloadurl,$file);
// }
$this->aria2->addUri(
[$downloadurl],
['dir'=>$shiyishi,
'out'=>$filename]
);
}else if($check && !is_file($file)){
copy($check,$file);
dump('跳过试一试:' . $file);
}else{
dump('试一试文件已存在:' . $file);
$this->complete($downloadurl,$file);
}
}
break;
case '9':
break;
case '10':
break;
case '11':
break;
case '13':
// 教辅
if(!isset($kk['content']['resourceList'])){
continue;
}
$jiaofupath = $sessionName . '/教辅/';
if(!is_dir($jiaofupath)){
mkdir($jiaofupath,0755,true);
}
$resourceLists = $kk['content']['resourceList'];
foreach($resourceLists as $resourceList){
$file = $jiaofupath . $resourceList['fileName'] ;
if(Str::endsWith($file,['.mp4','.mov'])){
$dd = $curr->getVideoUrl($resourceList['fileUrl']);
$downloadurl = $dd['data'];
}else{
$downloadurl = $resourceList['fileUrl'];
}
// 保存下载地址
$txt = "{$file}-下载地址.txt";
$this->savetxt($txt,$downloadurl);
$check = $this->checkfile($downloadurl,$file);
if(!$check && !is_file($file)){
dump('下载教辅:' . $file);
// $result = $curl->_fastDownload($downloadurl,$file);
// dump('教辅下载结果:',$result);
// if($result){
// $this->complete($downloadurl,$file);
// }
$this->aria2->addUri(
[$downloadurl],
['dir'=>$jiaofupath,
'out'=>$resourceList['fileName']]
);
}else if($check && !is_file($file)){
copy($check,$file);
dump('跳过教辅:' . $file);
}else{
dump('教辅文件已存在:' . $file);
$this->complete($downloadurl,$file);
}
}
break;
case '14':
// 备课
if(!isset($kk['content']['resourceList'])){
continue;
}
$beikepath = $sessionName . '/备课/';
if(!is_dir($beikepath)){
mkdir($beikepath,0755,true);
}
$resourceLists = $kk['content']['resourceList'];
foreach($resourceLists as $resourceList){
$file = $beikepath . $resourceList['fileName'] ;
if(Str::endsWith($file,['.mp4','.mov','.MP4','.mkv','.wmv'])){
$dd = $curr->getVideoUrl($resourceList['fileUrl']);
$downloadurl = $dd['data'];
}else{
$downloadurl = $resourceList['fileUrl'];
}
// 保存下载地址
$txt = "{$file}-下载地址.txt";
$this->savetxt($txt,$downloadurl);
$check = $this->checkfile($downloadurl,$file);
if(!$check && !is_file($file)){
dump('下载备课:' . $file);
// $result = $curl->_fastDownload($downloadurl,$file);
// dump('备课下载结果:',$result);
// if($result){
// $this->complete($downloadurl,$file);
// }
$this->aria2->addUri(
[$downloadurl],
['dir'=>$beikepath,
'out'=>$resourceList['fileName']]
);
}else if($check && !is_file($file)){
copy($check,$file);
dump('跳过备课:' . $file);
}else{
dump('备课文件已存在:' . $file);
$this->complete($downloadurl,$file);
}
}
break;
case '15':
// 课程内容
if(is_null($kk['content']['courseContent']))break;
$file = "{$sessionName}/课程内容.txt";
$this->savetxt($file,strip_tags($kk['content']['courseContent']));
break;
case '16':
break;
case '18':
break;
default:
break;
}
// break;
}
}
}
// break;
}
$this->completed = true;
}
private function checkfile($url,$file)
{
$key = 'lebolebo_check_header_'.md5($url);
try {
if(($head = Cache::get($key,null)) === NULL ){
$head = @get_headers($url,1);
if ($head === false) {
dump('获取文件信息失败,直接重新下载'.$file);
return false;
}
Cache::set($key,$head,86400);
}
$kk = 'lebolebo_file_' . pathinfo($file,PATHINFO_BASENAME);
if(isset($head['Content-Length']) && ($size = intval($head['Content-Length']))){
$kk .= $size;
if(is_file($file) && ($size !== filesize($file))){
dump('文件大小不符,重新下载'.$file);
unlink($file);
return false;
}
}
if(isset($head['ETag'])){
$t = $kk . md5($head['ETag']);
if(Cache::has($t)){
return Cache::get($t);
}
}
if(isset($head['Content-MD5'])){
$t = $kk . md5($head['Content-MD5']);
if(Cache::has($t)){
return Cache::get($t);
}
}
} catch (Exception $e) {
dump('检查文件失败:',$url,$file,$e);
exit;
}
return false;
}
private function complete($url,$file)
{
$key = 'lebolebo_check_header_' . md5($url);
try {
if(($head = Cache::get($key,null)) === NULL ){
$head = @get_headers($url,1);
if($head === false){
return false;
}
Cache::set($key,$head,86400);
}
$kk = 'lebolebo_file_' . pathinfo($file,PATHINFO_BASENAME);
if(isset($head['Content-Length'])){
$kk .= intval($head['Content-Length']);
}
if(isset($head['ETag'])){
$t = $kk . md5($head['ETag']);
Cache::set($t,$file,86400);
}
if(isset($head['Content-MD5'])){
$t = $kk . md5($head['Content-MD5']);
Cache::set($t,$file,86400);
}
} catch (Exception $e) {
dump($e);
exit;
}
}
private function savetxt(string $file,string $content)
{
if(is_file($file)){
unlink($file);
}
$myfile = fopen($file, "w");
fwrite($myfile, $content);
fclose($myfile);
// dump('已保存文本内容:'.$file);
}
private function waiting()
{
$num = 1;
while($num > 0){
$activeDownloads = $this->aria2->getGlobalStat();
$num = intval($activeDownloads['result']['numWaiting']);
if($num > 10){
dump('当前任务过多,等待任务数:',$num);
sleep(1);
}else{
break;
}
}
}
}

256
app/command/Zm.php Normal file
View File

@@ -0,0 +1,256 @@
<?php
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Option;
use think\console\input\Argument;
use think\console\input\InputOption;
use Aria2;
use think\facade\Log;
use GuzzleHttp\Client;
class Zm extends Command
{
private $aria2 = null;
private $completed = false;
private $user_id = '8ROYK0G3vGLyyEFjr9DtEQ==';
protected function configure()
{
// 指令配置
$this->setName('zm')
->setDescription('zm command');
}
protected function execute(Input $input, Output $output)
{
// 输出结果
// $output->writeln("Hello, {$name}!");
// $output->writeln("Option: {$option}");
$this->aria2 = new Aria2('http://127.0.0.1:16800/jsonrpc','11223344'); //实例化aria2对象
$this->aria2->setOption('enable-async-dns', true); //设置异步dns解析
$this->aria2->setOption('enable-http-pipelining', true); //设置http管道化
$this->aria2->setOption('enable-http-keep-alive', true); //设置http保持连接
$this->completed = false;
while($this->completed === false){
try {
$this->start();
} catch (\Exception $e) {
halt($e);
sleep(3);
}
}
dump('下载完成!');
}
protected function start()
{
$savepath = 'E:/zm';
$lable = $this->getLable();
if($lable['code'] == 0){
$leftLabel = $lable['data']['leftLabel'];
foreach ($leftLabel[0]['children'] as $key => $course) {
$lable_title = $course['title'];
$lable_id = $course['id'];
$next = true;
$curr_page = 1;
$curr_total = 0;
while($next){
$curr = $this->getCurr($lable_id,$curr_page);
$currs = $curr['data']['curriculum'];
foreach ($currs as $key => $value) {
$curr_total++;
$curr_item = $value;
$curr_item_title = $curr_item['title'];
$c = $savepath . '/' . $lable_title . '/' . $curr_item_title;
// dump('存储路径',$c);
is_dir($c) || mkdir($c,0755,true);
$author = $savepath . '/' . $lable_title . '/' . $curr_item_title . '/' . '作者.txt';
$this->savetxt($author,$curr_item['author']);
$introduce = $savepath . '/' . $lable_title . '/' . $curr_item_title . '/' . '介绍.txt';
$this->savetxt($introduce,$curr_item['introduce']);
$cover = $curr_item['cover'];
$this->download($cover,$c);
$cover_name = basename($cover);
$cover_path = "{$c}/{$cover_name}-下载地址.txt";
$this->savetxt($cover_path,$cover);
$curr_details = $this->getCurrDetails($curr_item['id']);
foreach($curr_details['data']['curriculum']['allClassSectionTrue'] as $class){
$class_path = $c . '/' . $class['title'];
is_dir($class_path) || mkdir($class_path,0755,true);
$class_details = $this->getClassDetails($class['id']);
dump($class_path,$class_details);
$class_id = $class_details['data']['classSection']['id'];
if(!empty($class_details['data']['classSection']['video'])){
$this->download($class_details['data']['classSection']['video'],$class_path);
}
if(!empty($class_details['data']['classSection']['courseware'])){
$this->download($class_details['data']['classSection']['courseware'],$class_path);
}
if(!empty($class_details['data']['classSection']['construction_draw'])){
$this->download($class_details['data']['classSection']['construction_draw'],$class_path);
}
if(!empty($class_details['data']['classSection']['construction_draw_3d'])){
$this->download($class_details['data']['classSection']['construction_draw_3d'],$class_path);
}
foreach($class_details['data']['classSection']['allEnclosure'] as $enclosure){
$parts = explode("{$class_id}/", $enclosure['url']);
$path = parse_url($enclosure['url'], PHP_URL_PATH);
$parts = explode('/', $path);
$this->download($enclosure['url'],$class_path . '/' . urldecode($parts[count($parts)-2]));
}
}
}
$curr_page++;
if($curr_total >= $curr['data']['total']){
$next = false;
break;
}
}
// exit();
}
dump($leftLabel);
}else{
dump($lable['msg']);
exit();
}
exit();
}
protected function download($downloadurl,$dir,$filename = null)
{
$result = $this->aria2->addUri(
[$downloadurl],
['dir'=>$dir,
'header'=>[
'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36 Core/1.116.489.400 QQBrowser/13.7.6351.400',
'referer: https://edu.zmrobo.com/courses',
],
'out'=>$filename]
);
}
public function getLable($sign = 'null')
{
$client = new Client();
$result = $client->get("https://edu.zmrobo.com/api/label",[
'headers'=>[
'User-Agent'=>'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36 Core/1.116.489.400 QQBrowser/13.7.6351.400',
'referer'=>'https://edu.zmrobo.com/courses',
'E-Date'=>time(),
'Sign'=>$sign,
]
]);
$result = json_decode($result->getBody()->getContents(),true);
if($result['code'] == -3){
return $this->getLable($result['sign']);
}else{
return $result;
}
}
public function getCurr($label_id,$page,$sign = 'null')
{
$client = new Client();
$options = [
'headers'=>[
'User-Agent'=>'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36 Core/1.116.489.400 QQBrowser/13.7.6351.400',
'referer'=>'https://edu.zmrobo.com/courses',
'E-Date'=>time(),
'Content-Type'=>'application/json; charset=utf-8',
'Origin'=>'https://edu.zmrobo.com',
'Sign'=>$sign,
],
'body'=>json_encode([
'label'=>[[$label_id]],
'page'=>$page,
])
];
$result = $client->post("https://edu.zmrobo.com/api/curriculum/list",$options);
$result = json_decode($result->getBody()->getContents(),true);
if($result['code'] == -3){
return $this->getCurr($label_id,$page,$result['sign']);
}else if($result['code'] == 0){
return $result;
}else{
dump($result['msg']);
exit();
}
}
public function getCurrDetails($curr_id,$sign = 'null')
{
$client = new Client();
$options = [
'headers'=>[
'User-Agent'=>'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36 Core/1.116.489.400 QQBrowser/13.7.6351.400',
'referer'=>'https://edu.zmrobo.com/courses',
'E-Date'=>time(),
'Content-Type'=>'application/json; charset=utf-8',
'Origin'=>'https://edu.zmrobo.com',
'Sign'=>$sign,
],
'body'=>json_encode([
'id'=>$curr_id,
'user_id'=>$this->user_id,
])
];
$result = $client->post("https://edu.zmrobo.com/api/curriculum/details",$options);
$result = json_decode($result->getBody()->getContents(),true);
if($result['code'] == -3){
return $this->getCurrDetails($curr_id,$result['sign']);
}else if($result['code'] == 0){
return $result;
}else{
dump($result['msg']);
exit();
}
}
public function getClassDetails($curr_id,$sign = 'null')
{
$client = new Client();
$options = [
'headers'=>[
'User-Agent'=>'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36 Core/1.116.489.400 QQBrowser/13.7.6351.400',
'referer'=>'https://edu.zmrobo.com/courses',
'E-Date'=>time(),
'Content-Type'=>'application/json',
'Origin'=>'https://edu.zmrobo.com',
'Sign'=>$sign,
],
'body'=>json_encode([
'id'=>$curr_id,
'user_id'=>$this->user_id,
'token'=>"7aa22a83fece93ed3e5a3119b085ced9",
])
];
$result = $client->post("https://edu.zmrobo.com/api/class/details",$options);
$result = json_decode($result->getBody()->getContents(),true);
if($result['code'] == -3){
return $this->getClassDetails($curr_id,$result['sign']);
}else if($result['code'] == 0){
return $result;
}else{
dump($result['msg']);
exit();
}
}
private function savetxt(string $file,string $content)
{
if(is_file($file)){
unlink($file);
}
$myfile = fopen($file, "w");
fwrite($myfile, $content);
fclose($myfile);
// dump('已保存文本内容:'.$file);
}
}

34
app/command/account.php Normal file
View File

@@ -0,0 +1,34 @@
<?php
declare (strict_types = 1);
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use Curl\Curl;
use app\kernel\Lebolebo\Account as a;
use app\kernel\Lebolebo\Curriculum;
class account extends Command
{
protected function configure()
{
// 指令配置
$this->setName('account')
->setDescription('the account command');
}
protected function execute(Input $input, Output $output)
{
$account = new a();
dump($account);
dump($account->login('13088393927','393927'));
// 指令输出
$output->writeln('account');
}
}

42
app/command/test.php Normal file
View File

@@ -0,0 +1,42 @@
<?php
declare (strict_types = 1);
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use Curl\Curl;
use Aria2;
class test extends Command
{
protected function configure()
{
// 指令配置
$this->setName('test')
->setDescription('the test command');
}
protected function execute(Input $input, Output $output)
{
$aria2 = new Aria2('http://127.0.0.1:16800/jsonrpc');
try {
// 获取所有活动的下载任务
$activeDownloads = $aria2->getGlobalStat();
dump('正在下载的任务数量:',intval($activeDownloads['result']['numWaiting']));
// dump('等待下载的任务数量:',$waitingCount);
} catch (Exception $e) {
dump($e);
}
// 指令输出
// $output->writeln('test');
}
}

17
app/common.php Normal file
View File

@@ -0,0 +1,17 @@
<?php
// 应用公共文件
function store_path(string $disk = 'local')
{
return config('filesystem.disks.'.$disk.'.root');
}
function bytesToSize($a,int $decimals = 2){
$d = [" B", " KB", " MB", " GB", " TB", " PB"];
$e = 1024;
for ($b = 0; $b < count($d); $b++) {
if ($a < $e) {
$ret = $b == 0 ? $a : number_format($a,$decimals);
return $ret . $d[$b];
}
$a /= $e;
}
}

17
app/controller/Index.php Normal file
View File

@@ -0,0 +1,17 @@
<?php
namespace app\controller;
use app\BaseController;
class Index extends BaseController
{
public function index()
{
return '<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:) </h1><p> ThinkPHP V' . \think\facade\App::version() . '<br/><span style="font-size:30px;">16载初心不改 - 你值得信赖的PHP框架</span></p><span style="font-size:25px;">[ V6.0 版本由 <a href="https://www.yisu.com/" target="yisu">亿速云</a> 独家赞助发布 ]</span></div><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="ee9b1aa918103c4fc"></think>';
}
public function hello($name = 'ThinkPHP6')
{
return 'hello,' . $name;
}
}

116
app/controller/Test.php Normal file
View File

@@ -0,0 +1,116 @@
<?php
declare (strict_types = 1);
namespace app\controller;
use Curl\Curl;
use app\kernel\Lebolebo\Account;
use app\kernel\Lebolebo\Curriculum;
class Test
{
public function login()
{
$account = new Account();
dump($account);
dump($account->login('13088393927','HIMIsm1yxpt4'));
}
public function index()
{
$savepath = store_path() . '/lebolebo/';
$curl = new Curl();
$curr = new Curriculum();
$course = $curr->list(0);
foreach ($course['data']['list'] as $list){
$c = $savepath . $list['courseName'];
is_dir($c) || mkdir($c);
dump($curr->course($list['courseCode']));
$detail = $curr->detail($list['id']);
dump($detail);
$courseCover = $c . '/courseCover' . '.png';
is_file($courseCover) || $curl->download($detail['data']['courseCover'],$courseCover);
$d = $curr->courseUnitList($list['courseCode']);
$courseUnits = $d['data']['courseUnit'];
foreach ($courseUnits as $courseUnit){
$courseUnitName = $c . '/' . str_ireplace('/','-',$courseUnit['courseUnitName']);
if(!is_dir($t)){
dump($t);
mkdir($t);
}
$selectByCourseUnits = $curr->selectByCourseUnits($courseUnit['courseCode'],$courseUnit['courseUnitCode']);
foreach ($selectByCourseUnits['data'] as $selectByCourseUnit){
$sessionName = $courseUnitName . '/' . $selectByCourseUnit['sessionName'];
if(!is_dir($sessionName)){
dump($sessionName);
mkdir($sessionName,0755,true);
}
$t = $curr->selectByCourseSessionCode($selectByCourseUnit['courseSessionCode']);
// 0: {type: 1, des: "PPT-HTML"}
// 1: {type: 2, des: "讲义"}
// 2: {type: 3, des: "课前预习"}
// 3: {type: 4, des: "测一测"}
// 4: {type: 5, des: "玩一玩"}
// 5: {type: 6, des: "试一试"}
// 6: {type: 9, des: "知识点"}
// 7: {type: 10, des: "名人名言"}
// 8: {type: 11, des: "录播课"}
// 9: {type: 13, des: "教辅"}
// 10: {type: 14, des: "备课"}
// 11: {type: 15, des: "课程内容"}
// 12: {type: 16, des: "课后拓展"}
// 13: {type: 18, des: "素养目标"}
$ts = $t['data'];
foreach ($ts as $kk ){
switch ($kk['resourceType']) {
case '1':// PPT-HTML
if(!isset($kk['content'])){
continue;
}
$filename = $kk['content']['fileName'];
$name = $kk['content']['fileUrl'];
if(!is_file($sessionName . '/' . $filename)){
$curl->download($name,$sessionName . '/' . $filename);
}
break;
case '2':
break;
case '3':
break;
case '4':
break;
case '5':
break;
case '6':
break;
case '9':
break;
case '10':
break;
case '11':
break;
case '13':
break;
case '14':
break;
case '15':
break;
case '16':
break;
case '18':
break;
default:
break;
}
// break;
}
}
}
// break;
}
// dump($course);
}
public function __call($method,$args)
{
dump('没有'.$method);
}
}

17
app/event.php Normal file
View File

@@ -0,0 +1,17 @@
<?php
// 事件定义文件
return [
'bind' => [
],
'listen' => [
'AppInit' => [],
'HttpRun' => [],
'HttpEnd' => [],
'LogLevel' => [],
'LogWrite' => [],
],
'subscribe' => [
],
];

View File

@@ -0,0 +1,36 @@
<?php
namespace app\kernel\Lebolebo;
use GuzzleHttp\Client;
class Account
{
protected $client;
public function __construct()
{
$this->client = new Client([
'timeout' => 10,
]);
}
public function login(string $username,string $password)
{
$url = 'https://api-manage2.shengtongedu.cn/st-permission-server/saas/account/login';
$options = [
'body'=>json_encode([
'campusIdList'=>['1863'],
'loginCode'=>$username,
'loginPassword'=>md5($password),
'platform'=>'OMO_WEB',
]),
'headers'=>[
'user-agent'=>'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.196.400 QQBrowser/11.7.5286.400',
'platform'=>'OMO_WEB',
'content-type'=>'application/json; charset=utf-8',
]
];
$result = $this->client->post($url,$options);
return json_decode($result->getBody()->getContents(),true);
}
}

View File

@@ -0,0 +1,173 @@
<?php
namespace app\kernel\Lebolebo;
use GuzzleHttp\Client;
use think\facade\Cache;
class Curriculum
{
protected $client;
protected $headers = [
'campusid'=>'1863',
'logincode'=>'13880615958',
'platform'=>'OMO_WEB',
'referer'=>'http://manage.shengtongedu.cn/',
'token'=>'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2ODE4MDAxMTcsInVzZXJDb2RlIjoiMTMwODgzOTM5MjcifQ.Wy61_ITLuag4JwYLhAOosEBz2Fsw-hCgGrrF-rgoQZM',
'user-agent'=>'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.196.400 QQBrowser/11.7.5286.400',
'content-type'=>'application/json; charset=utf-8',
'origin'=>'http://manage.shengtongedu.cn',
];
protected $config = [
'cache_time'=>86400
];
public function setHeader(string $key,string $value)
{
$this->headers[$key] = $value;
}
public function __construct()
{
$this->client = new Client([
'timeout' => 30,
]);
}
public function list(int $page = 0)
{
$url = 'https://api-manage2.shengtongedu.cn/st-course-server/manage/course/coursePageListV3';
$options = [
'body'=>json_encode([
'campusIdList'=>["1863"],
'pageNum'=>$page,
'pageSize'=>200,
'platform'=>"OMO_WEB",
'total'=>101,
]),
'headers'=>$this->headers
];
$result = $this->client->post($url,$options);
return json_decode($result->getBody()->getContents(),true);
}
public function getVideoUrl($videoId)
{
$key = 'lebolebo_curriculum_getVideoUrl_' . $videoId;
// if(($data = Cache::get($key,null)) !== null ){
// return $data;
// }
$url = 'https://api-manage2.shengtongedu.cn/st-msg-server/msg/bjy/getVideoUrl';
$options = [
'body'=>json_encode([
'campusIdList'=>["1863"],
'platform'=>"OMO_WEB",
'companyId'=>'139',
'videoId'=>$videoId,
]),
'headers'=>$this->headers
];
$result = $this->client->post($url,$options);
$d = json_decode($result->getBody()->getContents(),true);
Cache::set($key,$d,$this->config['cache_time']);
return $d;
}
public function courseUnitList(string $courseCode)
{
$key = 'lebolebo_curriculum_courseUnitList_' . $courseCode;
if(($data = Cache::get($key,null)) !== null ){
return $data;
}
$url = 'https://api-manage2.shengtongedu.cn/st-course-server/manage/course/unit/courseUnitList';
$options = [
'body'=>json_encode([
'campusIdList'=>["1863"],
'platform'=>"OMO_WEB",
'courseCode'=>$courseCode,
]),
'headers'=>$this->headers
];
$result = $this->client->post($url,$options);
$d = json_decode($result->getBody()->getContents(),true);
Cache::set($key,$d,$this->config['cache_time']);
return $d;
}
public function selectByCourseSessionCode(string $courseSessionCode)
{
$key = 'lebolebo_curriculum_selectByCourseSessionCode_' . $courseSessionCode;
if(($data = Cache::get($key,null)) !== null ){
return $data;
}
$url = 'https://api-manage2.shengtongedu.cn/st-course-server/manage/course/resource/selectByCourseSessionCode';
$options = [
'body'=>json_encode([
'campusIdList'=>["1863"],
'platform'=>"OMO_WEB",
'courseSessionCode'=>$courseSessionCode,
]),
'headers'=>$this->headers
];
$result = $this->client->post($url,$options);
$d = json_decode($result->getBody()->getContents(),true);
Cache::set($key,$d,$this->config['cache_time']);
return $d;
}
public function selectByCourseUnits(string $courseCode,string $courseUnitCode)
{
$key = 'lebolebo_curriculum_selectByCourseUnits_' . $courseCode . $courseUnitCode;
if(($data = Cache::get($key,null)) !== null ){
return $data;
}
$url = 'https://api-manage2.shengtongedu.cn/st-course-server/manage/course/sesson/selectByCourseUnits';
$options = [
'body'=>json_encode([
'campusIdList'=>["1863"],
'platform'=>"OMO_WEB",
'courseCode'=>$courseCode,
'courseUnitCode'=>$courseUnitCode
]),
'headers'=>$this->headers
];
$result = $this->client->post($url,$options);
$d = json_decode($result->getBody()->getContents(),true);
Cache::set($key,$d,$this->config['cache_time']);
return $d;
}
public function detail(int $id)
{
$key = 'lebolebo_curriculum_detail_' . $id;
if(($data = Cache::get($key,null)) !== null ){
return $data;
}
$url = 'https://api-manage2.shengtongedu.cn/st-course-server/manage/course/detailV2';
$options = [
'body'=>json_encode([
'campusIdList'=>["1863"],
'platform'=>"OMO_WEB",
'id'=>$id,
]),
'headers'=>$this->headers
];
$result = $this->client->post($url,$options);
$d = json_decode($result->getBody()->getContents(),true);
Cache::set($key,$d,$this->config['cache_time']);
return $d;
}
public function course(string $code)
{
$key = 'lebolebo_curriculum_course_'.$code;
if(($data = Cache::get($key,null)) !== null ){
return $data;
}
$url = 'https://api-manage2.shengtongedu.cn/st-course-server/manage/course/unit/courseUnitList';
$options = [
'body'=>json_encode([
'campusIdList'=>["1863"],
'platform'=>"OMO_WEB",
'courseCode'=>$code,
]),
'headers'=>$this->headers
];
$result = $this->client->post($url,$options);
$d = json_decode($result->getBody()->getContents(),true);
Cache::set($key,$d,$this->config['cache_time']);
return $d;
}
}

10
app/middleware.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
// 全局中间件定义文件
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
// \think\middleware\SessionInit::class
];

9
app/provider.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
use app\ExceptionHandle;
use app\Request;
// 容器Provider定义文件
return [
'think\Request' => Request::class,
'think\exception\Handle' => ExceptionHandle::class,
];

9
app/service.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
use app\AppService;
// 系统服务定义文件
// 服务在完成全局初始化之后执行
return [
AppService::class,
];