1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-26 12:23:06 +08:00

Merge branch 'koogua/v1.6.0' into demo

This commit is contained in:
koogua 2022-10-21 17:56:19 +08:00
commit 7f85b80102
30 changed files with 1384 additions and 958 deletions

View File

@ -48,13 +48,6 @@ H5手机端演示
Tips: 测试支付请用手机号注册一个新账户,以便接收订单通知,以及避免课程无法购买 Tips: 测试支付请用手机号注册一个新账户,以便接收订单通知,以及避免课程无法购买
即时通讯演示:
请使用以下两个账号在不同终端或者浏览器登录,打开微聊界面
- 帐号A100015@163.com / 123456
- 帐号B100065@163.com / 123456
微信推送演示: 微信推送演示:
Tips: 请用手机注册一个新账号,用户中心 -> 关注订阅,扫码关注公众号。之后的登录、购买、退款、直播、咨询等会有消息推送。 Tips: 请用手机注册一个新账号,用户中心 -> 关注订阅,扫码关注公众号。之后的登录、购买、退款、直播、咨询等会有消息推送。

View File

@ -15,7 +15,7 @@ class SyncAppInfoTask extends Task
public function mainAction() public function mainAction()
{ {
$url = 'https://koogua.com/api/instance/collect'; $url = 'https://www.koogua.com/api/instance/collect';
$site = $this->getSettings('site'); $site = $this->getSettings('site');

View File

@ -22,6 +22,7 @@
<col> <col>
<col> <col>
<col> <col>
<col>
<col width="10%"> <col width="10%">
<col width="10%"> <col width="10%">
<col width="12%"> <col width="12%">
@ -31,6 +32,7 @@
<th>编号</th> <th>编号</th>
<th>标题</th> <th>标题</th>
<th>分类</th> <th>分类</th>
<th>浏览</th>
<th>排序</th> <th>排序</th>
<th>发布</th> <th>发布</th>
<th>操作</th> <th>操作</th>
@ -48,6 +50,7 @@
<td>{{ item.id }}</td> <td>{{ item.id }}</td>
<td><a href="{{ edit_url }}">{{ item.title }}</a></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>{{ item.view_count }}</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="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="checked"{% endif %}></td>
<td class="center"> <td class="center">

View File

@ -9,7 +9,7 @@
<tbody> <tbody>
<tr> <tr>
<td>版权所有</td> <td>版权所有</td>
<td><a href="https://koogua.com" target="_blank">深圳市酷瓜软件有限公司</a></td> <td><a href="https://www.koogua.com" target="_blank">深圳市酷瓜软件有限公司</a></td>
</tr> </tr>
<tr> <tr>
<td>产品经理</td> <td>产品经理</td>

View File

@ -40,8 +40,8 @@
<th>编号</th> <th>编号</th>
<th>标题</th> <th>标题</th>
<th>别名</th> <th>别名</th>
<th>浏览</th>
<th>创建时间</th> <th>创建时间</th>
<th>更新时间</th>
<th>发布</th> <th>发布</th>
<th>操作</th> <th>操作</th>
</tr> </tr>
@ -57,8 +57,8 @@
<td>{{ item.id }}</td> <td>{{ item.id }}</td>
<td><a href="{{ edit_url }}">{{ item.title }}</a></td> <td><a href="{{ edit_url }}">{{ item.title }}</a></td>
<td>{{ alias_tips(item.alias) }}</td> <td>{{ alias_tips(item.alias) }}</td>
<td>{{ item.view_count }}</td>
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td> <td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
<td>{{ date('Y-m-d H:i:s',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="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="checked"{% endif %}>
</td> </td>
<td class="center"> <td class="center">

View File

@ -10,7 +10,7 @@
<label class="layui-form-label">手续费率</label> <label class="layui-form-label">手续费率</label>
<div class="layui-input-block"> <div class="layui-input-block">
<select name="service_rate" lay-verify="number"> <select name="service_rate" lay-verify="number">
{% for value in 1..30 %} {% for value in 0..30 %}
{% set selected = (value == alipay.service_rate) ? 'selected="selected"' : '' %} {% set selected = (value == alipay.service_rate) ? 'selected="selected"' : '' %}
<option value="{{ value }}" {{ selected }}>{{ value }}%</option> <option value="{{ value }}" {{ selected }}>{{ value }}%</option>
{% endfor %} {% endfor %}

View File

@ -10,7 +10,7 @@
<label class="layui-form-label">手续费率</label> <label class="layui-form-label">手续费率</label>
<div class="layui-input-block"> <div class="layui-input-block">
<select name="service_rate" lay-verify="number"> <select name="service_rate" lay-verify="number">
{% for value in 1..30 %} {% for value in 0..30 %}
{% set selected = (value == wxpay.service_rate) ? 'selected="selected"' : '' %} {% set selected = (value == wxpay.service_rate) ? 'selected="selected"' : '' %}
<option value="{{ value }}" {{ selected }}>{{ value }}%</option> <option value="{{ value }}" {{ selected }}>{{ value }}%</option>
{% endfor %} {% endfor %}

View File

@ -29,7 +29,7 @@ class TeacherController extends Controller
return $this->response->redirect($location); return $this->response->redirect($location);
} }
$this->seo->prependTitle('师'); $this->seo->prependTitle('');
} }
/** /**

View File

@ -20,6 +20,9 @@
<div class="layout-main"> <div class="layout-main">
<div class="layout-content"> <div class="layout-content">
<div class="player-wrap wrap"> <div class="player-wrap wrap">
<div id="play-mask" class="play-mask">
<span class="layui-icon layui-icon-play"></span>
</div>
<div id="player"></div> <div id="player"></div>
</div> </div>
<div id="comment-anchor"></div> <div id="comment-anchor"></div>

View File

@ -1,9 +1,8 @@
{% set logo_img = site_info.logo ? image(site_info.logo,false) : image('logo.png') %}
{% set logo_link = site_info.url ? site_info.url : '/' %}
<div class="logo"> <div class="logo">
{% if site_info.logo %} <a href="{{ logo_link }}">{{ logo_img }}</a>
{{ image(site_info.logo,false) }}
{% else %}
{{ image('logo.png') }}
{% endif %}
</div> </div>
<div class="top-nav"> <div class="top-nav">

View File

@ -6,7 +6,7 @@
<div class="layui-breadcrumb breadcrumb"> <div class="layui-breadcrumb breadcrumb">
<a href="/">首页</a> <a href="/">首页</a>
<a><cite>师</cite></a> <a><cite>师</cite></a>
</div> </div>
<div id="teacher-list" data-url="{{ pager_url }}"></div> <div id="teacher-list" data-url="{{ pager_url }}"></div>

View File

@ -16,7 +16,7 @@ class AppInfo
protected $link = 'https://www.koogua.com'; protected $link = 'https://www.koogua.com';
protected $version = '1.5.9'; protected $version = '1.6.0';
public function __get($name) public function __get($name)
{ {

41
app/Listeners/Help.php Normal file
View File

@ -0,0 +1,41 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Listeners;
use App\Models\Help as HelpModel;
use Phalcon\Events\Event as PhEvent;
class Help extends Listener
{
public function afterCreate(PhEvent $event, $source, HelpModel $help)
{
}
public function afterUpdate(PhEvent $event, $source, HelpModel $help)
{
}
public function afterDelete(PhEvent $event, $source, HelpModel $help)
{
}
public function afterRestore(PhEvent $event, $source, HelpModel $help)
{
}
public function afterView(PhEvent $event, $source, HelpModel $help)
{
}
}

41
app/Listeners/Page.php Normal file
View File

@ -0,0 +1,41 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Listeners;
use App\Models\Page as PageModel;
use Phalcon\Events\Event as PhEvent;
class Page extends Listener
{
public function afterCreate(PhEvent $event, $source, PageModel $page)
{
}
public function afterUpdate(PhEvent $event, $source, PageModel $page)
{
}
public function afterDelete(PhEvent $event, $source, PageModel $page)
{
}
public function afterRestore(PhEvent $event, $source, PageModel $page)
{
}
public function afterView(PhEvent $event, $source, PageModel $page)
{
}
}

View File

@ -69,6 +69,13 @@ class Help extends Model
*/ */
public $deleted = 0; public $deleted = 0;
/**
* 浏览量
*
* @var int
*/
public $view_count = 0;
/** /**
* 创建时间 * 创建时间
* *

View File

@ -198,4 +198,16 @@ class Notification extends Model
} }
} }
public function afterCreate()
{
/**
* @var $user User
*/
$user = User::findFirst($this->receiver_id);
$user->notice_count += 1;
$user->update();
}
} }

