mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-23 03:50:56 +08:00
Merge branch 'master' of https://gitee.com/koogua/course-tencent-cloud
This commit is contained in:
commit
d65e4cab43
24
CHANGELOG.md
24
CHANGELOG.md
@ -1,3 +1,27 @@
|
||||
### [v1.6.2](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.1)(2023-01-12)
|
||||
|
||||
- 增加ServerMonitor监控指标配置
|
||||
- 同步更新腾讯云短信内容规则
|
||||
- 文章和问答增加评论开关属性
|
||||
- 修正视频记忆播放无效问题
|
||||
- 升级composer包版本
|
||||
- 优化Repo查询默认排序
|
||||
- 优化管理后台细节
|
||||
- 优化二维码输出
|
||||
- 优化评分检查
|
||||
|
||||
### [v1.6.1](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.1)(2022-12-12)
|
||||
|
||||
- 富文本编辑器增加粘贴图片和远程图片本地化
|
||||
- 修正用户通知标记为已读,计数不归零问题
|
||||
- 修正播放器中央按钮显示问题
|
||||
- 优化腾讯云播放地址鉴权参数
|
||||
- 优化热门作者,答主和问题
|
||||
- 优化学员学习记录显示
|
||||
- 优化表单数据提交体验
|
||||
- 优化单章节层级显示
|
||||
- 优化ServerInfo类
|
||||
|
||||
### [v1.6.0](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.0)(2022-10-26)
|
||||
|
||||
- 播放器中间增加大号播放按钮
|
||||
|
@ -60,7 +60,6 @@ class DeliverTask extends Task
|
||||
break;
|
||||
default:
|
||||
$this->noMatchedHandler($order);
|
||||
break;
|
||||
}
|
||||
|
||||
$order->status = OrderModel::STATUS_FINISHED;
|
||||
|
@ -10,7 +10,7 @@ namespace App\Console\Tasks;
|
||||
use App\Library\Benchmark;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Services\Logic\Notice\External\DingTalk\ServerMonitor as ServerMonitorNotice;
|
||||
use App\Services\Search\UserSearcher;
|
||||
use App\Services\Search\CourseSearcher;
|
||||
use GatewayClient\Gateway;
|
||||
|
||||
class ServerMonitorTask extends Task
|
||||
@ -53,9 +53,13 @@ class ServerMonitorTask extends Task
|
||||
|
||||
$load = sys_getloadavg();
|
||||
|
||||
if ($load[1] > $cpuCount * 0.8) {
|
||||
$limit = $this->getConfig()->path('server_monitor.cpu', 0.8);
|
||||
|
||||
if ($load[1] > $cpuCount * $limit) {
|
||||
return sprintf("cpu负载超过%s", $load[1]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function checkMemory()
|
||||
@ -64,25 +68,29 @@ class ServerMonitorTask extends Task
|
||||
|
||||
$total = null;
|
||||
|
||||
if (preg_match('/MemTotal\:\s+(\d+) kB/', $memInfo, $totalMatches)) {
|
||||
if (preg_match('/MemTotal:\s+(\d+) kB/', $memInfo, $totalMatches)) {
|
||||
$total = $totalMatches[1];
|
||||
}
|
||||
|
||||
if ($total === null) return;
|
||||
if ($total === null) return null;
|
||||
|
||||
$available = null;
|
||||
|
||||
if (preg_match('/MemAvailable\:\s+(\d+) kB/', $memInfo, $avaMatches)) {
|
||||
if (preg_match('/MemAvailable:\s+(\d+) kB/', $memInfo, $avaMatches)) {
|
||||
$available = $avaMatches[1];
|
||||
}
|
||||
|
||||
if ($available === null) return;
|
||||
if ($available === null) return null;
|
||||
|
||||
$left = 100 * ($available / $total);
|
||||
|
||||
if ($left < 20) {
|
||||
$limit = $this->getConfig()->path('server_monitor.memory', 10);
|
||||
|
||||
if ($left < $limit) {
|
||||
return sprintf("memory剩余不足%s%%", round($left));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function checkDisk()
|
||||
@ -92,9 +100,13 @@ class ServerMonitorTask extends Task
|
||||
|
||||
$left = 100 * $free / $total;
|
||||
|
||||
if ($left < 20) {
|
||||
$limit = $this->getConfig()->path('server_monitor.disk', 20);
|
||||
|
||||
if ($left < $limit) {
|
||||
return sprintf("disk剩余不足%s%%", round($left));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function checkMysql()
|
||||
@ -111,8 +123,8 @@ class ServerMonitorTask extends Task
|
||||
|
||||
$elapsedTime = $benchmark->getElapsedTime();
|
||||
|
||||
if ($user === false) {
|
||||
return sprintf("mysql查询失败");
|
||||
if (!$user) {
|
||||
return "mysql查询失败";
|
||||
}
|
||||
|
||||
if ($elapsedTime > 1) {
|
||||
@ -120,8 +132,10 @@ class ServerMonitorTask extends Task
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return sprintf("mysql可能存在异常");
|
||||
return "mysql可能存在异常";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function checkRedis()
|
||||
@ -139,7 +153,7 @@ class ServerMonitorTask extends Task
|
||||
$elapsedTime = $benchmark->getElapsedTime();
|
||||
|
||||
if (empty($site)) {
|
||||
return sprintf("redis查询失败");
|
||||
return "redis查询失败";
|
||||
}
|
||||
|
||||
if ($elapsedTime > 1) {
|
||||
@ -147,8 +161,10 @@ class ServerMonitorTask extends Task
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return sprintf("redis可能存在异常");
|
||||
return "redis可能存在异常";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function checkXunsearch()
|
||||
@ -159,16 +175,16 @@ class ServerMonitorTask extends Task
|
||||
|
||||
$benchmark->start();
|
||||
|
||||
$searcher = new UserSearcher();
|
||||
$searcher = new CourseSearcher();
|
||||
|
||||
$user = $searcher->search('id:10000');
|
||||
$user = $searcher->search('id:1');
|
||||
|
||||
$benchmark->stop();
|
||||
|
||||
$elapsedTime = $benchmark->getElapsedTime();
|
||||
|
||||
if (empty($user)) {
|
||||
return sprintf("xunsearch搜索失败");
|
||||
return "xunsearch搜索失败";
|
||||
}
|
||||
|
||||
if ($elapsedTime > 1) {
|
||||
@ -176,8 +192,10 @@ class ServerMonitorTask extends Task
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return sprintf("xunsearch可能存在异常");
|
||||
return "xunsearch可能存在异常";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function checkWebsocket()
|
||||
@ -203,8 +221,10 @@ class ServerMonitorTask extends Task
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return sprintf("websocket可能存在异常");
|
||||
return "websocket可能存在异常";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function getCpuCount()
|
||||
|
@ -48,10 +48,12 @@ class SyncLearningTask extends Task
|
||||
*/
|
||||
protected function handleLearning($itemKey)
|
||||
{
|
||||
$cache = $this->getCache();
|
||||
|
||||
/**
|
||||
* @var LearningModel $cacheLearning
|
||||
*/
|
||||
$cacheLearning = $this->cache->get($itemKey);
|
||||
$cacheLearning = $cache->get($itemKey);
|
||||
|
||||
if (!$cacheLearning) return;
|
||||
|
||||
@ -76,7 +78,7 @@ class SyncLearningTask extends Task
|
||||
$this->updateChapterUser($dbLearning);
|
||||
}
|
||||
|
||||
$this->cache->delete($itemKey);
|
||||
$cache->delete($itemKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +113,12 @@ class SyncLearningTask extends Task
|
||||
|
||||
$progress = floor(100 * $chapterUser->duration / $duration);
|
||||
|
||||
$chapterUser->position = floor($learning->position);
|
||||
/**
|
||||
* 过于接近结束位置当作已结束处理,播放位置为起点0
|
||||
*/
|
||||
$playPosition = $duration - $learning->position > 10 ? floor($learning->position) : 0;
|
||||
|
||||
$chapterUser->position = $playPosition;
|
||||
$chapterUser->progress = $progress < 100 ? $progress : 100;
|
||||
$chapterUser->consumed = $chapterUser->duration > 0.3 * $duration ? 1 : 0;
|
||||
|
||||
|
@ -9,7 +9,6 @@ namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Builders\ArticleList as ArticleListBuilder;
|
||||
use App\Builders\ReportList as ReportListBuilder;
|
||||
use App\Caches\Article as ArticleCache;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Library\Utils\Word as WordUtil;
|
||||
use App\Models\Article as ArticleModel;
|
||||
@ -27,7 +26,6 @@ use App\Services\Logic\Article\XmTagList as XmTagListService;
|
||||
use App\Services\Logic\Notice\Internal\ArticleApproved as ArticleApprovedNotice;
|
||||
use App\Services\Logic\Notice\Internal\ArticleRejected as ArticleRejectedNotice;
|
||||
use App\Services\Logic\Point\History\ArticlePost as ArticlePostPointHistory;
|
||||
use App\Services\Sync\ArticleIndex as ArticleIndexSync;
|
||||
use App\Validators\Article as ArticleValidator;
|
||||
|
||||
class Article extends Service
|
||||
@ -209,8 +207,6 @@ class Article extends Service
|
||||
|
||||
$this->saveDynamicAttrs($article);
|
||||
|
||||
$this->rebuildArticleIndex($article);
|
||||
|
||||
$owner = $this->findUser($article->owner_id);
|
||||
|
||||
$this->recountUserArticles($owner);
|
||||
@ -230,8 +226,6 @@ class Article extends Service
|
||||
|
||||
$this->saveDynamicAttrs($article);
|
||||
|
||||
$this->rebuildArticleIndex($article);
|
||||
|
||||
$owner = $this->findUser($article->owner_id);
|
||||
|
||||
$this->recountUserArticles($owner);
|
||||
@ -251,8 +245,6 @@ class Article extends Service
|
||||
|
||||
$this->saveDynamicAttrs($article);
|
||||
|
||||
$this->rebuildArticleIndex($article);
|
||||
|
||||
$owner = $this->findUser($article->owner_id);
|
||||
|
||||
$this->recountUserArticles($owner);
|
||||
@ -292,7 +284,6 @@ class Article extends Service
|
||||
|
||||
if ($type == 'approve') {
|
||||
|
||||
$this->rebuildArticleIndex($article);
|
||||
$this->handleArticlePostPoint($article);
|
||||
$this->handleArticleApprovedNotice($article, $sender);
|
||||
|
||||
@ -403,20 +394,6 @@ class Article extends Service
|
||||
$user->update();
|
||||
}
|
||||
|
||||
protected function rebuildArticleCache(ArticleModel $article)
|
||||
{
|
||||
$cache = new ArticleCache();
|
||||
|
||||
$cache->rebuild($article->id);
|
||||
}
|
||||
|
||||
protected function rebuildArticleIndex(ArticleModel $article)
|
||||
{
|
||||
$sync = new ArticleIndexSync();
|
||||
|
||||
$sync->addItem($article->id);
|
||||
}
|
||||
|
||||
protected function handleArticlePostPoint(ArticleModel $article)
|
||||
{
|
||||
if ($article->published != ArticleModel::PUBLISH_APPROVED) return;
|
||||
|
@ -8,7 +8,6 @@
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Builders\CourseList as CourseListBuilder;
|
||||
use App\Caches\Course as CourseCache;
|
||||
use App\Caches\CourseCategoryList as CourseCategoryListCache;
|
||||
use App\Caches\CourseRelatedList as CourseRelatedListCache;
|
||||
use App\Caches\CourseTeacherList as CourseTeacherListCache;
|
||||
@ -25,7 +24,6 @@ use App\Repos\CourseCategory as CourseCategoryRepo;
|
||||
use App\Repos\CourseRelated as CourseRelatedRepo;
|
||||
use App\Repos\CourseUser as CourseUserRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
use App\Services\Sync\CourseIndex as CourseIndexSync;
|
||||
use App\Validators\Course as CourseValidator;
|
||||
use App\Validators\CourseOffline as CourseOfflineValidator;
|
||||
|
||||
@ -399,20 +397,6 @@ class Course extends Service
|
||||
return $validator->checkCourse($id);
|
||||
}
|
||||
|
||||
protected function rebuildCourseCache(CourseModel $course)
|
||||
{
|
||||
$cache = new CourseCache();
|
||||
|
||||
$cache->rebuild($course->id);
|
||||
}
|
||||
|
||||
protected function rebuildCourseIndex(CourseModel $course)
|
||||
{
|
||||
$sync = new CourseIndexSync();
|
||||
|
||||
$sync->addItem($course->id);
|
||||
}
|
||||
|
||||
protected function saveTeachers(CourseModel $course, $teacherIds)
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
@ -101,7 +101,6 @@ class Package extends Service
|
||||
$data = [];
|
||||
|
||||
$data['title'] = $validator->checkTitle($post['title']);
|
||||
$data['summary'] = $validator->checkSummary($post['summary']);
|
||||
|
||||
$package = new PackageModel();
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Caches\Page as PageCache;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Models\Page as PageModel;
|
||||
use App\Repos\Page as PageRepo;
|
||||
@ -53,8 +52,6 @@ class Page extends Service
|
||||
|
||||
$page->create($data);
|
||||
|
||||
$this->rebuildPageCache($page);
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
@ -96,8 +93,6 @@ class Page extends Service
|
||||
|
||||
$page->update($data);
|
||||
|
||||
$this->rebuildPageCache($page);
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
@ -109,8 +104,6 @@ class Page extends Service
|
||||
|
||||
$page->update();
|
||||
|
||||
$this->rebuildPageCache($page);
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
@ -122,18 +115,9 @@ class Page extends Service
|
||||
|
||||
$page->update();
|
||||
|
||||
$this->rebuildPageCache($page);
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
protected function rebuildPageCache(PageModel $page)
|
||||
{
|
||||
$cache = new PageCache();
|
||||
|
||||
$cache->rebuild($page->id);
|
||||
}
|
||||
|
||||
protected function findOrFail($id)
|
||||
{
|
||||
$validator = new PageValidator();
|
||||
|
@ -9,7 +9,6 @@ namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Builders\QuestionList as QuestionListBuilder;
|
||||
use App\Builders\ReportList as ReportListBuilder;
|
||||
use App\Caches\Question as QuestionCache;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Models\Category as CategoryModel;
|
||||
use App\Models\Question as QuestionModel;
|
||||
@ -26,7 +25,6 @@ use App\Services\Logic\Point\History\QuestionPost as QuestionPostPointHistory;
|
||||
use App\Services\Logic\Question\QuestionDataTrait;
|
||||
use App\Services\Logic\Question\QuestionInfo as QuestionInfoService;
|
||||
use App\Services\Logic\Question\XmTagList as XmTagListService;
|
||||
use App\Services\Sync\QuestionIndex as QuestionIndexSync;
|
||||
use App\Validators\Question as QuestionValidator;
|
||||
|
||||
class Question extends Service
|
||||
@ -191,8 +189,6 @@ class Question extends Service
|
||||
|
||||
$this->saveDynamicAttrs($question);
|
||||
|
||||
$this->rebuildQuestionIndex($question);
|
||||
|
||||
$owner = $this->findUser($question->owner_id);
|
||||
|
||||
$this->recountUserQuestions($owner);
|
||||
@ -212,8 +208,6 @@ class Question extends Service
|
||||
|
||||
$this->saveDynamicAttrs($question);
|
||||
|
||||
$this->rebuildQuestionIndex($question);
|
||||
|
||||
$owner = $this->findUser($question->owner_id);
|
||||
|
||||
$this->recountUserQuestions($owner);
|
||||
@ -231,8 +225,6 @@ class Question extends Service
|
||||
|
||||
$question->update();
|
||||
|
||||
$this->rebuildQuestionIndex($question);
|
||||
|
||||
$owner = $this->findUser($question->owner_id);
|
||||
|
||||
$this->recountUserQuestions($owner);
|
||||
@ -268,7 +260,6 @@ class Question extends Service
|
||||
|
||||
if ($type == 'approve') {
|
||||
|
||||
$this->rebuildQuestionIndex($question);
|
||||
$this->handleQuestionPostPoint($question);
|
||||
$this->handleQuestionApprovedNotice($question, $sender);
|
||||
|
||||
@ -379,20 +370,6 @@ class Question extends Service
|
||||
$user->update();
|
||||
}
|
||||
|
||||
protected function rebuildQuestionCache(QuestionModel $question)
|
||||
{
|
||||
$cache = new QuestionCache();
|
||||
|
||||
$cache->rebuild($question->id);
|
||||
}
|
||||
|
||||
protected function rebuildQuestionIndex(QuestionModel $question)
|
||||
{
|
||||
$sync = new QuestionIndexSync();
|
||||
|
||||
$sync->addItem($question->id);
|
||||
}
|
||||
|
||||
protected function handleQuestionPostPoint(QuestionModel $question)
|
||||
{
|
||||
if ($question->published != QuestionModel::PUBLISH_APPROVED) return;
|
||||
|
@ -87,7 +87,6 @@ class Topic extends Service
|
||||
$data = [];
|
||||
|
||||
$data['title'] = $validator->checkTitle($post['title']);
|
||||
$data['summary'] = $validator->checkSummary($post['summary']);
|
||||
|
||||
$topic = new TopicModel();
|
||||
|
||||
|
@ -12,12 +12,6 @@
|
||||
<input class="layui-input" type="text" name="title" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">简介</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea class="layui-textarea" name="summary"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"></label>
|
||||
<div class="layui-input-block">
|
||||
|
@ -64,7 +64,7 @@
|
||||
<input type="radio" name="template[order_finish][enabled]" value="0" title="否" {% if template.order_finish.enabled == "0" %}checked="checked"{% endif %}>
|
||||
</td>
|
||||
<td><input class="layui-input" type="text" name="template[order_finish][id]" value="{{ template.order_finish.id }}" lay-verify="required"></td>
|
||||
<td><input id="tc-order-finish" class="layui-input" type="text" value="下单成功,商品名称:{1},订单序号:{2},订单金额:¥{3}" readonly="readonly"></td>
|
||||
<td><input id="tc-order-finish" class="layui-input" type="text" value="下单成功,商品名称:{1},订单序号:{2},订单金额:{3}元" readonly="readonly"></td>
|
||||
<td><span class="kg-copy layui-btn" data-clipboard-target="#tc-order-finish">复制</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -84,7 +84,7 @@
|
||||
<input type="radio" name="template[refund_finish][enabled]" value="0" title="否" {% if template.refund_finish.enabled == "0" %}checked="checked"{% endif %}>
|
||||
</td>
|
||||
<td><input class="layui-input" type="text" name="template[refund_finish][id]" value="{{ template.refund_finish.id }}" lay-verify="required"></td>
|
||||
<td><input id="tc-refund-finish" class="layui-input" type="text" value="退款成功,商品名称:{1},退款序号:{2},退款金额:¥{3}" readonly="readonly"></td>
|
||||
<td><input id="tc-refund-finish" class="layui-input" type="text" value="退款成功,商品名称:{1},退款序号:{2},退款金额:{3}元" readonly="readonly"></td>
|
||||
<td><span class="kg-copy layui-btn" data-clipboard-target="#tc-refund-finish">复制</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -32,6 +32,8 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in pager.items %}
|
||||
{% set duration = item.duration > 0 ? item.duration|duration : 'N/A' %}
|
||||
{% set active_time = item.active_time > 0 ? date('Y-m-d H:i:s',item.active_time) : 'N/A' %}
|
||||
<tr>
|
||||
<td>
|
||||
<p class="layui-elip">课程:{{ item.course.title }}</p>
|
||||
@ -41,8 +43,8 @@
|
||||
<p>类型:{{ client_type_info(item.client_type) }}</p>
|
||||
<p>地址:<a href="javascript:" class="kg-ip2region" title="查看位置" data-ip="{{ item.client_ip }}">{{ item.client_ip }}</a></p>
|
||||
</td>
|
||||
<td>{{ item.duration|duration }}</td>
|
||||
<td>{{ date('Y-m-d H:i:s',item.active_time) }}</td>
|
||||
<td>{{ duration }}</td>
|
||||
<td>{{ active_time }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -12,12 +12,6 @@
|
||||
<input class="layui-input" type="text" name="title" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">简介</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea class="layui-textarea" name="summary"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"></label>
|
||||
<div class="layui-input-block">
|
||||
|
@ -71,11 +71,15 @@
|
||||
<input class="layui-input" name="apply_note" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item kg-center">
|
||||
<button class="layui-btn" lay-submit="true" lay-filter="go">提交申请</button>
|
||||
<input type="hidden" name="trade_amount" value="{{ trade.amount }}">
|
||||
<input type="hidden" name="refund_amount" value="{{ confirm.refund_amount }}">
|
||||
<input type="hidden" name="service_fee" value="{{ confirm.service_fee }}">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"></label>
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
<input type="hidden" name="trade_amount" value="{{ trade.amount }}">
|
||||
<input type="hidden" name="refund_amount" value="{{ confirm.refund_amount }}">
|
||||
<input type="hidden" name="service_fee" value="{{ confirm.service_fee }}">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@ -73,18 +73,19 @@ class PublicController extends \Phalcon\Mvc\Controller
|
||||
{
|
||||
$text = $this->request->getQuery('text', 'string');
|
||||
$size = $this->request->getQuery('size', 'int', 320);
|
||||
$margin = $this->request->getQuery('margin', 'int', 10);
|
||||
|
||||
$text = urldecode($text);
|
||||
|
||||
$qrCode = new QrCode($text);
|
||||
|
||||
$qrCode->setSize($size);
|
||||
$qrCode->setMargin($margin);
|
||||
|
||||
$qrCode->getContentType();
|
||||
$this->response->setContentType('image/png');
|
||||
$this->response->setContent($qrCode->writeString());
|
||||
|
||||
echo $qrCode->writeString();
|
||||
|
||||
exit;
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
{% set sort_val = request.get('sort','trim','latest') %}
|
||||
{% set pager_url = url({'for':'home.article.pager'}, params) %}
|
||||
{% set top_authors_url = url({'for':'home.widget.top_authors'}) %}
|
||||
{% set top_authors_url = url({'for':'home.widget.top_authors'},{'limit':5}) %}
|
||||
{% set my_tags_url = url({'for':'home.widget.my_tags'},{'type':'article'}) %}
|
||||
|
||||
<div class="breadcrumb">
|
||||
|
@ -1,23 +1,35 @@
|
||||
{%- macro show_lesson_list(chapter) %}
|
||||
<ul class="sidebar-lesson-list">
|
||||
{% for lesson in chapter.children %}
|
||||
{% set url = url({'for':'home.chapter.show','id':lesson.id}) %}
|
||||
{% set active = (chapter.id == lesson.id) ? 'active' : 'normal' %}
|
||||
<li class="lesson-title layui-elip">
|
||||
{% if lesson.me.owned == 1 %}
|
||||
<a class="{{ active }}" href="{{ url }}" title="{{ lesson.title }}">{{ lesson.title }}</a>
|
||||
{% else %}
|
||||
<span class="deny" title="{{ lesson.title }}">{{ lesson.title }}</span>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{%- endmacro %}
|
||||
|
||||
<div class="layui-card sidebar-card sidebar-chapter">
|
||||
<div class="layui-card-header">课程目录</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="sidebar-chapter-list">
|
||||
{% for item in catalog %}
|
||||
<div class="chapter-title layui-elip">{{ item.title }}</div>
|
||||
<ul class="sidebar-lesson-list">
|
||||
{% for lesson in item.children %}
|
||||
{% set url = url({'for':'home.chapter.show','id':lesson.id}) %}
|
||||
{% set active = (chapter.id == lesson.id) ? 'active' : 'normal' %}
|
||||
<li class="lesson-title layui-elip">
|
||||
{% if lesson.me.owned == 1 %}
|
||||
<a class="{{ active }}" href="{{ url }}" title="{{ lesson.title }}">{{ lesson.title }}</a>
|
||||
{% else %}
|
||||
<span class="deny" title="{{ lesson.title }}">{{ lesson.title }}</span>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if catalog|length > 1 %}
|
||||
<div class="sidebar-chapter-list">
|
||||
{% for item in catalog %}
|
||||
<div class="chapter-title layui-elip">{{ item.title }}</div>
|
||||
<div class="sidebar-lesson-list">
|
||||
{{ show_lesson_list(item) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="sidebar-lesson-list">
|
||||
{{ show_lesson_list(catalog[0]) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
@ -1,3 +1,19 @@
|
||||
{%- macro show_lesson_list(chapter) %}
|
||||
<ul class="lesson-list">
|
||||
{% for lesson in chapter.children %}
|
||||
{% if lesson.model == 1 %}
|
||||
<li class="lesson-item">{{ vod_lesson_info(lesson) }}</li>
|
||||
{% elseif lesson.model == 2 %}
|
||||
<li class="lesson-item">{{ live_lesson_info(lesson) }}</li>
|
||||
{% elseif lesson.model == 3 %}
|
||||
<li class="lesson-item">{{ read_lesson_info(lesson) }}</li>
|
||||
{% elseif lesson.model == 4 %}
|
||||
<li class="lesson-item">{{ offline_lesson_info(lesson) }}</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro vod_lesson_info(lesson) %}
|
||||
{% set url = lesson.me.owned ? url({'for':'home.chapter.show','id':lesson.id}) : '' %}
|
||||
{% set priv = lesson.me.owned ? 'allow' : 'deny' %}
|
||||
@ -87,28 +103,20 @@
|
||||
|
||||
{% set show_all = course.lesson_count < 30 %}
|
||||
|
||||
{% if chapters %}
|
||||
<div class="layui-collapse" lay-accordion="true">
|
||||
{% for chapter in chapters %}
|
||||
{% set show_class = (show_all or loop.first) ? 'layui-show' : '' %}
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">{{ chapter.title }}</h2>
|
||||
<div class="layui-colla-content {{ show_class }}">
|
||||
<ul class="lesson-list">
|
||||
{% for lesson in chapter.children %}
|
||||
{% if lesson.model == 1 %}
|
||||
<li class="lesson-item">{{ vod_lesson_info(lesson) }}</li>
|
||||
{% elseif lesson.model == 2 %}
|
||||
<li class="lesson-item">{{ live_lesson_info(lesson) }}</li>
|
||||
{% elseif lesson.model == 3 %}
|
||||
<li class="lesson-item">{{ read_lesson_info(lesson) }}</li>
|
||||
{% elseif lesson.model == 4 %}
|
||||
<li class="lesson-item">{{ offline_lesson_info(lesson) }}</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% if chapters|length > 0 %}
|
||||
{% if chapters|length > 1 %}
|
||||
<div class="layui-collapse" lay-accordion="true">
|
||||
{% for chapter in chapters %}
|
||||
{% set show_class = (show_all or loop.first) ? 'layui-show' : '' %}
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">{{ chapter.title }}</h2>
|
||||
<div class="layui-colla-content {{ show_class }}">
|
||||
{{ show_lesson_list(chapter) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ show_lesson_list(chapters[0]) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
@ -4,8 +4,8 @@
|
||||
|
||||
{% set sort_val = request.get('sort','trim','latest') %}
|
||||
{% set pager_url = url({'for':'home.question.pager'}, params) %}
|
||||
{% set hot_questions_url = url({'for':'home.widget.hot_questions'}) %}
|
||||
{% set top_answerers_url = url({'for':'home.widget.top_answerers'}) %}
|
||||
{% set hot_questions_url = url({'for':'home.widget.hot_questions'},{'limit':10}) %}
|
||||
{% set top_answerers_url = url({'for':'home.widget.top_answerers'},{'limit':5}) %}
|
||||
{% set my_tags_url = url({'for':'home.widget.my_tags'},{'type':'question'}) %}
|
||||
|
||||
<div class="breadcrumb">
|
||||
|
@ -16,7 +16,7 @@ class AppInfo
|
||||
|
||||
protected $link = 'https://www.koogua.com';
|
||||
|
||||
protected $version = '1.6.0';
|
||||
protected $version = '1.6.2';
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
@ -28,6 +28,8 @@ class AppInfo
|
||||
if (isset($this->{$name})) {
|
||||
return $this->{$name};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -31,13 +31,13 @@ class ServerInfo
|
||||
|
||||
$total = 0;
|
||||
|
||||
if (preg_match('/MemTotal\:\s+(\d+) kB/', $mem, $totalMatches)) {
|
||||
if (preg_match('/MemTotal:\s+(\d+) kB/', $mem, $totalMatches)) {
|
||||
$total = $totalMatches[1];
|
||||
}
|
||||
|
||||
$free = 0;
|
||||
|
||||
if (preg_match('/MemFree\:\s+(\d+) kB/', $mem, $freeMatches)) {
|
||||
if (preg_match('/MemFree:\s+(\d+) kB/', $mem, $freeMatches)) {
|
||||
$free = $freeMatches[1];
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,9 @@ class Answer extends Repository
|
||||
case 'accepted':
|
||||
$orderBy = 'accepted DESC, like_count DESC';
|
||||
break;
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -112,6 +112,9 @@ class Article extends Repository
|
||||
case 'popular':
|
||||
$orderBy = 'score DESC';
|
||||
break;
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -35,6 +35,9 @@ class ArticleFavorite extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -51,6 +51,9 @@ class Audit extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -99,6 +99,9 @@ class Chapter extends Repository
|
||||
*/
|
||||
public function findByFileId($fileId)
|
||||
{
|
||||
/**
|
||||
* @var ChapterVodModel $vod
|
||||
*/
|
||||
$vod = ChapterVodModel::findFirst([
|
||||
'conditions' => 'file_id = :file_id:',
|
||||
'bind' => ['file_id' => $fileId],
|
||||
|
@ -15,7 +15,7 @@ use Phalcon\Mvc\Model;
|
||||
class ChapterLive extends Repository
|
||||
{
|
||||
|
||||
public function paginate($where = [], $sort = 'latest', $page = 1, $limit = 15)
|
||||
public function paginate($where = [], $sort = 'oldest', $page = 1, $limit = 15)
|
||||
{
|
||||
$builder = $this->modelsManager->createBuilder();
|
||||
|
||||
@ -44,6 +44,9 @@ class ChapterLive extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'latest':
|
||||
$orderBy = 'cl.start_time DESC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'cl.start_time ASC';
|
||||
break;
|
||||
|
@ -68,6 +68,9 @@ class Comment extends Repository
|
||||
case 'popular':
|
||||
$orderBy = 'like_count DESC';
|
||||
break;
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -65,6 +65,9 @@ class Consult extends Repository
|
||||
case 'priority':
|
||||
$orderBy = 'priority ASC, id DESC';
|
||||
break;
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -127,6 +127,9 @@ class Course extends Repository
|
||||
case 'popular':
|
||||
$orderBy = 'user_count DESC';
|
||||
break;
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -35,6 +35,9 @@ class CourseFavorite extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -34,6 +34,9 @@ class CourseTopic extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -45,6 +45,9 @@ class CourseUser extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -49,6 +49,9 @@ class Danmu extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -66,6 +66,9 @@ class FlashSale extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -39,6 +39,9 @@ class Learning extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -78,6 +78,9 @@ class Order extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -43,6 +43,9 @@ class Package extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -37,6 +37,9 @@ class Page extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -52,6 +52,9 @@ class PointGift extends Repository
|
||||
case 'popular':
|
||||
$orderBy = 'redeem_count DESC';
|
||||
break;
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -39,6 +39,9 @@ class PointGiftRedeem extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -41,6 +41,9 @@ class PointHistory extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -105,6 +105,9 @@ class Question extends Repository
|
||||
case 'score':
|
||||
$orderBy = 'score DESC';
|
||||
break;
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -35,6 +35,9 @@ class QuestionFavorite extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -53,6 +53,9 @@ class Refund extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -49,6 +49,9 @@ class Report extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -64,6 +64,9 @@ class Review extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -50,6 +50,9 @@ class Tag extends Repository
|
||||
case 'priority':
|
||||
$orderBy = 'priority ASC, id ASC';
|
||||
break;
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -32,6 +32,9 @@ class TagFollow extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -41,6 +41,9 @@ class TeacherConsult extends Repository
|
||||
$builder->andWhere('c.deleted = 0');
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'c.id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'c.id DESC';
|
||||
break;
|
||||
|
@ -43,6 +43,9 @@ class Topic extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -69,6 +69,9 @@ class Trade extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -69,6 +69,9 @@ class User extends Repository
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
case 'oldest':
|
||||
$orderBy = 'id ASC';
|
||||
break;
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
break;
|
||||
|
@ -170,7 +170,7 @@ class DingTalkNotice extends Service
|
||||
|
||||
$result = $content['errcode'] == 0;
|
||||
|
||||
if ($result == false) {
|
||||
if (!$result) {
|
||||
$this->logger->error('Send Message Failed ' . kg_json_encode($content));
|
||||
}
|
||||
|
||||
|
159
app/Services/EditorStorage.php
Normal file
159
app/Services/EditorStorage.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Library\Utils\FileInfo;
|
||||
use App\Models\Upload as UploadModel;
|
||||
use App\Repos\Upload as UploadRepo;
|
||||
use Phalcon\Text;
|
||||
|
||||
class EditorStorage extends Storage
|
||||
{
|
||||
|
||||
public function handle($content)
|
||||
{
|
||||
$content = $this->handleBase64Image($content);
|
||||
$content = $this->handleRemoteImage($content);
|
||||
|
||||
return trim($content);
|
||||
}
|
||||
|
||||
protected function handleBase64Image($content)
|
||||
{
|
||||
$content = preg_replace("/data-ke-src=\"(.*?)\"/", '', $content);
|
||||
|
||||
preg_match_all('/src="(data:image\/(\S+);base64,(\S+))"/U', $content, $matches);
|
||||
|
||||
if (count($matches[3]) > 0) {
|
||||
foreach ($matches[3] as $key => $value) {
|
||||
$imageUrl = $this->uploadBase64Image($matches[3][$key], $matches[2][$key]);
|
||||
$content = str_replace($matches[1][$key], $imageUrl, $content);
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
protected function handleRemoteImage($content)
|
||||
{
|
||||
$baseUrl = $this->getBaseUrl();
|
||||
|
||||
preg_match_all('/<img src="(\S+)"/', $content, $matches);
|
||||
|
||||
if (count($matches[1]) > 0) {
|
||||
foreach ($matches[1] as $key => $value) {
|
||||
if (!Text::startsWith($value, $baseUrl)) {
|
||||
$imageUrl = $this->uploadRemoteImage($value);
|
||||
$content = str_replace($value, $imageUrl, $content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
protected function uploadBase64Image($encodeContent, $extension)
|
||||
{
|
||||
$keyName = $this->generateFileName($extension, '/img/content/');
|
||||
|
||||
$content = base64_decode($encodeContent);
|
||||
|
||||
$md5 = md5($content);
|
||||
|
||||
$uploadRepo = new UploadRepo();
|
||||
|
||||
$upload = $uploadRepo->findByMd5($md5);
|
||||
|
||||
if (!$upload) {
|
||||
|
||||
$uploadPath = $this->putString($keyName, $content);
|
||||
|
||||
if ($uploadPath) {
|
||||
|
||||
$upload = new UploadModel();
|
||||
|
||||
$upload->type = UploadModel::TYPE_CONTENT_IMG;
|
||||
$upload->mime = FileInfo::getMimeTypeByExt($extension);
|
||||
$upload->name = pathinfo($uploadPath, PATHINFO_BASENAME);
|
||||
$upload->size = strlen($content);
|
||||
$upload->path = $uploadPath;
|
||||
$upload->md5 = $md5;
|
||||
|
||||
$upload->create();
|
||||
}
|
||||
|
||||
$imageUrl = $uploadPath ? $this->getImageUrl($uploadPath) : '';
|
||||
|
||||
} else {
|
||||
|
||||
$imageUrl = $this->getImageUrl($upload->path);
|
||||
}
|
||||
|
||||
return $imageUrl;
|
||||
}
|
||||
|
||||
protected function uploadRemoteImage($remoteUrl)
|
||||
{
|
||||
$extension = $this->getImageExtension($remoteUrl);
|
||||
|
||||
$content = file_get_contents($remoteUrl);
|
||||
|
||||
if ($content === false) return $remoteUrl;
|
||||
|
||||
$keyName = $this->generateFileName($extension, '/img/content/');
|
||||
|
||||
$md5 = md5($content);
|
||||
|
||||
$uploadRepo = new UploadRepo();
|
||||
|
||||
$upload = $uploadRepo->findByMd5($md5);
|
||||
|
||||
if (!$upload) {
|
||||
|
||||
$uploadPath = $this->putString($keyName, $content);
|
||||
|
||||
if ($uploadPath) {
|
||||
|
||||
$upload = new UploadModel();
|
||||
|
||||
$upload->type = UploadModel::TYPE_CONTENT_IMG;
|
||||
$upload->mime = FileInfo::getMimeTypeByExt($extension);
|
||||
$upload->name = pathinfo($uploadPath, PATHINFO_BASENAME);
|
||||
$upload->size = strlen($content);
|
||||
$upload->path = $uploadPath;
|
||||
$upload->md5 = $md5;
|
||||
|
||||
$upload->create();
|
||||
}
|
||||
|
||||
$imageUrl = $uploadPath ? $this->getImageUrl($uploadPath) : $remoteUrl;
|
||||
|
||||
} else {
|
||||
|
||||
$imageUrl = $this->getImageUrl($upload->path);
|
||||
}
|
||||
|
||||
return $imageUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 例如:https://abc.com/123.jpg!large,这类不规范地址,需要特殊处理
|
||||
*
|
||||
* @param string $imageUrl
|
||||
* @return string
|
||||
*/
|
||||
protected function getImageExtension($imageUrl)
|
||||
{
|
||||
$path = parse_url($imageUrl, PHP_URL_PATH);
|
||||
|
||||
preg_match('/(\S+)\.(png|gif|jpg|jpeg)/i', $path, $matches);
|
||||
|
||||
return $matches[2] ? strtolower($matches[2]) : 'jpg';
|
||||
}
|
||||
|
||||
}
|
@ -15,11 +15,17 @@ class TopAuthorList extends LogicService
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$limit = $this->request->getQuery('limit', 'int', 10);
|
||||
|
||||
$cache = new TopAuthorListCache();
|
||||
|
||||
$result = $cache->get();
|
||||
$list = $cache->get();
|
||||
|
||||
return $result ?: [];
|
||||
if($limit < count($list)) {
|
||||
$list = array_slice($list, $limit);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,10 +34,8 @@ class AccountLogin extends LogicService
|
||||
$subscribe = $subscribeRepo->findByUserId($userId);
|
||||
|
||||
if ($subscribe) {
|
||||
|
||||
$notice = new WeChatAccountLoginNotice();
|
||||
|
||||
return $notice->handle($subscribe, $params);
|
||||
$notice->handle($subscribe, $params);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ trait PointGiftTrait
|
||||
return $validator->checkPointGift($id);
|
||||
}
|
||||
|
||||
public function checkFlashSaleCache($id)
|
||||
public function checkPointGiftCache($id)
|
||||
{
|
||||
$validator = new PointGiftValidator();
|
||||
|
||||
|
@ -15,11 +15,17 @@ class HotQuestionList extends LogicService
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$limit = $this->request->getQuery('limit', 'int', 10);
|
||||
|
||||
$cache = new HotQuestionListCache();
|
||||
|
||||
$result = $cache->get();
|
||||
$list = $cache->get();
|
||||
|
||||
return $result ?: [];
|
||||
if($limit < count($list)) {
|
||||
$list = array_slice($list, $limit);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,11 +15,17 @@ class TopAnswererList extends LogicService
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$limit = $this->request->getQuery('limit', 'int', 10);
|
||||
|
||||
$cache = new TopAnswererListCache();
|
||||
|
||||
$result = $cache->get();
|
||||
$list = $cache->get();
|
||||
|
||||
return $result ?: [];
|
||||
if($limit < count($list)) {
|
||||
$list = array_slice($list, $limit);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,12 @@ class NotificationRead extends LogicService
|
||||
{
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
if ($user->notice_count == 0) return;
|
||||
|
||||
$user->notice_count = 0;
|
||||
|
||||
$user->update();
|
||||
|
||||
$notifyRepo = new NotificationRepo();
|
||||
|
||||
$notifyRepo->markAllAsViewed($user->id);
|
||||
|
@ -183,58 +183,6 @@ class MyStorage extends Storage
|
||||
return $this->upload('/resource/', self::MIME_FILE, UploadModel::TYPE_RESOURCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return UploadModel|bool
|
||||
*/
|
||||
public function uploadRemoteImage($url)
|
||||
{
|
||||
$path = parse_url($url, PHP_URL_PATH);
|
||||
$extension = pathinfo($path, PATHINFO_EXTENSION);
|
||||
$originalName = pathinfo($path, PATHINFO_BASENAME);
|
||||
|
||||
$fileName = $this->generateFileName($extension);
|
||||
|
||||
$filePath = tmp_path($fileName);
|
||||
|
||||
$contents = file_get_contents($url);
|
||||
|
||||
if (file_put_contents($filePath, $contents) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$keyName = "/img/content/{$fileName}";
|
||||
|
||||
$uploadPath = $this->putFile($keyName, $filePath);
|
||||
|
||||
if (!$uploadPath) return false;
|
||||
|
||||
$md5 = md5_file($filePath);
|
||||
|
||||
$uploadRepo = new UploadRepo();
|
||||
|
||||
$upload = $uploadRepo->findByMd5($md5);
|
||||
|
||||
if ($upload == false) {
|
||||
|
||||
$upload = new UploadModel();
|
||||
|
||||
$upload->name = $originalName;
|
||||
$upload->mime = mime_content_type($filePath);
|
||||
$upload->size = filesize($filePath);
|
||||
$upload->type = UploadModel::TYPE_CONTENT_IMG;
|
||||
$upload->path = $uploadPath;
|
||||
$upload->md5 = $md5;
|
||||
|
||||
$upload->create();
|
||||
}
|
||||
|
||||
unlink($filePath);
|
||||
|
||||
return $upload;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*
|
||||
@ -256,7 +204,7 @@ class MyStorage extends Storage
|
||||
|
||||
foreach ($files as $file) {
|
||||
|
||||
if ($this->checkFile($file->getRealType(), $mimeType) == false) {
|
||||
if (!$this->checkFile($file->getRealType(), $mimeType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -264,7 +212,7 @@ class MyStorage extends Storage
|
||||
|
||||
$upload = $uploadRepo->findByMd5($md5);
|
||||
|
||||
if ($upload == false) {
|
||||
if (!$upload) {
|
||||
|
||||
$name = $this->filter->sanitize($file->getName(), ['trim', 'string']);
|
||||
|
||||
|
@ -91,7 +91,7 @@ abstract class Smser extends Service
|
||||
|
||||
$result = $sendStatus->getCode() == 'Ok';
|
||||
|
||||
if ($result == false) {
|
||||
if (!$result) {
|
||||
$this->logger->error('Send Message Failed ' . $response->toJsonString());
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ class Throttle extends Service
|
||||
{
|
||||
$config = $this->getConfig();
|
||||
|
||||
if ($config->path('throttle.enabled') == false) {
|
||||
if (!$config->path('throttle.enabled')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -172,29 +172,25 @@ class Vod extends Service
|
||||
|
||||
$expiredTime = base_convert(time() + $expiry, 10, 16);
|
||||
$tryTime = 0; // 试看时间,0不限制
|
||||
$ipLimit = 0; // ip数量限制,0不限制
|
||||
$random = rand(100000, 999999); // 随机数
|
||||
$ipLimit = 9; // ip数量限制,0不限制
|
||||
$random = uniqid(); // 随机数
|
||||
|
||||
/**
|
||||
* 腾讯坑爹的参数类型和文档,先凑合吧
|
||||
* 不限制试看 => 必须exper=0(不能设置为空)
|
||||
* 不限制IP => 必须rlimit为空(不能设置为0),暂不可用
|
||||
* 不限制IP => 必须rlimit为空(不能设置为0)
|
||||
*/
|
||||
$myTryTime = $tryTime >= 0 ? $tryTime : 0;
|
||||
$myIpLimit = $ipLimit > 0 ? $ipLimit : '';
|
||||
$myTryTime = $tryTime;
|
||||
$myIpLimit = $ipLimit;
|
||||
$sign = $key . $dirName . $expiredTime . $myTryTime . $myIpLimit . $random;
|
||||
|
||||
$query = [];
|
||||
|
||||
$query['t'] = $expiredTime;
|
||||
|
||||
if ($tryTime >= 0) {
|
||||
$query['exper'] = $tryTime;
|
||||
}
|
||||
$query['exper'] = $myTryTime;
|
||||
|
||||
if ($ipLimit > 0) {
|
||||
$query['rlimit'] = $ipLimit;
|
||||
}
|
||||
$query['rlimit'] = $myIpLimit;
|
||||
|
||||
$query['us'] = $random;
|
||||
|
||||
|
@ -70,7 +70,7 @@ abstract class WeChatNotice extends Service
|
||||
|
||||
$result = $response['errcode'] == 0;
|
||||
|
||||
if ($result == false) {
|
||||
if (!$result) {
|
||||
$this->logger->error('Send Template Message Failed ' . kg_json_encode($response));
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ use App\Models\Reason as ReasonModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\Answer as AnswerRepo;
|
||||
use App\Repos\Question as QuestionRepo;
|
||||
use App\Services\EditorStorage as EditorStorageService;
|
||||
|
||||
class Answer extends Validator
|
||||
{
|
||||
@ -58,6 +59,10 @@ class Answer extends Validator
|
||||
{
|
||||
$value = $this->filter->sanitize($content, ['trim']);
|
||||
|
||||
$storage = new EditorStorageService();
|
||||
|
||||
$value = $storage->handle($value);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length < 10) {
|
||||
|
@ -14,6 +14,7 @@ use App\Library\Validators\Common as CommonValidator;
|
||||
use App\Models\Article as ArticleModel;
|
||||
use App\Models\Reason as ReasonModel;
|
||||
use App\Repos\Article as ArticleRepo;
|
||||
use App\Services\EditorStorage as EditorStorageService;
|
||||
|
||||
class Article extends Validator
|
||||
{
|
||||
@ -94,6 +95,10 @@ class Article extends Validator
|
||||
{
|
||||
$value = $this->filter->sanitize($content, ['trim']);
|
||||
|
||||
$storage = new EditorStorageService();
|
||||
|
||||
$value = $storage->handle($value);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length < 10) {
|
||||
|
@ -13,6 +13,7 @@ use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Library\Validators\Common as CommonValidator;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Services\EditorStorage as EditorStorageService;
|
||||
|
||||
class Course extends Validator
|
||||
{
|
||||
@ -119,6 +120,10 @@ class Course extends Validator
|
||||
{
|
||||
$value = $this->filter->sanitize($details, ['trim']);
|
||||
|
||||
$storage = new EditorStorageService();
|
||||
|
||||
$value = $storage->handle($value);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length > 30000) {
|
||||
|
@ -12,6 +12,7 @@ use App\Caches\MaxHelpId as MaxHelpIdCache;
|
||||
use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Models\Help as HelpModel;
|
||||
use App\Repos\Help as HelpRepo;
|
||||
use App\Services\EditorStorage as EditorStorageService;
|
||||
|
||||
class Help extends Validator
|
||||
{
|
||||
@ -90,6 +91,10 @@ class Help extends Validator
|
||||
{
|
||||
$value = $this->filter->sanitize($content, ['trim']);
|
||||
|
||||
$storage = new EditorStorageService();
|
||||
|
||||
$value = $storage->handle($value);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length < 10) {
|
||||
|
@ -13,6 +13,7 @@ use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Library\Validators\Common as CommonValidator;
|
||||
use App\Models\Page as PageModel;
|
||||
use App\Repos\Page as PageRepo;
|
||||
use App\Services\EditorStorage as EditorStorageService;
|
||||
|
||||
class Page extends Validator
|
||||
{
|
||||
@ -124,6 +125,10 @@ class Page extends Validator
|
||||
{
|
||||
$value = $this->filter->sanitize($content, ['trim']);
|
||||
|
||||
$storage = new EditorStorageService();
|
||||
|
||||
$value = $storage->handle($value);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length < 10) {
|
||||
|
@ -13,6 +13,7 @@ use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Library\Validators\Common as CommonValidator;
|
||||
use App\Models\PointGift as PointGiftModel;
|
||||
use App\Repos\PointGift as PointGiftRepo;
|
||||
use App\Services\EditorStorage as EditorStorageService;
|
||||
|
||||
class PointGift extends Validator
|
||||
{
|
||||
@ -86,6 +87,10 @@ class PointGift extends Validator
|
||||
{
|
||||
$value = $this->filter->sanitize($details, ['trim']);
|
||||
|
||||
$storage = new EditorStorageService();
|
||||
|
||||
$value = $storage->handle($value);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length > 30000) {
|
||||
|
@ -13,6 +13,7 @@ use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Models\Question as QuestionModel;
|
||||
use App\Models\Reason as ReasonModel;
|
||||
use App\Repos\Question as QuestionRepo;
|
||||
use App\Services\EditorStorage as EditorStorageService;
|
||||
|
||||
class Question extends Validator
|
||||
{
|
||||
@ -106,6 +107,10 @@ class Question extends Validator
|
||||
{
|
||||
$value = $this->filter->sanitize($content, ['trim']);
|
||||
|
||||
$storage = new EditorStorageService();
|
||||
|
||||
$value = $storage->handle($value);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length > 30000) {
|
||||
|
@ -54,7 +54,7 @@ class Review extends Validator
|
||||
|
||||
public function checkRating($rating)
|
||||
{
|
||||
if (!in_array($rating, [1, 2, 3, 4, 5])) {
|
||||
if ($rating < 1 || $rating > 5) {
|
||||
throw new BadRequestException('review.invalid_rating');
|
||||
}
|
||||
|
||||
|
60
composer.lock
generated
60
composer.lock
generated
@ -2366,16 +2366,16 @@
|
||||
},
|
||||
{
|
||||
"name": "qcloud/cos-sdk-v5",
|
||||
"version": "v2.5.6",
|
||||
"version": "v2.6.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tencentyun/cos-php-sdk-v5.git",
|
||||
"reference": "607ee49d372a799964206b6ae0a9eb2816201c42"
|
||||
"reference": "d367ba8d0305b83364b64055594a0ac22b1cefd8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tencentyun/cos-php-sdk-v5/zipball/607ee49d372a799964206b6ae0a9eb2816201c42",
|
||||
"reference": "607ee49d372a799964206b6ae0a9eb2816201c42",
|
||||
"url": "https://api.github.com/repos/tencentyun/cos-php-sdk-v5/zipball/d367ba8d0305b83364b64055594a0ac22b1cefd8",
|
||||
"reference": "d367ba8d0305b83364b64055594a0ac22b1cefd8",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -2433,9 +2433,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/tencentyun/cos-php-sdk-v5/issues",
|
||||
"source": "https://github.com/tencentyun/cos-php-sdk-v5/tree/v2.5.6"
|
||||
"source": "https://github.com/tencentyun/cos-php-sdk-v5/tree/v2.6.1"
|
||||
},
|
||||
"time": "2022-06-07T14:49:19+00:00"
|
||||
"time": "2023-02-07T09:49:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
@ -2489,16 +2489,16 @@
|
||||
},
|
||||
{
|
||||
"name": "robmorgan/phinx",
|
||||
"version": "0.12.12",
|
||||
"version": "0.12.13",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cakephp/phinx.git",
|
||||
"reference": "9a6ce1e7fdf0fa4e602ba5875b5bc9442ccaa115"
|
||||
"reference": "6eb0f295e140ed2804d93396755f0ce9ada4ec07"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cakephp/phinx/zipball/9a6ce1e7fdf0fa4e602ba5875b5bc9442ccaa115",
|
||||
"reference": "9a6ce1e7fdf0fa4e602ba5875b5bc9442ccaa115",
|
||||
"url": "https://api.github.com/repos/cakephp/phinx/zipball/6eb0f295e140ed2804d93396755f0ce9ada4ec07",
|
||||
"reference": "6eb0f295e140ed2804d93396755f0ce9ada4ec07",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -2575,9 +2575,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/cakephp/phinx/issues",
|
||||
"source": "https://github.com/cakephp/phinx/tree/0.12.12"
|
||||
"source": "https://github.com/cakephp/phinx/tree/0.12.13"
|
||||
},
|
||||
"time": "2022-07-09T18:53:51+00:00"
|
||||
"time": "2022-10-03T04:57:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
@ -4910,16 +4910,16 @@
|
||||
},
|
||||
{
|
||||
"name": "tencentcloud/tencentcloud-sdk-php",
|
||||
"version": "3.0.731",
|
||||
"version": "3.0.824",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/TencentCloud/tencentcloud-sdk-php.git",
|
||||
"reference": "a247a556c120dd7dd95db40035edcde7271fe40d"
|
||||
"reference": "1d85da7e51ba02defe33fbae0b6dbae0f1d7caf5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/TencentCloud/tencentcloud-sdk-php/zipball/a247a556c120dd7dd95db40035edcde7271fe40d",
|
||||
"reference": "a247a556c120dd7dd95db40035edcde7271fe40d",
|
||||
"url": "https://api.github.com/repos/TencentCloud/tencentcloud-sdk-php/zipball/1d85da7e51ba02defe33fbae0b6dbae0f1d7caf5",
|
||||
"reference": "1d85da7e51ba02defe33fbae0b6dbae0f1d7caf5",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -4957,9 +4957,9 @@
|
||||
"homepage": "https://github.com/TencentCloud/tencentcloud-sdk-php",
|
||||
"support": {
|
||||
"issues": "https://github.com/TencentCloud/tencentcloud-sdk-php/issues",
|
||||
"source": "https://github.com/TencentCloud/tencentcloud-sdk-php/tree/3.0.731"
|
||||
"source": "https://github.com/TencentCloud/tencentcloud-sdk-php/tree/3.0.824"
|
||||
},
|
||||
"time": "2022-09-21T00:09:54+00:00"
|
||||
"time": "2023-02-15T00:03:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
@ -5097,16 +5097,16 @@
|
||||
},
|
||||
{
|
||||
"name": "workerman/gateway-worker",
|
||||
"version": "v3.0.25",
|
||||
"version": "v3.0.27",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/walkor/GatewayWorker.git",
|
||||
"reference": "5b47eb9a90c6b2afc25327979e41de352cb3c286"
|
||||
"reference": "c0cae6c0e69288ab7dcc8b25599d3b9e4f4441d2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/walkor/GatewayWorker/zipball/5b47eb9a90c6b2afc25327979e41de352cb3c286",
|
||||
"reference": "5b47eb9a90c6b2afc25327979e41de352cb3c286",
|
||||
"url": "https://api.github.com/repos/walkor/GatewayWorker/zipball/c0cae6c0e69288ab7dcc8b25599d3b9e4f4441d2",
|
||||
"reference": "c0cae6c0e69288ab7dcc8b25599d3b9e4f4441d2",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -5116,7 +5116,7 @@
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"workerman/workerman": "^4.0.30"
|
||||
"workerman/workerman": "^4.0.0 || ^5.0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -5135,7 +5135,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/walkor/GatewayWorker/issues",
|
||||
"source": "https://github.com/walkor/GatewayWorker/tree/v3.0.25"
|
||||
"source": "https://github.com/walkor/GatewayWorker/tree/v3.0.27"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -5147,7 +5147,7 @@
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2022-09-19T09:59:56+00:00"
|
||||
"time": "2023-02-09T09:16:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "workerman/gatewayclient",
|
||||
@ -5306,16 +5306,16 @@
|
||||
},
|
||||
{
|
||||
"name": "yansongda/pay",
|
||||
"version": "v2.10.4",
|
||||
"version": "v2.10.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/yansongda/pay.git",
|
||||
"reference": "e378f43800f867d53ce35ee90aa17f0c3b7b5838"
|
||||
"reference": "f7d93ed784de4ca09d3386d28139c724ddd526fc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/yansongda/pay/zipball/e378f43800f867d53ce35ee90aa17f0c3b7b5838",
|
||||
"reference": "e378f43800f867d53ce35ee90aa17f0c3b7b5838",
|
||||
"url": "https://api.github.com/repos/yansongda/pay/zipball/f7d93ed784de4ca09d3386d28139c724ddd526fc",
|
||||
"reference": "f7d93ed784de4ca09d3386d28139c724ddd526fc",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -5366,7 +5366,7 @@
|
||||
"issues": "https://github.com/yansongda/pay/issues",
|
||||
"source": "https://github.com/yansongda/pay"
|
||||
},
|
||||
"time": "2022-03-10T01:27:10+00:00"
|
||||
"time": "2022-12-03T13:44:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "yansongda/supports",
|
||||
|
@ -172,4 +172,19 @@ $config['websocket']['connect_address'] = 'your_domain.com:8282';
|
||||
*/
|
||||
$config['websocket']['register_address'] = '127.0.0.1:1238';
|
||||
|
||||
/**
|
||||
* 资源监控: CPU负载(0.1-1.0)
|
||||
*/
|
||||
$config['server_monitor']['cpu'] = 0.8;
|
||||
|
||||
/**
|
||||
* 资源监控: 内存剩余占比(10-100)%
|
||||
*/
|
||||
$config['server_monitor']['memory'] = 10;
|
||||
|
||||
/**
|
||||
* 资源监控: 磁盘剩余占比(10-100)%
|
||||
*/
|
||||
$config['server_monitor']['disk'] = 20;
|
||||
|
||||
return $config;
|
||||
|
@ -49,14 +49,15 @@ layui.use(['jquery', 'form', 'element', 'layer', 'kgDropdown'], function () {
|
||||
|
||||
form.on('submit(go)', function (data) {
|
||||
var submit = $(this);
|
||||
submit.attr('disabled', 'disabled').addClass('layui-btn-disabled');
|
||||
var orgText = $(this).text();
|
||||
submit.text('提交中···').attr('disabled', 'disabled').addClass('layui-btn-disabled');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: data.form.action,
|
||||
data: data.field,
|
||||
success: function (res) {
|
||||
if (res.msg) {
|
||||
layer.msg(res.msg, {icon: 1});
|
||||
layer.msg(res.msg, {icon: 1, time: 1500});
|
||||
}
|
||||
if (res.location) {
|
||||
var target = res.target || 'self';
|
||||
@ -66,13 +67,14 @@ layui.use(['jquery', 'form', 'element', 'layer', 'kgDropdown'], function () {
|
||||
} else {
|
||||
window.location.href = res.location;
|
||||
}
|
||||
}, 1500);
|
||||
} else {
|
||||
submit.removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||
}, 1000);
|
||||
}
|
||||
setTimeout(function () {
|
||||
submit.text(orgText).removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||
}, 1500);
|
||||
},
|
||||
error: function () {
|
||||
submit.removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||
submit.text(orgText).removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
|
@ -56,14 +56,17 @@ layui.use(['jquery', 'helper'], function () {
|
||||
});
|
||||
|
||||
/**
|
||||
* 播放器中央播放按钮点击事件
|
||||
* 播放器中央播放按钮
|
||||
*/
|
||||
$('#play-mask').on('click', function () {
|
||||
var $playMask = $('#play-mask');
|
||||
|
||||
$playMask.on('click', function () {
|
||||
$(this).hide();
|
||||
player.toggle();
|
||||
});
|
||||
|
||||
function start() {
|
||||
$playMask.hide();
|
||||
if (interval != null) {
|
||||
clearInterval(interval);
|
||||
interval = null;
|
||||
@ -72,6 +75,7 @@ layui.use(['jquery', 'helper'], function () {
|
||||
}
|
||||
|
||||
function stop() {
|
||||
$playMask.show();
|
||||
if (interval != null) {
|
||||
clearInterval(interval);
|
||||
interval = null;
|
||||
|
@ -7,6 +7,7 @@ layui.use(['jquery', 'helper'], function () {
|
||||
var intervalTime = 15000;
|
||||
var userId = window.user.id;
|
||||
var requestId = helper.getRequestId();
|
||||
var chapterId = $('input[name="chapter.id"]').val();
|
||||
var planId = $('input[name="chapter.plan_id"]').val();
|
||||
var lastPosition = $('input[name="chapter.position"]').val();
|
||||
var learningUrl = $('input[name="chapter.learning_url"]').val();
|
||||
@ -29,8 +30,6 @@ layui.use(['jquery', 'helper'], function () {
|
||||
}
|
||||
});
|
||||
|
||||
console.log(quality)
|
||||
|
||||
var player = new DPlayer({
|
||||
container: document.getElementById('player'),
|
||||
video: {
|
||||
@ -52,22 +51,39 @@ layui.use(['jquery', 'helper'], function () {
|
||||
});
|
||||
|
||||
/**
|
||||
* 播放器中央播放按钮点击事件
|
||||
* 播放器中央播放按钮
|
||||
*/
|
||||
$('#play-mask').on('click', function () {
|
||||
var $playMask = $('#play-mask');
|
||||
|
||||
$playMask.on('click', function () {
|
||||
$(this).hide();
|
||||
player.toggle();
|
||||
});
|
||||
|
||||
var position = parseInt(lastPosition);
|
||||
var position = getLastPosition();
|
||||
|
||||
/**
|
||||
* 过于接近结束位置当作已结束处理
|
||||
* 上次播放位置
|
||||
*/
|
||||
if (position > 0 && player.video.duration - position > 10) {
|
||||
if (position > 0) {
|
||||
player.seek(position);
|
||||
}
|
||||
|
||||
function getPositionKey() {
|
||||
return 'chapter:' + chapterId + ':position';
|
||||
}
|
||||
|
||||
function getLastPosition() {
|
||||
var key = getPositionKey();
|
||||
var value = localStorage.getItem(key);
|
||||
return value != null ? parseInt(value) : lastPosition;
|
||||
}
|
||||
|
||||
function setLastPosition(value) {
|
||||
var key = getPositionKey();
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
|
||||
function clearLearningInterval() {
|
||||
if (interval != null) {
|
||||
clearInterval(interval);
|
||||
@ -80,20 +96,24 @@ layui.use(['jquery', 'helper'], function () {
|
||||
}
|
||||
|
||||
function play() {
|
||||
$playMask.hide();
|
||||
clearLearningInterval();
|
||||
setLearningInterval();
|
||||
}
|
||||
|
||||
function pause() {
|
||||
$playMask.show();
|
||||
clearLearningInterval();
|
||||
}
|
||||
|
||||
function ended() {
|
||||
clearLearningInterval();
|
||||
learning();
|
||||
setLastPosition(0);
|
||||
clearLearningInterval();
|
||||
}
|
||||
|
||||
function learning() {
|
||||
setLastPosition(player.video.currentTime);
|
||||
if (userId !== '0' && planId !== '0') {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
|
@ -68,14 +68,15 @@ layui.use(['jquery', 'form', 'element', 'layer', 'helper'], function () {
|
||||
|
||||
form.on('submit(go)', function (data) {
|
||||
var submit = $(this);
|
||||
submit.attr('disabled', 'disabled').addClass('layui-btn-disabled');
|
||||
var orgText = $(this).text();
|
||||
submit.text('提交中···').attr('disabled', 'disabled').addClass('layui-btn-disabled');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: data.form.action,
|
||||
data: data.field,
|
||||
success: function (res) {
|
||||
if (res.msg) {
|
||||
layer.msg(res.msg, {icon: 1});
|
||||
layer.msg(res.msg, {icon: 1, time: 1500});
|
||||
}
|
||||
if (res.location) {
|
||||
var target = res.target || 'self';
|
||||
@ -85,13 +86,14 @@ layui.use(['jquery', 'form', 'element', 'layer', 'helper'], function () {
|
||||
} else {
|
||||
window.location.href = res.location;
|
||||
}
|
||||
}, 1500);
|
||||
} else {
|
||||
submit.removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||
}, 1000);
|
||||
}
|
||||
setTimeout(function () {
|
||||
submit.text(orgText).removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||
}, 1500);
|
||||
},
|
||||
error: function () {
|
||||
submit.removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||
submit.text(orgText).removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user