1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-28 13:21:37 +08:00

统一了状态类型,修复一些改字段名带来的错误

This commit is contained in:
xiaochong0302 2020-08-31 19:34:32 +08:00
parent c22417913a
commit 477a9f1c42
53 changed files with 14176 additions and 14240 deletions

View File

@ -109,7 +109,7 @@ class CloseTradeTask extends Task
* @param int $limit * @param int $limit
* @return ResultsetInterface|Resultset|TradeModel[] * @return ResultsetInterface|Resultset|TradeModel[]
*/ */
protected function findTrades($limit = 15) protected function findTrades($limit = 50)
{ {
$status = TradeModel::STATUS_PENDING; $status = TradeModel::STATUS_PENDING;

View File

@ -14,7 +14,7 @@ use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset; use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface; use Phalcon\Mvc\Model\ResultsetInterface;
class OrderTask extends Task class DeliverTask extends Task
{ {
const TRY_COUNT = 3; const TRY_COUNT = 3;
@ -178,11 +178,11 @@ class OrderTask extends Task
$refund = new RefundModel(); $refund = new RefundModel();
$refund->subject = $order->subject; $refund->owner_id = $order->owner_id;
$refund->amount = $order->amount;
$refund->user_id = $order->user_id;
$refund->order_id = $order->id; $refund->order_id = $order->id;
$refund->trade_id = $trade->id; $refund->trade_id = $trade->id;
$refund->subject = $order->subject;
$refund->amount = $order->amount;
$refund->apply_note = '开通服务失败,自动退款'; $refund->apply_note = '开通服务失败,自动退款';
$refund->review_note = '自动操作'; $refund->review_note = '自动操作';
@ -210,7 +210,7 @@ class OrderTask extends Task
*/ */
protected function findTasks($limit = 100) protected function findTasks($limit = 100)
{ {
$itemType = TaskModel::TYPE_ORDER; $itemType = TaskModel::TYPE_DELIVER;
$status = TaskModel::STATUS_PENDING; $status = TaskModel::STATUS_PENDING;
$tryCount = self::TRY_COUNT; $tryCount = self::TRY_COUNT;

View File

@ -1,70 +0,0 @@
<?php
namespace App\Console\Tasks;
use App\Library\Cache\Backend\Redis as RedisCache;
use App\Services\Smser\Live as LiveSmser;
use Phalcon\Cli\Task;
class LiveNoticeConsumerTask extends Task
{
/**
* @var RedisCache
*/
protected $cache;
/**
* @var \Redis
*/
protected $redis;
public function mainAction()
{
$hour = date('h');
/**
* 限定合理的时间范围
*/
if ($hour < 7 || $hour > 23) {
return;
}
$this->cache = $this->getDI()->get('cache');
$this->redis = $this->cache->getRedis();
$providerTask = new LiveNoticeProviderTask();
$cacheKey = $providerTask->getCacheKey();
$members = $this->redis->sMembers($cacheKey);
if (!$members) return;
$smser = new LiveSmser();
$now = time();
$removeList = [];
foreach ($members as $member) {
list($chapterId, $userId, $startTime) = explode(':', $member);
if ($now - $startTime < 3600) {
$smser->handle($chapterId, $userId, $startTime);
$removeList[] = $member;
}
if ($now > $startTime) {
$removeList[] = $member;
}
}
if (count($removeList) > 0) {
$this->redis->sRem($cacheKey, ...$removeList);
}
}
}

View File

@ -1,92 +0,0 @@
<?php
namespace App\Console\Tasks;
use App\Library\Cache\Backend\Redis as RedisCache;
use App\Models\ChapterLive as ChapterLiveModel;
use App\Models\CourseUser as CourseUserModel;
use Phalcon\Cli\Task;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class LiveNoticeProviderTask extends Task
{
/**
* @var RedisCache
*/
protected $cache;
/**
* @var \Redis
*/
protected $redis;
public function mainAction()
{
$this->cache = $this->getDI()->get('cache');
$this->redis = $this->cache->getRedis();
$tasks = $this->findTasks();
if ($tasks->count() == 0) {
return;
}
$values = [];
foreach ($tasks as $task) {
$items = [$task->chapter_id, $task->user_id, $task->start_time];
$values[] = implode(':', $items);
}
$key = $this->getCacheKey();
$lifetime = $this->getLifetime();
$this->redis->sAdd($key, ...$values);
$this->redis->expire($key, $lifetime);
}
/**
* @return ResultsetInterface|Resultset
*/
protected function findTasks()
{
$beginTime = strtotime('today');
$endTime = strtotime('tomorrow');
/**
* 过滤付费和导入用户,减少发送量
*/
$sourceTypes = [
CourseUserModel::SOURCE_CHARGE,
CourseUserModel::SOURCE_IMPORT,
];
return $this->modelsManager->createBuilder()
->columns(['cu.course_id', 'cu.user_id', 'cl.chapter_id', 'cl.start_time'])
->addFrom(ChapterLiveModel::class, 'cl')
->join(CourseUserModel::class, 'cl.course_id = cu.course_id', 'cu')
->inWhere('cu.source_type', $sourceTypes)
->betweenWhere('start_time', $beginTime, $endTime)
->getQuery()->execute();
}
public function getLifetime()
{
$tomorrow = strtotime('tomorrow');
return $tomorrow - time();
}
public function getCacheKey()
{
return 'live_notice';
}
}

View File

@ -0,0 +1,98 @@
<?php
namespace App\Console\Tasks;
use App\Library\Cache\Backend\Redis as RedisCache;
use App\Models\CourseUser as CourseUserModel;
use App\Repos\Chapter as ChapterRepo;
use App\Services\LiveNotify as LiveNotifyService;
use App\Services\Smser\Live as LiveSmser;
use Phalcon\Cli\Task;
class LiveNotifyTask extends Task
{
/**
* @var RedisCache
*/
protected $cache;
/**
* @var \Redis
*/
protected $redis;
public function mainAction()
{
$this->cache = $this->getDI()->get('cache');
$this->redis = $this->cache->getRedis();
$service = new LiveNotifyService();
$key = $service->getNotifyKey();
$chapterIds = $this->redis->sMembers($key);
if (!$chapterIds) return;
$sentKey = $service->getSentNotifyKey();
$sentChapterIds = $this->redis->sMembers($sentKey);
foreach ($chapterIds as $chapterId) {
if (!in_array($chapterId, $sentChapterIds)) {
$this->sendNotification($chapterId);
} else {
$this->redis->sAdd($sentKey, $chapterId);
}
}
if ($this->redis->sCard($sentKey) == 1) {
$this->redis->expire($sentKey, 86400);
}
}
protected function sendNotification($chapterId)
{
$chapterRepo = new ChapterRepo();
$chapterLive = $chapterRepo->findChapterLive($chapterId);
if (!$chapterLive) return;
$targetUserIds = $this->findTargetUserIds($chapterLive->course_id);
if (!$targetUserIds) return;
$smser = new LiveSmser();
foreach ($targetUserIds as $userId) {
$smser->handle($chapterId, $userId, $chapterLive->start_time);
}
}
protected function findTargetUserIds($courseId)
{
/**
* 只给付费和vip用户发通知
*/
$sourceTypes = [
CourseUserModel::SOURCE_CHARGE,
CourseUserModel::SOURCE_VIP,
];
$rows = CourseUserModel::query()
->where('course_id = :course_id:', ['course_id' => $courseId])
->andWhere('role_type = :role_type:', ['role_type' => CourseUserModel::ROLE_STUDENT])
->inWhere('source_type', $sourceTypes)
->execute();
if ($rows->count() > 0) {
return kg_array_column($rows->toArray(), 'user_id');
}
return [];
}
}

View File

@ -188,7 +188,7 @@ class RefundTask extends Task
{ {
$courseUserRepo = new CourseUserRepo(); $courseUserRepo = new CourseUserRepo();
$courseUser = $courseUserRepo->findCourseStudent($order->item_id, $order->user_id); $courseUser = $courseUserRepo->findCourseStudent($order->item_id, $order->owner_id);
if ($courseUser) { if ($courseUser) {
@ -216,7 +216,7 @@ class RefundTask extends Task
foreach ($itemInfo['courses'] as $course) { foreach ($itemInfo['courses'] as $course) {
$courseUser = $courseUserRepo->findCourseStudent($course['id'], $order->user_id); $courseUser = $courseUserRepo->findCourseStudent($course['id'], $order->owner_id);
if ($courseUser) { if ($courseUser) {
@ -238,7 +238,7 @@ class RefundTask extends Task
{ {
$userRepo = new UserRepo(); $userRepo = new UserRepo();
$user = $userRepo->findById($order->user_id); $user = $userRepo->findById($order->owner_id);
/** /**
* @var array $itemInfo * @var array $itemInfo
@ -293,7 +293,7 @@ class RefundTask extends Task
* @param int $limit * @param int $limit
* @return ResultsetInterface|Resultset|TaskModel[] * @return ResultsetInterface|Resultset|TaskModel[]
*/ */
protected function findTasks($limit = 5) protected function findTasks($limit = 30)
{ {
$itemType = TaskModel::TYPE_REFUND; $itemType = TaskModel::TYPE_REFUND;
$status = TaskModel::STATUS_PENDING; $status = TaskModel::STATUS_PENDING;

View File

@ -17,7 +17,7 @@ class CategoryController extends Controller
public function listAction() public function listAction()
{ {
$parentId = $this->request->get('parent_id', 'int', 0); $parentId = $this->request->get('parent_id', 'int', 0);
$type = $this->request->get('type', 'string', CategoryModel::TYPE_COURSE); $type = $this->request->get('type', 'int', CategoryModel::TYPE_COURSE);
$categoryService = new CategoryService(); $categoryService = new CategoryService();
@ -41,7 +41,7 @@ class CategoryController extends Controller
public function addAction() public function addAction()
{ {
$parentId = $this->request->get('parent_id', 'int', 0); $parentId = $this->request->get('parent_id', 'int', 0);
$type = $this->request->get('type', 'string', 'course'); $type = $this->request->get('type', 'int', CategoryModel::TYPE_COURSE);
$categoryService = new CategoryService(); $categoryService = new CategoryService();
@ -69,7 +69,7 @@ class CategoryController extends Controller
$location = $this->url->get( $location = $this->url->get(
['for' => 'admin.category.list'], ['for' => 'admin.category.list'],
['type' => $category->type, 'parent_id' => $category->parent_id], ['type' => $category->type, 'parent_id' => $category->parent_id]
); );
$content = [ $content = [
@ -105,7 +105,7 @@ class CategoryController extends Controller
$location = $this->url->get( $location = $this->url->get(
['for' => 'admin.category.list'], ['for' => 'admin.category.list'],
['type' => $category->type, 'parent_id' => $category->parent_id], ['type' => $category->type, 'parent_id' => $category->parent_id]
); );
$content = [ $content = [

View File

@ -133,10 +133,7 @@ class SettingController extends Controller
$live = $settingService->getLiveSettings(); $live = $settingService->getLiveSettings();
$ptt = json_decode($live->pull_trans_template);
$this->view->setVar('live', $live); $this->view->setVar('live', $live);
$this->view->setVar('ptt', $ptt);
} }
} }

View File

@ -33,8 +33,8 @@ class Nav extends Service
$navRepo = new NavRepo(); $navRepo = new NavRepo();
return $navRepo->findAll([ return $navRepo->findAll([
'position' => NavModel::POS_TOP,
'parent_id' => 0, 'parent_id' => 0,
'position' => 'top',
'published' => 1, 'published' => 1,
]); ]);
} }

View File

@ -7,6 +7,12 @@
{% endif %} {% endif %}
{%- endmacro %} {%- endmacro %}
{%- macro live_status_info(attrs) %}
{% if attrs['stream']['status'] != 'active' %}
<span class="layui-badge layui-bg-blue">直播中</span>
{% endif %}
{%- endmacro %}
<table class="layui-table kg-table layui-form"> <table class="layui-table kg-table layui-form">
<colgroup> <colgroup>
<col> <col>
@ -21,7 +27,7 @@
<tr> <tr>
<th>编号</th> <th>编号</th>
<th>名称</th> <th>名称</th>
<th>直播时间</th> <th>时间</th>
<th>排序</th> <th>排序</th>
<th>免费</th> <th>免费</th>
<th>发布</th> <th>发布</th>
@ -30,6 +36,7 @@
</thead> </thead>
<tbody> <tbody>
{% for item in lessons %} {% for item in lessons %}
{% set preview_url = url({'for':'desktop.chapter.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.chapter.edit','id':item.id}) %} {% set edit_url = url({'for':'admin.chapter.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.chapter.update','id':item.id}) %} {% set update_url = url({'for':'admin.chapter.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.chapter.delete','id':item.id}) %} {% set delete_url = url({'for':'admin.chapter.delete','id':item.id}) %}
@ -39,6 +46,7 @@
<td> <td>
<span><a href="{{ edit_url }}">{{ item.title }}</a></span> <span><a href="{{ edit_url }}">{{ item.title }}</a></span>
<span class="layui-badge layui-bg-green">课</span> <span class="layui-badge layui-bg-green">课</span>
{{ live_status_info(item.attrs) }}
</td> </td>
<td>{{ live_time_info(item.attrs) }}</td> <td>{{ live_time_info(item.attrs) }}</td>
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ update_url }}"></td> <td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ update_url }}"></td>
@ -48,6 +56,7 @@
<div class="layui-dropdown"> <div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button> <button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>
<ul> <ul>
<li><a href="{{ preview_url }}" target="_blank">预览</a></li>
<li><a href="{{ edit_url }}">编辑</a></li> <li><a href="{{ edit_url }}">编辑</a></li>
{% if item.deleted == 0 %} {% if item.deleted == 0 %}
<li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li> <li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li>

View File

@ -21,6 +21,7 @@
</thead> </thead>
<tbody> <tbody>
{% for item in lessons %} {% for item in lessons %}
{% set preview_url = url({'for':'desktop.chapter.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.chapter.edit','id':item.id}) %} {% set edit_url = url({'for':'admin.chapter.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.chapter.update','id':item.id}) %} {% set update_url = url({'for':'admin.chapter.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.chapter.delete','id':item.id}) %} {% set delete_url = url({'for':'admin.chapter.delete','id':item.id}) %}
@ -39,6 +40,7 @@
<div class="layui-dropdown"> <div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button> <button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>
<ul> <ul>
<li><a href="{{ preview_url }}" target="_blank">预览</a></li>
<li><a href="{{ edit_url }}">编辑</a></li> <li><a href="{{ edit_url }}">编辑</a></li>
{% if item.deleted == 0 %} {% if item.deleted == 0 %}
<li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li> <li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li>

View File

@ -37,6 +37,7 @@
</thead> </thead>
<tbody> <tbody>
{% for item in lessons %} {% for item in lessons %}
{% set show_url = url({'for':'desktop.chapter.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.chapter.edit','id':item.id}) %} {% set edit_url = url({'for':'admin.chapter.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.chapter.update','id':item.id}) %} {% set update_url = url({'for':'admin.chapter.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.chapter.delete','id':item.id}) %} {% set delete_url = url({'for':'admin.chapter.delete','id':item.id}) %}
@ -56,6 +57,7 @@
<div class="layui-dropdown"> <div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button> <button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>
<ul> <ul>
<li><a href="{{ preview_url }}" target="_blank">预览</a></li>
<li><a href="{{ edit_url }}">编辑</a></li> <li><a href="{{ edit_url }}">编辑</a></li>
{% if item.deleted == 0 %} {% if item.deleted == 0 %}
<li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li> <li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li>

View File

@ -69,6 +69,7 @@
</thead> </thead>
<tbody> <tbody>
{% for item in pager.items %} {% for item in pager.items %}
{% set preview_url = url({'for':'desktop.course.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.course.edit','id':item.id}) %} {% set edit_url = url({'for':'admin.course.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.course.update','id':item.id}) %} {% set update_url = url({'for':'admin.course.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.course.delete','id':item.id}) %} {% set delete_url = url({'for':'admin.course.delete','id':item.id}) %}
@ -101,6 +102,7 @@
<div class="layui-dropdown"> <div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button> <button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>
<ul> <ul>
<li><a href="{{ preview_url }}" target="_blank">预览课程</a></li>
<li><a href="{{ edit_url }}">编辑课程</a></li> <li><a href="{{ edit_url }}">编辑课程</a></li>
{% if item.deleted == 0 %} {% if item.deleted == 0 %}
<li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除课程</a></li> <li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除课程</a></li>

View File

@ -32,13 +32,14 @@
<tbody> <tbody>
{% for item in helps %} {% for item in helps %}
{% set list_url = url({'for':'admin.help.list'},{'category_id':item.category.id}) %} {% set list_url = url({'for':'admin.help.list'},{'category_id':item.category.id}) %}
{% set preview_url = url({'for':'desktop.help.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.help.edit','id':item.id}) %} {% set edit_url = url({'for':'admin.help.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.help.update','id':item.id}) %} {% set update_url = url({'for':'admin.help.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.help.delete','id':item.id}) %} {% set delete_url = url({'for':'admin.help.delete','id':item.id}) %}
{% set restore_url = url({'for':'admin.help.restore','id':item.id}) %} {% set restore_url = url({'for':'admin.help.restore','id':item.id}) %}
<tr> <tr>
<td>{{ item.id }}</td> <td>{{ item.id }}</td>
<td>{{ item.title }}</td> <td><a href="{{ edit_url }}">{{ item.title }}</a></td>
<td><a href="{{ list_url }}">{{ item.category.name }}</a></td> <td><a href="{{ list_url }}">{{ item.category.name }}</a></td>
<td class="center"><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ update_url }}"></td> <td class="center"><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ update_url }}"></td>
<td class="center"><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td> <td class="center"><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
@ -46,6 +47,7 @@
<div class="layui-dropdown"> <div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button> <button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>
<ul> <ul>
<li><a href="{{ preview_url }}" target="_blank">预览</a></li>
<li><a href="{{ edit_url }}">编辑</a></li> <li><a href="{{ edit_url }}">编辑</a></li>
{% if item.deleted == 0 %} {% if item.deleted == 0 %}
<li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li> <li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li>

View File

@ -40,8 +40,8 @@
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">位置</label> <label class="layui-form-label">位置</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="radio" name="position" value="top" title="顶部" checked="checked"> <input type="radio" name="position" value="1" title="顶部" checked="checked">
<input type="radio" name="position" value="bottom" title="底部"> <input type="radio" name="position" value="2" title="底部">
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">

View File

@ -27,8 +27,8 @@
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">位置</label> <label class="layui-form-label">位置</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="radio" name="position" value="top" title="顶部" {% if nav.position == 'top' %}checked{% endif %}> <input type="radio" name="position" value="top" title="顶部" {% if nav.position == 1 %}checked{% endif %}>
<input type="radio" name="position" value="bottom" title="底部" {% if nav.position == 'bottom' %}checked{% endif %}> <input type="radio" name="position" value="bottom" title="底部" {% if nav.position == 2 %}checked{% endif %}>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">

View File

@ -3,9 +3,9 @@
{% block content %} {% block content %}
{%- macro position_info(value) %} {%- macro position_info(value) %}
{% if value == 'top' %} {% if value == 1 %}
<span class="layui-badge layui-bg-green">顶部</span> <span class="layui-badge layui-bg-green">顶部</span>
{% elseif value == 'bottom' %} {% elseif value == 2 %}
<span class="layui-badge layui-bg-blue">底部</span> <span class="layui-badge layui-bg-blue">底部</span>
{% endif %} {% endif %}
{%- endmacro %} {%- endmacro %}

View File

@ -31,13 +31,13 @@
</thead> </thead>
<tbody> <tbody>
{% for item in pager.items %} {% for item in pager.items %}
{% set show_url = url({'for':'desktop.page.show','id':item.id}) %} {% set preview_url = url({'for':'desktop.page.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.page.edit','id':item.id}) %} {% set edit_url = url({'for':'admin.page.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.page.update','id':item.id}) %} {% set update_url = url({'for':'admin.page.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.page.delete','id':item.id}) %} {% set delete_url = url({'for':'admin.page.delete','id':item.id}) %}
<tr> <tr>
<td>{{ item.id }}</td> <td>{{ item.id }}</td>
<td><a href="{{ show_url }}" target="_blank">{{ item.title }}</a></td> <td><a href="{{ edit_url }}">{{ item.title }}</a></td>
<td>{{ date('Y-m-d H:i',item.create_time) }}</td> <td>{{ date('Y-m-d H:i',item.create_time) }}</td>
<td>{{ date('Y-m-d H:i',item.update_time) }}</td> <td>{{ date('Y-m-d H:i',item.update_time) }}</td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}> <td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}>
@ -46,6 +46,7 @@
<div class="layui-dropdown"> <div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button> <button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>
<ul> <ul>
<li><a href="{{ preview_url }}" target="_blank">预览</a></li>
<li><a href="{{ edit_url }}">编辑</a></li> <li><a href="{{ edit_url }}">编辑</a></li>
{% if item.deleted == 0 %} {% if item.deleted == 0 %}
<li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li> <li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li>

View File

@ -16,7 +16,7 @@
{{ partial('setting/live_pull') }} {{ partial('setting/live_pull') }}
</div> </div>
<div class="layui-tab-item"> <div class="layui-tab-item">
{{ partial('setting/live_callback') }} {{ partial('setting/live_notify') }}
</div> </div>
</div> </div>
</div> </div>

View File

@ -52,42 +52,45 @@
<input type="radio" name="pull_trans_enabled" value="0" title="否" lay-filter="pull_trans_enabled" {% if live.pull_trans_enabled == 0 %}checked{% endif %}> <input type="radio" name="pull_trans_enabled" value="0" title="否" lay-filter="pull_trans_enabled" {% if live.pull_trans_enabled == 0 %}checked{% endif %}>
</div> </div>
</div> </div>
<table class="layui-table kg-table layui-form" id="ptt-block" {{ ppt_display }}> <div id="ptt-block" {{ ppt_display }}>
<colgroup> <table class="layui-table kg-table layui-form">
<col> <colgroup>
<col> <col>
<col> <col>
<col> <col>
</colgroup> <col>
<thead> </colgroup>
<tr> <thead>
<th>模板名称</th> <tr>
<th>模板描述</th> <th>模板名称</th>
<th>视频码率kbps</th> <th>模板描述</th>
<th>视频高度px</th> <th>视频码率kbps</th>
</tr> <th>视频高度px</th>
</thead> </tr>
<tbody> </thead>
<tr> <tbody>
<td><input class="layui-input" type="text" name="ptt[id][fd]" value="{{ ptt.fd.id }}" readonly="readonly"></td> <tr>
<td><input class="layui-input" type="text" name="ptt[summary][fd]" value="{{ ptt.fd.summary }}" readonly="readonly"></td> <td>fd</td>
<td><input class="layui-input" type="text" name="ptt[bit_rate][fd]" value="{{ ptt.fd.bit_rate }}" readonly="readonly"></td> <td>流畅</td>
<td><input class="layui-input" type="text" name="ptt[height][fd]" value="{{ ptt.fd.height }}" readonly="readonly"></td> <td>500</td>
</tr> <td>540</td>
<tr> </tr>
<td><input class="layui-input" type="text" name="ptt[id][sd]" value="{{ ptt.sd.id }}" readonly="readonly"></td> <tr>
<td><input class="layui-input" type="text" name="ptt[summary][sd]" value="{{ ptt.sd.summary }}" readonly="readonly"></td> <td>sd</td>
<td><input class="layui-input" type="text" name="ptt[bit_rate][sd]" value="{{ ptt.sd.bit_rate }}" readonly="readonly"></td> <td>标清</td>
<td><input class="layui-input" type="text" name="ptt[height][sd]" value="{{ ptt.sd.height }}" readonly="readonly"></td> <td>1000</td>
</tr> <td>720</td>
<tr> </tr>
<td><input class="layui-input" type="text" name="ptt[id][hd]" value="{{ ptt.hd.id }}" readonly="readonly"></td> <tr>
<td><input class="layui-input" type="text" name="ptt[summary][hd]" value="{{ ptt.hd.summary }}" readonly="readonly"></td> <td>hd</td>
<td><input class="layui-input" type="text" name="ptt[bit_rate][hd]" value="{{ ptt.hd.bit_rate }}" readonly="readonly"></td> <td>高清</td>
<td><input class="layui-input" type="text" name="ptt[height][hd]" value="{{ ptt.hd.height }}" readonly="readonly"></td> <td>2000</td>
</tr> <td>1080</td>
</tbody> </tr>
</table> </tbody>
</table>
<br>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label"></label> <label class="layui-form-label"></label>
<div class="layui-input-block"> <div class="layui-input-block">

View File

@ -35,12 +35,6 @@
<input type="radio" name="video_format" value="mp4" title="MP4" disabled="disabled" lay-filter="video_format" {% if vod.video_format == "mp4" %}checked{% endif %}> <input type="radio" name="video_format" value="mp4" title="MP4" disabled="disabled" lay-filter="video_format" {% if vod.video_format == "mp4" %}checked{% endif %}>
</div> </div>
</div> </div>
<div class="layui-form-item">
<label class="layui-form-label">视频模板ID</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="video_template" readonly="readonly" layui-verify="required">
</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">音频格式</label> <label class="layui-form-label">音频格式</label>
<div class="layui-input-block"> <div class="layui-input-block">
@ -48,12 +42,6 @@
<input type="radio" name="audio_format" value="m4a" title="M4A" disabled="disabled" lay-filter="audio_format" {% if vod.audio_format == "m4a" %}checked{% endif %}> <input type="radio" name="audio_format" value="m4a" title="M4A" disabled="disabled" lay-filter="audio_format" {% if vod.audio_format == "m4a" %}checked{% endif %}>
</div> </div>
</div> </div>
<div class="layui-form-item">
<label class="layui-form-label">音频模板ID</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="audio_template" readonly="readonly" layui-verify="required">
</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">开启水印</label> <label class="layui-form-label">开启水印</label>
<div class="layui-input-block"> <div class="layui-input-block">
@ -148,24 +136,6 @@
var $ = layui.jquery; var $ = layui.jquery;
var form = layui.form; var form = layui.form;
var changeVideoTemplate = function (format) {
var template = $('input[name=video_template]');
if (format === 'mp4') {
template.val('100010,100020,100030');
} else {
template.val('100210,100220,100230');
}
};
var changeAudioTemplate = function (format) {
var template = $('input[name=audio_template]');
if (format === 'mp3') {
template.val('1010');
} else {
template.val('1110');
}
};
form.on('radio(storage_type)', function (data) { form.on('radio(storage_type)', function (data) {
var block = $('#storage-region-block'); var block = $('#storage-region-block');
if (data.value === 'fixed') { if (data.value === 'fixed') {
@ -193,20 +163,6 @@
} }
}); });
form.on('radio(video_format)', function (data) {
changeVideoTemplate(data.value);
});
form.on('radio(audio_format)', function (data) {
changeAudioTemplate(data.value);
});
var videoFormat = $('input[name=video_format]:checked').val();
var audioFormat = $('input[name=audio_format]:checked').val();
changeVideoTemplate(videoFormat);
changeAudioTemplate(audioFormat);
}); });
</script> </script>

View File

@ -33,6 +33,7 @@
</thead> </thead>
<tbody> <tbody>
{% for item in pager.items %} {% for item in pager.items %}
{% set preview_url = url({'for':'desktop.topic.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.topic.edit','id':item.id}) %} {% set edit_url = url({'for':'admin.topic.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.topic.update','id':item.id}) %} {% set update_url = url({'for':'admin.topic.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.topic.delete','id':item.id}) %} {% set delete_url = url({'for':'admin.topic.delete','id':item.id}) %}
@ -48,6 +49,7 @@
<div class="layui-dropdown"> <div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button> <button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>
<ul> <ul>
<li><a href="{{ preview_url }}" target="_blank">预览</a></li>
<li><a href="{{ edit_url }}">编辑</a></li> <li><a href="{{ edit_url }}">编辑</a></li>
{% if item.deleted == 0 %} {% if item.deleted == 0 %}
<li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li> <li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除</a></li>

View File

@ -68,10 +68,11 @@
</thead> </thead>
<tbody> <tbody>
{% for item in pager.items %} {% for item in pager.items %}
{% set preview_url = url({'for':'desktop.user.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.user.edit','id':item.id}) %} {% set edit_url = url({'for':'admin.user.edit','id':item.id}) %}
<tr> <tr>
<td>{{ item.id }}</td> <td>{{ item.id }}</td>
<td><span title="{{ item.about }}">{{ item.name }}</span>{{ status_info(item) }}</td> <td><a href="{{ edit_url }}" title="{{ item.about }}">{{ item.name }}</a>{{ status_info(item) }}</td>
<td>{{ gender_info(item.gender) }}</td> <td>{{ gender_info(item.gender) }}</td>
<td>{{ edu_role_info(item) }}</td> <td>{{ edu_role_info(item) }}</td>
<td>{{ admin_role_info(item) }}</td> <td>{{ admin_role_info(item) }}</td>
@ -81,6 +82,7 @@
<div class="layui-dropdown"> <div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button> <button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>
<ul> <ul>
<li><a href="{{ preview_url }}" target="_blank">预览</a></li>
<li><a href="{{ edit_url }}">编辑</a></li> <li><a href="{{ edit_url }}">编辑</a></li>
</ul> </ul>
</div> </div>

View File

@ -19,7 +19,7 @@ class PageController extends Controller
$page = $service->handle($id); $page = $service->handle($id);
$this->seo->prependTitle($page['title']); $this->seo->prependTitle(['单页', $page['title']]);
$this->view->setVar('page', $page); $this->view->setVar('page', $page);
} }

View File

@ -5,6 +5,7 @@
<div class="breadcrumb"> <div class="breadcrumb">
<span class="layui-breadcrumb"> <span class="layui-breadcrumb">
<a href="/">首页</a> <a href="/">首页</a>
<a><cite>单页</cite></a>
<a><cite>{{ page.title }}</cite></a> <a><cite>{{ page.title }}</cite></a>
</span> </span>
</div> </div>

View File

@ -42,8 +42,8 @@
<tr> <tr>
<td> <td>
<p>课程:<a href="{{ course_url }}" target="_blank">{{ item.course.title }}</a></p> <p>课程:<a href="{{ course_url }}" target="_blank">{{ item.course.title }}</a></p>
<p class="question layui-elip" title="{{ item.question }}">提问:{{ item.question }}</p> <p class="content layui-elip" title="{{ item.question }}">提问:{{ item.question }}</p>
<p class="answer layui-elip" title="{{ item.answer }}">回复:{{ answer }}</p> <p class="content layui-elip" title="{{ item.answer }}">回复:{{ answer }}</p>
</td> </td>
<td>{{ item.priority }}</td> <td>{{ item.priority }}</td>
<td>{{ date('Y-m-d',item.create_time) }}</td> <td>{{ date('Y-m-d',item.create_time) }}</td>

View File

@ -12,7 +12,7 @@
{{ vip_info(item.vip) }} {{ vip_info(item.vip) }}
<div class="avatar"> <div class="avatar">
<a href="{{ user_url }}" title="{{ item.about }}"> <a href="{{ user_url }}" title="{{ item.about }}">
<img src="{{ item.avatar }}" alt="{{ item.name }}"> <img src="{{ item.avatar }}!avatar_160" alt="{{ item.name }}">
</a> </a>
</div> </div>
<div class="name layui-elip"> <div class="name layui-elip">

View File

@ -11,7 +11,7 @@
{{ type_info(item.type) }} {{ type_info(item.type) }}
<div class="avatar"> <div class="avatar">
<a href="{{ group_url }}" title="{{ item.about }}"> <a href="{{ group_url }}" title="{{ item.about }}">
<img src="{{ item.avatar }}" alt="{{ item.name }}"> <img src="{{ item.avatar }}!avatar_160" alt="{{ item.name }}">
</a> </a>
</div> </div>
<div class="name layui-elip"> <div class="name layui-elip">

View File

@ -50,7 +50,9 @@
<div class="tab-wrap"> <div class="tab-wrap">
<div class="layui-tab layui-tab-brief user-tab"> <div class="layui-tab layui-tab-brief user-tab">
<ul class="layui-tab-title"> <ul class="layui-tab-title">
<li class="layui-this">课程<span class="tab-count">{{ user.course_count }}</span></li> {% if show_tab_courses %}
<li class="layui-this">课程<span class="tab-count">{{ user.course_count }}</span></li>
{% endif %}
{% if show_tab_favorites %} {% if show_tab_favorites %}
<li>收藏<span class="tab-count">{{ user.favorite_count }}</span></li> <li>收藏<span class="tab-count">{{ user.favorite_count }}</span></li>
{% endif %} {% endif %}
@ -62,7 +64,9 @@
{% endif %} {% endif %}
</ul> </ul>
<div class="layui-tab-content"> <div class="layui-tab-content">
<div class="layui-tab-item layui-show" id="tab-courses" data-url="{{ courses_url }}"></div> {% if show_tab_courses %}
<div class="layui-tab-item layui-show" id="tab-courses" data-url="{{ courses_url }}"></div>
{% endif %}
{% if show_tab_favorites %} {% if show_tab_favorites %}
<div class="layui-tab-item" id="tab-favorites" data-url="{{ favorites_url }}"></div> <div class="layui-tab-item" id="tab-favorites" data-url="{{ favorites_url }}"></div>
{% endif %} {% endif %}

View File

@ -6,11 +6,15 @@ use App\Models\Order as OrderModel;
use App\Models\Task as TaskModel; use App\Models\Task as TaskModel;
use App\Models\Trade as TradeModel; use App\Models\Trade as TradeModel;
use App\Repos\Order as OrderRepo; use App\Repos\Order as OrderRepo;
use Phalcon\Events\Event; use Phalcon\Events\Event as PhEvent;
use Phalcon\Logger\Adapter\File as FileLogger;
class Pay extends Listener class Pay extends Listener
{ {
/**
* @var FileLogger
*/
protected $logger; protected $logger;
public function __construct() public function __construct()
@ -18,7 +22,7 @@ class Pay extends Listener
$this->logger = $this->getLogger(); $this->logger = $this->getLogger();
} }
public function afterPay(Event $event, $source, TradeModel $trade) public function afterPay(PhEvent $event, $source, TradeModel $trade)
{ {
try { try {
@ -34,7 +38,7 @@ class Pay extends Listener
$order = $orderRepo->findById($trade->order_id); $order = $orderRepo->findById($trade->order_id);
$order->status = OrderModel::STATUS_SHIPPING; $order->status = OrderModel::STATUS_DELIVERING;
if ($order->update() === false) { if ($order->update() === false) {
throw new \RuntimeException('Update Order Status Failed'); throw new \RuntimeException('Update Order Status Failed');
@ -52,7 +56,7 @@ class Pay extends Listener
$task->item_id = $order->id; $task->item_id = $order->id;
$task->item_info = $itemInfo; $task->item_info = $itemInfo;
$task->item_type = TaskModel::TYPE_ORDER; $task->item_type = TaskModel::TYPE_DELIVER;
if ($task->create() === false) { if ($task->create() === false) {
throw new \RuntimeException('Create Order Process Task Failed'); throw new \RuntimeException('Create Order Process Task Failed');
@ -69,15 +73,15 @@ class Pay extends Listener
'code' => $e->getCode(), 'code' => $e->getCode(),
'message' => $e->getMessage(), 'message' => $e->getMessage(),
])); ]));
$this->logger->debug('Event: {event}, Source: {source}, Data: {data}', [
'event' => $event->getType(),
'source' => get_class($source),
'data' => kg_json_encode($trade),
]);
throw new \RuntimeException('sys.trans_rollback');
} }
$this->logger->debug('Event: {event}, Source: {source}, Data: {data}', [
'event' => $event->getType(),
'source' => get_class($source),
'data' => kg_json_encode($trade),
]);
throw new \RuntimeException('sys.trans_rollback');
} }
} }

View File

@ -2,14 +2,22 @@
namespace App\Listeners; namespace App\Listeners;
use Phalcon\Db\Adapter as DbAdapter;
use Phalcon\Db\Profiler as DbProfiler; use Phalcon\Db\Profiler as DbProfiler;
use Phalcon\Events\Event; use Phalcon\Events\Event as PhEvent;
use Phalcon\Logger\Adapter\File as FileLogger;
class Profiler extends Listener class Profiler extends Listener
{ {
/**
* @var FileLogger
*/
protected $logger; protected $logger;
/**
* @var DbProfiler
*/
protected $profiler; protected $profiler;
public function __construct() public function __construct()
@ -19,12 +27,20 @@ class Profiler extends Listener
$this->profiler = new DbProfiler(); $this->profiler = new DbProfiler();
} }
public function beforeQuery(Event $event, $connection) /**
* @param PhEvent $event
* @param DbAdapter $connection
*/
public function beforeQuery(PhEvent $event, $connection)
{ {
$this->profiler->startProfile($connection->getSQLStatement(), $connection->getSQLVariables()); $this->profiler->startProfile($connection->getSqlStatement(), $connection->getSqlVariables());
} }
public function afterQuery(Event $event, $connection) /**
* @param PhEvent $event
* @param DbAdapter $connection
*/
public function afterQuery(PhEvent $event, $connection)
{ {
$this->profiler->stopProfile(); $this->profiler->stopProfile();

View File

@ -11,8 +11,8 @@ class Category extends Model
/** /**
* 类型 * 类型
*/ */
const TYPE_COURSE = 'course'; // 课程 const TYPE_COURSE = 1; // 课程
const TYPE_HELP = 'help'; // 帮助 const TYPE_HELP = 2; // 帮助
/** /**
* 主键编号 * 主键编号
@ -38,7 +38,7 @@ class Category extends Model
/** /**
* 类型 * 类型
* *
* @var string * @var int
*/ */
public $type; public $type;

View File

@ -18,7 +18,8 @@ class CourseUser extends Model
*/ */
const SOURCE_FREE = 1; // 免费 const SOURCE_FREE = 1; // 免费
const SOURCE_CHARGE = 2; // 付费 const SOURCE_CHARGE = 2; // 付费
const SOURCE_IMPORT = 3; // 导入 const SOURCE_VIP = 3; // 会员
const SOURCE_IMPORT = 4; // 导入
/** /**
* 主键编号 * 主键编号
@ -153,6 +154,7 @@ class CourseUser extends Model
return [ return [
self::SOURCE_FREE => '免费', self::SOURCE_FREE => '免费',
self::SOURCE_CHARGE => '付费', self::SOURCE_CHARGE => '付费',
self::SOURCE_VIP => '会员',
self::SOURCE_IMPORT => '导入', self::SOURCE_IMPORT => '导入',
]; ];
} }

View File

@ -10,8 +10,8 @@ class Nav extends Model
/** /**
* 位置类型 * 位置类型
*/ */
const POS_TOP = 'top'; const POS_TOP = 1; // 顶部
const POS_BOTTOM = 'bottom'; const POS_BOTTOM = 2; // 底部
/** /**
* 打开方式 * 打开方式
@ -54,13 +54,6 @@ class Nav extends Model
*/ */
public $path; public $path;
/**
* 位置
*
* @var string
*/
public $position;
/** /**
* 打开方式 * 打开方式
* *
@ -75,6 +68,13 @@ class Nav extends Model
*/ */
public $url; public $url;
/**
* 位置
*
* @var int
*/
public $position;
/** /**
* 优先级 * 优先级
* *

View File

@ -20,7 +20,7 @@ class Order extends Model
* 状态类型 * 状态类型
*/ */
const STATUS_PENDING = 1; // 待支付 const STATUS_PENDING = 1; // 待支付
const STATUS_SHIPPING = 2; // 发货中 const STATUS_DELIVERING = 2; // 发货中
const STATUS_FINISHED = 3; // 已完成 const STATUS_FINISHED = 3; // 已完成
const STATUS_CLOSED = 4; // 已关闭 const STATUS_CLOSED = 4; // 已关闭
const STATUS_REFUNDED = 5; // 已退款 const STATUS_REFUNDED = 5; // 已退款
@ -198,7 +198,7 @@ class Order extends Model
{ {
return [ return [
self::STATUS_PENDING => '待支付', self::STATUS_PENDING => '待支付',
self::STATUS_SHIPPING => '发货中', self::STATUS_DELIVERING => '发货中',
self::STATUS_FINISHED => '已完成', self::STATUS_FINISHED => '已完成',
self::STATUS_CLOSED => '已关闭', self::STATUS_CLOSED => '已关闭',
self::STATUS_REFUNDED => '已退款', self::STATUS_REFUNDED => '已退款',

View File

@ -10,8 +10,8 @@ class Role extends Model
/** /**
* 角色类型 * 角色类型
*/ */
const TYPE_SYSTEM = 'system'; // 内置 const TYPE_SYSTEM = 1; // 内置
const TYPE_CUSTOM = 'custom'; // 自定 const TYPE_CUSTOM = 2; // 自定
/** /**
* 内置角色 * 内置角色

View File

@ -8,7 +8,7 @@ class Task extends Model
/** /**
* 任务类型 * 任务类型
*/ */
const TYPE_ORDER = 1; // 下单 const TYPE_DELIVER = 1; // 发货
const TYPE_REFUND = 2; // 退款 const TYPE_REFUND = 2; // 退款
/** /**

View File

@ -2,6 +2,7 @@
namespace App\Services; namespace App\Services;
use App\Library\Cache\Backend\Redis as RedisCache;
use App\Models\Chapter as ChapterModel; use App\Models\Chapter as ChapterModel;
use App\Models\ChapterLive as ChapterLiveModel; use App\Models\ChapterLive as ChapterLiveModel;
use App\Repos\Chapter as ChapterRepo; use App\Repos\Chapter as ChapterRepo;
@ -13,7 +14,7 @@ class LiveNotify extends Service
{ {
$time = $this->request->getPost('t'); $time = $this->request->getPost('t');
$sign = $this->request->getPost('sign'); $sign = $this->request->getPost('sign');
$type = $this->request->getQuery('action'); $action = $this->request->getQuery('action');
if (!$this->checkSign($sign, $time)) { if (!$this->checkSign($sign, $time)) {
return false; return false;
@ -21,7 +22,7 @@ class LiveNotify extends Service
$result = false; $result = false;
switch ($type) { switch ($action) {
case 'streamBegin': case 'streamBegin':
$result = $this->handleStreamBegin(); $result = $this->handleStreamBegin();
break; break;
@ -42,14 +43,24 @@ class LiveNotify extends Service
return $result; return $result;
} }
public function getNotifyKey()
{
return 'live_notify';
}
public function getSentNotifyKey()
{
return 'live_notify_sent';
}
/** /**
* 推流 * 推流
*/ */
protected function handleStreamBegin() protected function handleStreamBegin()
{ {
$steamId = $this->request->getPost('stream_id'); $streamId = $this->request->getPost('stream_id');
$chapter = $this->getChapter($steamId); $chapter = $this->getChapter($streamId);
if (!$chapter) return false; if (!$chapter) return false;
@ -63,9 +74,7 @@ class LiveNotify extends Service
$chapterLive->update(['status' => ChapterLiveModel::STATUS_ACTIVE]); $chapterLive->update(['status' => ChapterLiveModel::STATUS_ACTIVE]);
/** $this->sendBeginNotify($chapter);
* @todo 发送直播通知
*/
return true; return true;
} }
@ -75,9 +84,9 @@ class LiveNotify extends Service
*/ */
protected function handleStreamEnd() protected function handleStreamEnd()
{ {
$steamId = $this->request->getPost('stream_id'); $streamId = $this->request->getPost('stream_id');
$chapter = $this->getChapter($steamId); $chapter = $this->getChapter($streamId);
if (!$chapter) return false; if (!$chapter) return false;
@ -118,6 +127,22 @@ class LiveNotify extends Service
} }
protected function sendBeginNotify(ChapterModel $chapter)
{
/**
* @var RedisCache $cache
*/
$cache = $this->getDI()->get('cache');
$redis = $cache->getRedis();
$keyName = $this->getNotifyKeyName();
$redis->sAdd($keyName, $chapter->id);
$redis->expire($keyName, 86400);
}
protected function getChapter($streamId) protected function getChapter($streamId)
{ {
$id = (int)str_replace('chapter_', '', $streamId); $id = (int)str_replace('chapter_', '', $streamId);

View File

@ -38,7 +38,7 @@ class Refund extends Service
$refundAmount = 0.00; $refundAmount = 0.00;
if ($itemInfo['course']['refund_expiry_time'] > time()) { if ($itemInfo['course']['refund_expiry_time'] > time()) {
$refundPercent = $this->getCourseRefundPercent($order->item_id, $order->user_id); $refundPercent = $this->getCourseRefundPercent($order->item_id, $order->owner_id);
$refundAmount = $order->amount * $refundPercent; $refundAmount = $order->amount * $refundPercent;
} }
@ -79,7 +79,7 @@ class Refund extends Service
if ($course['refund_expiry_time'] > time()) { if ($course['refund_expiry_time'] > time()) {
$pricePercent = round($course['market_price'] / $totalMarketPrice, 4); $pricePercent = round($course['market_price'] / $totalMarketPrice, 4);
$refundPercent = $this->getCourseRefundPercent($order->user_id, $course['id']); $refundPercent = $this->getCourseRefundPercent($course['id'], $order->owner_id);
$refundAmount = round($order->amount * $pricePercent * $refundPercent, 2); $refundAmount = round($order->amount * $pricePercent * $refundPercent, 2);
$totalRefundAmount += $refundAmount; $totalRefundAmount += $refundAmount;
} }

View File

@ -24,7 +24,7 @@ class Live extends Smser
$account = $accountRepo->findById($userId); $account = $accountRepo->findById($userId);
if (!$account->phone) { if (empty($account->phone)) {
return false; return false;
} }

View File

@ -19,9 +19,9 @@ class Order extends Smser
{ {
$accountRepo = new AccountRepo(); $accountRepo = new AccountRepo();
$account = $accountRepo->findById($order->user_id); $account = $accountRepo->findById($order->owner_id);
if (!$account->phone) { if (empty($account->phone)) {
return false; return false;
} }

View File

@ -19,9 +19,9 @@ class Refund extends Smser
{ {
$accountRepo = new AccountRepo(); $accountRepo = new AccountRepo();
$account = $accountRepo->findById($refund->user_id); $account = $accountRepo->findById($refund->owner_id);
if (!$account->phone) { if (empty($account->phone)) {
return false; return false;
} }

View File

@ -36,7 +36,9 @@ class CourseIndex extends Service
$this->redis->sAdd($key, $courseId); $this->redis->sAdd($key, $courseId);
$this->redis->expire($key, $this->lifetime); if ($this->redis->sCard($key) == 1) {
$this->redis->expire($key, $this->lifetime);
}
} }
public function getSyncKey() public function getSyncKey()

View File

@ -36,7 +36,9 @@ class GroupIndex extends Service
$this->redis->sAdd($key, $groupId); $this->redis->sAdd($key, $groupId);
$this->redis->expire($key, $this->lifetime); if ($this->redis->sCard($key) == 1) {
$this->redis->expire($key, $this->lifetime);
}
} }
public function getSyncKey() public function getSyncKey()

View File

@ -65,11 +65,13 @@ class Learning extends Service
$this->cache->save($itemKey, $cacheLearning, $this->lifetime); $this->cache->save($itemKey, $cacheLearning, $this->lifetime);
} }
$syncKey = $this->getSyncKey(); $key = $this->getSyncKey();
$this->redis->sAdd($syncKey, $learning->request_id); $this->redis->sAdd($key, $learning->request_id);
$this->redis->expire($syncKey, $this->lifetime); if ($this->redis->sCard($key) == 1) {
$this->redis->expire($key, $this->lifetime);
}
} }
public function getItemKey($id) public function getItemKey($id)

View File

@ -36,7 +36,9 @@ class UserIndex extends Service
$this->redis->sAdd($key, $userId); $this->redis->sAdd($key, $userId);
$this->redis->expire($key, $this->lifetime); if ($this->redis->sCard($key) == 1) {
$this->redis->expire($key, $this->lifetime);
}
} }
public function getSyncKey() public function getSyncKey()

File diff suppressed because it is too large Load Diff

View File

@ -80,11 +80,6 @@ final class InsertSettingData extends AbstractMigration
'item_key' => 'push_domain', 'item_key' => 'push_domain',
'item_value' => 'push.abc.com', 'item_value' => 'push.abc.com',
], ],
[
'section' => 'live',
'item_key' => 'pull_trans_template',
'item_value' => '{"fd":{"id":"fd","bit_rate":"500","summary":"流畅","height":"540"},"sd":{"id":"sd","bit_rate":"1000","summary":"标清","height":"720"},"hd":{"id":"hd","bit_rate":"2000","summary":"高清","height":"1080"}}',
],
[ [
'section' => 'live', 'section' => 'live',
'item_key' => 'pull_trans_enabled', 'item_key' => 'pull_trans_enabled',
@ -125,11 +120,6 @@ final class InsertSettingData extends AbstractMigration
'item_key' => 'pull_domain', 'item_key' => 'pull_domain',
'item_value' => 'play.abc.com', 'item_value' => 'play.abc.com',
], ],
[
'section' => 'live',
'item_key' => 'push_template',
'item_value' => '',
],
[ [
'section' => 'live', 'section' => 'live',
'item_key' => 'push_auth_key', 'item_key' => 'push_auth_key',
@ -375,11 +365,6 @@ final class InsertSettingData extends AbstractMigration
'item_key' => 'watermark_template', 'item_key' => 'watermark_template',
'item_value' => '462027', 'item_value' => '462027',
], ],
[
'section' => 'vod',
'item_key' => 'video_template',
'item_value' => '100210,100220,100230',
],
[ [
'section' => 'vod', 'section' => 'vod',
'item_key' => 'audio_format', 'item_key' => 'audio_format',
@ -400,11 +385,6 @@ final class InsertSettingData extends AbstractMigration
'item_key' => 'storage_region', 'item_key' => 'storage_region',
'item_value' => '', 'item_value' => '',
], ],
[
'section' => 'vod',
'item_key' => 'template',
'item_value' => '',
],
[ [
'section' => 'vod', 'section' => 'vod',
'item_key' => 'key_anti_ip_limit', 'item_key' => 'key_anti_ip_limit',
@ -415,11 +395,6 @@ final class InsertSettingData extends AbstractMigration
'item_key' => 'dist_domain', 'item_key' => 'dist_domain',
'item_value' => '', 'item_value' => '',
], ],
[
'section' => 'vod',
'item_key' => 'audio_template',
'item_value' => '1110',
],
[ [
'section' => 'vod', 'section' => 'vod',
'item_key' => 'key_anti_key', 'item_key' => 'key_anti_key',

View File

@ -16,9 +16,9 @@ final class InsertNavData extends AbstractMigration
'level' => 1, 'level' => 1,
'name' => '首页', 'name' => '首页',
'path' => ',1,', 'path' => ',1,',
'position' => 'top',
'target' => '_self', 'target' => '_self',
'url' => '/', 'url' => '/',
'position' => 1,
'priority' => 1, 'priority' => 1,
'published' => 1, 'published' => 1,
], ],
@ -28,9 +28,9 @@ final class InsertNavData extends AbstractMigration
'level' => 1, 'level' => 1,
'name' => '录播', 'name' => '录播',
'path' => ',2,', 'path' => ',2,',
'position' => 'top',
'target' => '_self', 'target' => '_self',
'url' => '/course/list?model=1', 'url' => '/course/list?model=1',
'position' => 1,
'priority' => 2, 'priority' => 2,
'published' => 1, 'published' => 1,
], ],
@ -40,9 +40,9 @@ final class InsertNavData extends AbstractMigration
'level' => 1, 'level' => 1,
'name' => '直播', 'name' => '直播',
'path' => ',3,', 'path' => ',3,',
'position' => 'top',
'target' => '_self', 'target' => '_self',
'url' => '/course/list?model=2', 'url' => '/course/list?model=2',
'position' => 1,
'priority' => 3, 'priority' => 3,
'published' => 1, 'published' => 1,
], ],
@ -52,9 +52,9 @@ final class InsertNavData extends AbstractMigration
'level' => 1, 'level' => 1,
'name' => '专栏', 'name' => '专栏',
'path' => ',4,', 'path' => ',4,',
'position' => 'top',
'target' => '_self', 'target' => '_self',
'url' => '/course/list?model=3', 'url' => '/course/list?model=3',
'position' => 1,
'priority' => 4, 'priority' => 4,
'published' => 1, 'published' => 1,
], ],
@ -64,9 +64,9 @@ final class InsertNavData extends AbstractMigration
'level' => 1, 'level' => 1,
'name' => '名师', 'name' => '名师',
'path' => ',5,', 'path' => ',5,',
'position' => 'top',
'target' => '_self', 'target' => '_self',
'url' => '/teacher/list', 'url' => '/teacher/list',
'position' => 1,
'priority' => 5, 'priority' => 5,
'published' => 1, 'published' => 1,
], ],
@ -76,9 +76,9 @@ final class InsertNavData extends AbstractMigration
'level' => 1, 'level' => 1,
'name' => '群组', 'name' => '群组',
'path' => ',6,', 'path' => ',6,',
'position' => 'top',
'target' => '_self', 'target' => '_self',
'url' => '/im/group/list', 'url' => '/im/group/list',
'position' => 1,
'priority' => 6, 'priority' => 6,
'published' => 1, 'published' => 1,
], ],
@ -88,9 +88,9 @@ final class InsertNavData extends AbstractMigration
'level' => 1, 'level' => 1,
'name' => '关于我们', 'name' => '关于我们',
'path' => ',7,', 'path' => ',7,',
'position' => 'bottom',
'target' => '_blank', 'target' => '_blank',
'url' => '#', 'url' => '#',
'position' => 2,
'priority' => 1, 'priority' => 1,
'published' => 1, 'published' => 1,
], ],
@ -100,9 +100,9 @@ final class InsertNavData extends AbstractMigration
'level' => 1, 'level' => 1,
'name' => '联系我们', 'name' => '联系我们',
'path' => ',8,', 'path' => ',8,',
'position' => 'bottom',
'target' => '_blank', 'target' => '_blank',
'url' => '#', 'url' => '#',
'position' => 2,
'priority' => 2, 'priority' => 2,
'published' => 1, 'published' => 1,
], ],
@ -112,9 +112,9 @@ final class InsertNavData extends AbstractMigration
'level' => 1, 'level' => 1,
'name' => '人才招聘', 'name' => '人才招聘',
'path' => ',9,', 'path' => ',9,',
'position' => 'bottom',
'target' => '_blank', 'target' => '_blank',
'url' => '#', 'url' => '#',
'position' => 2,
'priority' => 3, 'priority' => 3,
'published' => 1, 'published' => 1,
], ],
@ -124,9 +124,9 @@ final class InsertNavData extends AbstractMigration
'level' => 1, 'level' => 1,
'name' => '帮助中心', 'name' => '帮助中心',
'path' => ',10,', 'path' => ',10,',
'position' => 'bottom',
'target' => '_blank', 'target' => '_blank',
'url' => '/help', 'url' => '/help',
'position' => 2,
'priority' => 4, 'priority' => 4,
'published' => 1, 'published' => 1,
], ],
@ -136,9 +136,9 @@ final class InsertNavData extends AbstractMigration
'level' => 1, 'level' => 1,
'name' => '友情链接', 'name' => '友情链接',
'path' => ',11,', 'path' => ',11,',
'position' => 'bottom',
'target' => '_blank', 'target' => '_blank',
'url' => '#', 'url' => '#',
'position' => 2,
'priority' => 5, 'priority' => 5,
'published' => 1, 'published' => 1,
], ],