View File

@ -62,6 +62,13 @@ class Page extends Model
*/ */
public $deleted = 0; public $deleted = 0;
/**
* 浏览量
*
* @var int
*/
public $view_count = 0;
/** /**
* 创建时间 * 创建时间
* *

View File

@ -154,6 +154,13 @@ class User extends Model
*/ */
public $favorite_count = 0; public $favorite_count = 0;
/**
* 通知数
*
* @var int
*/
public $notice_count = 0;
/** /**
* 会员期限 * 会员期限
* *

View File

@ -32,6 +32,7 @@ class HelpInfo extends LogicService
'content' => $help->content, 'content' => $help->content,
'published' => $help->published, 'published' => $help->published,
'deleted' => $help->deleted, 'deleted' => $help->deleted,
'view_count' => $help->view_count,
'create_time' => $help->create_time, 'create_time' => $help->create_time,
'update_time' => $help->update_time, 'update_time' => $help->update_time,
]; ];

View File

@ -20,6 +20,10 @@ class PageInfo extends LogicService
{ {
$page = $this->checkPage($id); $page = $this->checkPage($id);
$this->incrPageViewCount($page);
$this->eventsManager->fire('Page:afterView', $this, $page);
return $this->handlePage($page); return $this->handlePage($page);
} }
@ -32,9 +36,17 @@ class PageInfo extends LogicService
'content' => $page->content, 'content' => $page->content,
'published' => $page->published, 'published' => $page->published,
'deleted' => $page->deleted, 'deleted' => $page->deleted,
'view_count' => $page->view_count,
'create_time' => $page->create_time, 'create_time' => $page->create_time,
'update_time' => $page->update_time, 'update_time' => $page->update_time,
]; ];
} }
protected function incrPageViewCount(PageModel $page)
{
$page->view_count += 1;
$page->update();
}
} }

View File

@ -7,7 +7,6 @@
namespace App\Services\Logic\User\Console; namespace App\Services\Logic\User\Console;
use App\Repos\User as UserRepo;
use App\Services\Logic\Service as LogicService; use App\Services\Logic\Service as LogicService;
class NotifyStats extends LogicService class NotifyStats extends LogicService
@ -17,16 +16,7 @@ class NotifyStats extends LogicService
{ {
$user = $this->getLoginUser(); $user = $this->getLoginUser();
$noticeCount = $this->getNoticeCount($user->id); return ['notice_count' => $user->notice_count];
return ['notice_count' => $noticeCount];
}
protected function getNoticeCount($userId)
{
$userRepo = new UserRepo();
return $userRepo->countUnreadNotifications($userId);
} }
} }

1471
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,8 @@ use App\Listeners\Answer;
use App\Listeners\Article; use App\Listeners\Article;
use App\Listeners\Comment; use App\Listeners\Comment;
use App\Listeners\Consult; use App\Listeners\Consult;
use App\Listeners\Help;
use App\Listeners\Page;
use App\Listeners\Question; use App\Listeners\Question;
use App\Listeners\Report; use App\Listeners\Report;
use App\Listeners\Review; use App\Listeners\Review;
@ -18,15 +20,17 @@ use App\Listeners\Trade;
use App\Listeners\UserDailyCounter; use App\Listeners\UserDailyCounter;
return [ return [
'UserDailyCounter' => UserDailyCounter::class,
'Account' => Account::class, 'Account' => Account::class,
'Answer' => Answer::class, 'Answer' => Answer::class,
'Article' => Article::class, 'Article' => Article::class,
'Comment' => Comment::class, 'Comment' => Comment::class,
'Consult' => Consult::class, 'Consult' => Consult::class,
'Help' => Help::class,
'Page' => Page::class,
'Question' => Question::class, 'Question' => Question::class,
'Report' => Report::class, 'Report' => Report::class,
'Review' => Review::class, 'Review' => Review::class,
'Trade' => Trade::class,
'Site' => Site::class, 'Site' => Site::class,
'Trade' => Trade::class,
'UserDailyCounter' => UserDailyCounter::class,
]; ];

View File

@ -155,7 +155,7 @@ final class V20210403184518 extends AbstractMigration
'id' => 5, 'id' => 5,
'parent_id' => 0, 'parent_id' => 0,
'level' => 1, 'level' => 1,
'name' => '师', 'name' => '',
'path' => ',5,', 'path' => ',5,',
'target' => '_self', 'target' => '_self',
'url' => '/teacher/list', 'url' => '/teacher/list',

View File

@ -0,0 +1,75 @@
<?php
/**
* @copyright Copyright (c) 2022 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
use Phinx\Db\Adapter\MysqlAdapter;
use Phinx\Migration\AbstractMigration;
final class V20221021035953 extends AbstractMigration
{
public function up()
{
$this->alterPageTable();
$this->alterHelpTable();
$this->alterUserTable();
}
protected function alterPageTable()
{
$table = $this->table('kg_page');
if ($table->hasColumn('view_count') == false) {
$table->addColumn('view_count', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '浏览数',
'after' => 'deleted',
]);
}
$table->save();
}
protected function alterHelpTable()
{
$table = $this->table('kg_help');
if ($table->hasColumn('view_count') == false) {
$table->addColumn('view_count', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '浏览数',
'after' => 'deleted',
]);
}
$table->save();
}
protected function alterUserTable()
{
$table = $this->table('kg_user');
if ($table->hasColumn('notice_count') == false) {
$table->addColumn('notice_count', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '通知数',
'after' => 'favorite_count',
]);
}
$table->save();
}
}

View File

@ -1335,6 +1335,26 @@
height: 428px; height: 428px;
} }
.play-mask {
top: 50%;
left: 50%;
z-index: 8;
position: absolute;
margin-top: -32px;
margin-left: -32px;
}
.play-mask .layui-icon-play {
color: white;
cursor: pointer;
font-size: 64px;
}
.play-mask .layui-icon-play:hover {
color: #00a4ff;
}
.chat-wrap .layui-card-header { .chat-wrap .layui-card-header {
text-align: center; text-align: center;
} }

View File

@ -158,6 +158,10 @@
border-left: none; border-left: none;
} }
.ke-content table tr:first-child td {
border-top: none;
}
.ke-content code, .ke-content code,
.ke-content pre { .ke-content pre {
font-family: Consolas, Monaco, Andale Mono, monospace; font-family: Consolas, Monaco, Andale Mono, monospace;

View File

@ -55,6 +55,14 @@ layui.use(['jquery', 'helper'], function () {
stop(); stop();
}); });
/**
* 播放器中央播放按钮点击事件
*/
$('#play-mask').on('click', function () {
$(this).hide();
player.toggle();
});
function start() { function start() {
if (interval != null) { if (interval != null) {
clearInterval(interval); clearInterval(interval);

View File

@ -51,6 +51,14 @@ layui.use(['jquery', 'helper'], function () {
ended(); ended();
}); });
/**
* 播放器中央播放按钮点击事件
*/
$('#play-mask').on('click', function () {
$(this).hide();
player.toggle();
});
var position = parseInt(lastPosition); var position = parseInt(lastPosition);
/** /**

View File

@ -48,7 +48,7 @@ layui.use(['jquery', 'form', 'element', 'layer', 'helper'], function () {
$token.attr('content', res.token); $token.attr('content', res.token);
} }
}); });
}, 300000); }, 600000);
if (window.user.id > 0) { if (window.user.id > 0) {
setInterval(function () { setInterval(function () {
@ -60,7 +60,7 @@ layui.use(['jquery', 'form', 'element', 'layer', 'helper'], function () {
$notifyDot.removeClass('layui-badge-dot'); $notifyDot.removeClass('layui-badge-dot');
} }
}); });
}, 30000); }, 60000);
setInterval(function () { setInterval(function () {
$.post('/uc/online'); $.post('/uc/online');
}, 60000); }, 60000);