File diff suppressed because it is too large Load Diff

View File

@ -1465,15 +1465,11 @@ body {
text-align: center; text-align: center;
} }
.consult-table .item-elip {
width: 450px;
}
.review-table .title { .review-table .title {
width: 400px; width: 400px;
} }
.review-table .content { .review-table .content, .consult-table .content {
width: 400px; width: 400px;
color: #666; color: #666;
} }

View File

@ -10,20 +10,20 @@ $script = __DIR__ . '/console.php';
$bin = '/usr/bin/php'; $bin = '/usr/bin/php';
$scheduler->php($script, $bin, ['--task' => 'sync_learning', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'deliver', '--action' => 'main'])
->at('*/3 * * * *'); ->at('*/3 * * * *');
$scheduler->php($script, $bin, ['--task' => 'order', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'live_notify', '--action' => 'main'])
->at('*/5 * * * *'); ->at('*/5 * * * *');
$scheduler->php($script, $bin, ['--task' => 'sync_learning', '--action' => 'main'])
->at('*/7 * * * *');
$scheduler->php($script, $bin, ['--task' => 'vod_event', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'vod_event', '--action' => 'main'])
->at('*/5 * * * *'); ->at('*/9 * * * *');
$scheduler->php($script, $bin, ['--task' => 'close_trade', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'close_trade', '--action' => 'main'])
->at('*/10 * * * *'); ->at('*/13 * * * *');
$scheduler->php($script, $bin, ['--task' => 'live_notice_consumer', '--action' => 'main'])
->at('*/15 * * * *');
$scheduler->php($script, $bin, ['--task' => 'close_order', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'close_order', '--action' => 'main'])
->hourly(3); ->hourly(3);
@ -43,11 +43,8 @@ $scheduler->php($script, $bin, ['--task' => 'unlock_user', '--action' => 'main']
$scheduler->php($script, $bin, ['--task' => 'revoke_vip', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'revoke_vip', '--action' => 'main'])
->daily(3, 11); ->daily(3, 11);
$scheduler->php($script, $bin, ['--task' => 'live_notice_provider', '--action' => 'main'])
->daily(3, 17);
$scheduler->php($script, $bin, ['--task' => 'clean_token', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'clean_token', '--action' => 'main'])
->daily(3, 23); ->daily(3, 17);
$scheduler->php($script, $bin, ['--task' => 'site_map', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'site_map', '--action' => 'main'])
->daily(4, 3); ->daily(4, 3);