mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-24 20:06:09 +08:00
Merge branch 'koogua/v1.7.4' into demo
# Conflicts: # CHANGELOG.md
This commit is contained in:
commit
4bf963c9ab
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,3 +1,15 @@
|
|||||||
|
### [v1.7.4](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.4)(2024-12-10)
|
||||||
|
|
||||||
|
- 更新layui-v2.9.20
|
||||||
|
- 优化编辑器内容自动提交
|
||||||
|
- 修正课时详情页目录高亮问题
|
||||||
|
- 修正CommentInfo中点赞判断
|
||||||
|
- 精简AccountSearchTrait
|
||||||
|
- 优化kg_h5_index_url()
|
||||||
|
- 优化CourseUserTrait
|
||||||
|
- 优化kg_setting()
|
||||||
|
- 优化CsrfToken
|
||||||
|
|
||||||
### [v1.7.3](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.3)(2024-10-10)
|
### [v1.7.3](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.3)(2024-10-10)
|
||||||
|
|
||||||
- 更新layui-v2.9.16
|
- 更新layui-v2.9.16
|
||||||
|
29
app/Console/Migrations/V20241110191316.php
Normal file
29
app/Console/Migrations/V20241110191316.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2024 深圳市酷瓜软件有限公司
|
||||||
|
* @license https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* @link https://www.koogua.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Console\Migrations;
|
||||||
|
|
||||||
|
class V20241110191316 extends Migration
|
||||||
|
{
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$this->handleContactSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleContactSettings()
|
||||||
|
{
|
||||||
|
$setting = [
|
||||||
|
'section' => 'contact',
|
||||||
|
'item_key' => 'douyin',
|
||||||
|
'item_value' => '',
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->saveSetting($setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -40,7 +40,7 @@ class CourseUser extends Service
|
|||||||
|
|
||||||
$sourceType = CourseUserModel::SOURCE_MANUAL;
|
$sourceType = CourseUserModel::SOURCE_MANUAL;
|
||||||
|
|
||||||
return $this->assignUserCourse($course, $user, $expiryTime, $sourceType);
|
$this->assignUserCourse($course, $user, $expiryTime, $sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUsers($id)
|
public function getUsers($id)
|
||||||
|
@ -45,7 +45,7 @@ class Resource extends Service
|
|||||||
|
|
||||||
$this->recountCourseResources($course);
|
$this->recountCourseResources($course);
|
||||||
|
|
||||||
return $upload;
|
return $resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateResource($id)
|
public function updateResource($id)
|
||||||
@ -67,6 +67,8 @@ class Resource extends Service
|
|||||||
$upload->update($data);
|
$upload->update($data);
|
||||||
|
|
||||||
$resource->update();
|
$resource->update();
|
||||||
|
|
||||||
|
return $resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteResource($id)
|
public function deleteResource($id)
|
||||||
@ -80,6 +82,8 @@ class Resource extends Service
|
|||||||
$resource->delete();
|
$resource->delete();
|
||||||
|
|
||||||
$this->recountCourseResources($course);
|
$this->recountCourseResources($course);
|
||||||
|
|
||||||
|
return $resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function findOrFail($id)
|
protected function findOrFail($id)
|
||||||
|
@ -15,31 +15,28 @@ trait AccountSearchTrait
|
|||||||
|
|
||||||
protected function handleAccountSearchParams($params)
|
protected function handleAccountSearchParams($params)
|
||||||
{
|
{
|
||||||
|
$key = null;
|
||||||
|
|
||||||
|
if (isset($params['user_id'])) {
|
||||||
|
$key = 'user_id';
|
||||||
|
} elseif (isset($params['owner_id'])) {
|
||||||
|
$key = 'owner_id';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($key == null) return $params;
|
||||||
|
|
||||||
$accountRepo = new AccountRepo();
|
$accountRepo = new AccountRepo();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 兼容用户编号|手机号码|邮箱地址查询
|
* 兼容用户编号|手机号码|邮箱地址查询
|
||||||
*/
|
*/
|
||||||
if (!empty($params['user_id'])) {
|
if (!empty($params[$key])) {
|
||||||
if (CommonValidator::phone($params['user_id'])) {
|
if (CommonValidator::phone($params[$key])) {
|
||||||
$account = $accountRepo->findByPhone($params['user_id']);
|
$account = $accountRepo->findByPhone($params[$key]);
|
||||||
$params['user_id'] = $account ? $account->id : -1000;
|
$params[$key] = $account ? $account->id : -1000;
|
||||||
} elseif (CommonValidator::email($params['user_id'])) {
|
} elseif (CommonValidator::email($params[$key])) {
|
||||||
$account = $accountRepo->findByEmail($params['user_id']);
|
$account = $accountRepo->findByEmail($params[$key]);
|
||||||
$params['user_id'] = $account ? $account->id : -1000;
|
$params[$key] = $account ? $account->id : -1000;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 兼容用户编号|手机号码|邮箱地址查询
|
|
||||||
*/
|
|
||||||
if (!empty($params['owner_id'])) {
|
|
||||||
if (CommonValidator::phone($params['owner_id'])) {
|
|
||||||
$account = $accountRepo->findByPhone($params['owner_id']);
|
|
||||||
$params['owner_id'] = $account ? $account->id : -1000;
|
|
||||||
} elseif (CommonValidator::email($params['owner_id'])) {
|
|
||||||
$account = $accountRepo->findByEmail($params['owner_id']);
|
|
||||||
$params['owner_id'] = $account ? $account->id : -1000;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ class User extends Service
|
|||||||
$this->db->commit();
|
$this->db->commit();
|
||||||
|
|
||||||
if ($adminRole > 0) {
|
if ($adminRole > 0) {
|
||||||
$this->updateAdminUserCount($adminRole);
|
$this->recountRoleUsers($adminRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->rebuildUserCache($user);
|
$this->rebuildUserCache($user);
|
||||||
@ -225,11 +225,11 @@ class User extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($oldAdminRole > 0) {
|
if ($oldAdminRole > 0) {
|
||||||
$this->updateAdminUserCount($oldAdminRole);
|
$this->recountRoleUsers($oldAdminRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($user->admin_role > 0) {
|
if ($user->admin_role > 0) {
|
||||||
$this->updateAdminUserCount($user->admin_role);
|
$this->recountRoleUsers($user->admin_role);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->rebuildUserCache($user);
|
$this->rebuildUserCache($user);
|
||||||
@ -341,7 +341,7 @@ class User extends Service
|
|||||||
$apiAuth->logoutClients($user->id);
|
$apiAuth->logoutClients($user->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function updateAdminUserCount($roleId)
|
protected function recountRoleUsers($roleId)
|
||||||
{
|
{
|
||||||
$roleRepo = new RoleRepo();
|
$roleRepo = new RoleRepo();
|
||||||
|
|
||||||
|
@ -40,6 +40,15 @@
|
|||||||
<button class="layui-btn" type="button" id="upload-toutiao">上传</button>
|
<button class="layui-btn" type="button" id="upload-toutiao">上传</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">抖音二维码</label>
|
||||||
|
<div class="layui-inline" style="width:40%;">
|
||||||
|
<input class="layui-input" type="text" name="douyin" placeholder="请确保存储已正确配置" value="{{ contact.douyin }}">
|
||||||
|
</div>
|
||||||
|
<div class="layui-inline">
|
||||||
|
<button class="layui-btn" type="button" id="upload-douyin">上传</button>
|
||||||
|
</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">
|
||||||
@ -138,6 +147,22 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
upload.render({
|
||||||
|
elem: '#upload-douyin',
|
||||||
|
url: '/admin/upload/icon/img',
|
||||||
|
exts: 'gif|jpg|png',
|
||||||
|
before: function () {
|
||||||
|
layer.load();
|
||||||
|
},
|
||||||
|
done: function (res, index, upload) {
|
||||||
|
$('input[name=douyin]').val(res.data.url);
|
||||||
|
layer.closeAll('loading');
|
||||||
|
},
|
||||||
|
error: function (index, upload) {
|
||||||
|
layer.msg('上传文件失败', {icon: 2});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{ client_type(item.client_type) }}</td>
|
<td>{{ client_type(item.client_type) }}</td>
|
||||||
<td><a href="javascript:" class="kg-ip2region" title="查看位置" data-ip="{{ item.client_ip }}">{{ item.client_ip }}</a></td>
|
<td><a href="javascript:" class="kg-ip2region" title="查看位置" data-ip="{{ item.client_ip }}">{{ item.client_ip }}</a></td>
|
||||||
<td>{{ date('Y-m-d H:i',item.active_time) }}</td>
|
<td>{{ date('Y-m-d H:i:s',item.active_time) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -15,6 +15,7 @@ use App\Services\Auth\Home as HomeAuth;
|
|||||||
use App\Services\Service as AppService;
|
use App\Services\Service as AppService;
|
||||||
use App\Traits\Response as ResponseTrait;
|
use App\Traits\Response as ResponseTrait;
|
||||||
use App\Traits\Security as SecurityTrait;
|
use App\Traits\Security as SecurityTrait;
|
||||||
|
use Phalcon\Config;
|
||||||
use Phalcon\Mvc\Dispatcher;
|
use Phalcon\Mvc\Dispatcher;
|
||||||
|
|
||||||
class Controller extends \Phalcon\Mvc\Controller
|
class Controller extends \Phalcon\Mvc\Controller
|
||||||
@ -46,7 +47,7 @@ class Controller extends \Phalcon\Mvc\Controller
|
|||||||
protected $contactInfo;
|
protected $contactInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var Config
|
||||||
*/
|
*/
|
||||||
protected $websocketInfo;
|
protected $websocketInfo;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{%- macro show_lesson_list(chapter) %}
|
{%- macro show_lesson_list(parent,chapter) %}
|
||||||
<ul class="sidebar-lesson-list">
|
<ul class="sidebar-lesson-list">
|
||||||
{% for lesson in chapter.children %}
|
{% for lesson in parent.children %}
|
||||||
{% set url = url({'for':'home.chapter.show','id':lesson.id}) %}
|
{% set url = url({'for':'home.chapter.show','id':lesson.id}) %}
|
||||||
{% set active = (chapter.id == lesson.id) ? 'active' : 'normal' %}
|
{% set active = (chapter.id == lesson.id) ? 'active' : 'normal' %}
|
||||||
<li class="lesson-title layui-elip">
|
<li class="lesson-title layui-elip">
|
||||||
@ -22,13 +22,13 @@
|
|||||||
{% for item in catalog %}
|
{% for item in catalog %}
|
||||||
<div class="chapter-title layui-elip">{{ item.title }}</div>
|
<div class="chapter-title layui-elip">{{ item.title }}</div>
|
||||||
<div class="sidebar-lesson-list">
|
<div class="sidebar-lesson-list">
|
||||||
{{ show_lesson_list(item) }}
|
{{ show_lesson_list(item,chapter) }}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="sidebar-lesson-list">
|
<div class="sidebar-lesson-list">
|
||||||
{{ show_lesson_list(catalog[0]) }}
|
{{ show_lesson_list(catalog[0],chapter) }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,6 +33,9 @@
|
|||||||
{% if contact_info.toutiao %}
|
{% if contact_info.toutiao %}
|
||||||
<a class="toutiao" href="javascript:" title="头条号"><span class="iconfont icon-toutiao"></span></a>
|
<a class="toutiao" href="javascript:" title="头条号"><span class="iconfont icon-toutiao"></span></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if contact_info.douyin %}
|
||||||
|
<a class="douyin" href="javascript:" title="抖音号"><span class="iconfont icon-douyin"></span></a>
|
||||||
|
{% endif %}
|
||||||
{% if contact_info.weibo %}
|
{% if contact_info.weibo %}
|
||||||
{% set link_url = 'https://weibo.com/u/%s'|format(contact_info.weibo) %}
|
{% set link_url = 'https://weibo.com/u/%s'|format(contact_info.weibo) %}
|
||||||
<a class="weibo" href="{{ link_url }}" title="微博主页"><span class="iconfont icon-weibo"></span></a>
|
<a class="weibo" href="{{ link_url }}" title="微博主页"><span class="iconfont icon-weibo"></span></a>
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
qq: '{{ contact_info.qq }}',
|
qq: '{{ contact_info.qq }}',
|
||||||
wechat: '{{ contact_info.wechat }}',
|
wechat: '{{ contact_info.wechat }}',
|
||||||
toutiao: '{{ contact_info.toutiao }}',
|
toutiao: '{{ contact_info.toutiao }}',
|
||||||
|
douyin: '{{ contact_info.douyin }}',
|
||||||
weibo: '{{ contact_info.weibo }}',
|
weibo: '{{ contact_info.weibo }}',
|
||||||
zhihu: '{{ contact_info.zhihu }}',
|
zhihu: '{{ contact_info.zhihu }}',
|
||||||
phone: '{{ contact_info.phone }}',
|
phone: '{{ contact_info.phone }}',
|
||||||
|
@ -16,7 +16,7 @@ class AppInfo
|
|||||||
|
|
||||||
protected $link = 'https://www.koogua.com';
|
protected $link = 'https://www.koogua.com';
|
||||||
|
|
||||||
protected $version = '1.7.3';
|
protected $version = '1.7.4';
|
||||||
|
|
||||||
public function __get($name)
|
public function __get($name)
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,7 @@ class CsrfToken
|
|||||||
$content = [
|
$content = [
|
||||||
$this->getExpiredTime(),
|
$this->getExpiredTime(),
|
||||||
$this->fixed,
|
$this->fixed,
|
||||||
Text::random(8),
|
Text::random(Text::RANDOM_ALNUM, 8),
|
||||||
];
|
];
|
||||||
|
|
||||||
$text = implode($this->delimiter, $content);
|
$text = implode($this->delimiter, $content);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
use App\Caches\Setting as SettingCache;
|
use App\Caches\Setting as SettingCache;
|
||||||
use App\Library\Purifier as HtmlPurifier;
|
use App\Library\Purifier as HtmlPurifier;
|
||||||
use App\Library\Validators\Common as CommonValidator;
|
use App\Library\Validators\Common as CommonValidator;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
use App\Services\Logic\Url\ShareUrl as ShareUrlService;
|
use App\Services\Logic\Url\ShareUrl as ShareUrlService;
|
||||||
use App\Services\Storage as StorageService;
|
use App\Services\Storage as StorageService;
|
||||||
use Phalcon\Config;
|
use Phalcon\Config;
|
||||||
@ -189,9 +190,10 @@ function kg_site_url()
|
|||||||
*
|
*
|
||||||
* @param string $section
|
* @param string $section
|
||||||
* @param string $key
|
* @param string $key
|
||||||
|
* @param mixed $defaultValue
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
function kg_setting($section, $key = null)
|
function kg_setting($section, $key = null, $defaultValue = null)
|
||||||
{
|
{
|
||||||
$cache = new SettingCache();
|
$cache = new SettingCache();
|
||||||
|
|
||||||
@ -199,7 +201,9 @@ function kg_setting($section, $key = null)
|
|||||||
|
|
||||||
if (!$key) return $settings;
|
if (!$key) return $settings;
|
||||||
|
|
||||||
return $settings[$key] ?? null;
|
if (isset($settings[$key])) return $settings[$key];
|
||||||
|
|
||||||
|
return $defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -488,7 +492,7 @@ function kg_editor_content_length($content)
|
|||||||
{
|
{
|
||||||
$content = trim($content);
|
$content = trim($content);
|
||||||
|
|
||||||
$content = strip_tags($content,'<img>');
|
$content = strip_tags($content, '<img>');
|
||||||
|
|
||||||
return kg_strlen($content);
|
return kg_strlen($content);
|
||||||
}
|
}
|
||||||
@ -768,7 +772,7 @@ function kg_static_url($path, $local = true, $version = null)
|
|||||||
$baseUri = rtrim($config->get('static_base_uri'), '/');
|
$baseUri = rtrim($config->get('static_base_uri'), '/');
|
||||||
$path = ltrim($path, '/');
|
$path = ltrim($path, '/');
|
||||||
$url = $local ? $baseUri . '/' . $path : $path;
|
$url = $local ? $baseUri . '/' . $path : $path;
|
||||||
$version = $version ? $version : $config->get('static_version');
|
$version = $version ?: $config->get('static_version');
|
||||||
|
|
||||||
if ($version) {
|
if ($version) {
|
||||||
$url .= '?v=' . $version;
|
$url .= '?v=' . $version;
|
||||||
@ -818,5 +822,13 @@ function kg_share_url($type, $id, $referer = 0)
|
|||||||
*/
|
*/
|
||||||
function kg_h5_index_url()
|
function kg_h5_index_url()
|
||||||
{
|
{
|
||||||
return kg_site_url() . '/h5/#/pages/index/index';
|
$service = new FullH5UrlService();
|
||||||
|
|
||||||
|
$url = $service->getHomeUrl();
|
||||||
|
|
||||||
|
if ($pos = strpos($url, '?')) {
|
||||||
|
return substr($url, 0, $pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
}
|
}
|
||||||
|
@ -462,7 +462,9 @@ class Course extends Model
|
|||||||
3 => '3个月',
|
3 => '3个月',
|
||||||
6 => '6个月',
|
6 => '6个月',
|
||||||
12 => '12个月',
|
12 => '12个月',
|
||||||
|
24 => '24个月',
|
||||||
36 => '36个月',
|
36 => '36个月',
|
||||||
|
48 => '48个月',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,11 +472,11 @@ class Course extends Model
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
0 => '0天',
|
0 => '0天',
|
||||||
|
1 => '1天',
|
||||||
|
3 => '3天',
|
||||||
7 => '7天',
|
7 => '7天',
|
||||||
14 => '14天',
|
14 => '14天',
|
||||||
30 => '30天',
|
30 => '30天',
|
||||||
90 => '90天',
|
|
||||||
180 => '180天',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,10 @@ class Chapter extends Repository
|
|||||||
$query->andWhere('course_id = :course_id:', ['course_id' => $where['course_id']]);
|
$query->andWhere('course_id = :course_id:', ['course_id' => $where['course_id']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($where['model'])) {
|
||||||
|
$query->andWhere('model = :model:', ['model' => $where['model']]);
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($where['published'])) {
|
if (isset($where['published'])) {
|
||||||
$query->andWhere('published = :published:', ['published' => $where['published']]);
|
$query->andWhere('published = :published:', ['published' => $where['published']]);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,8 @@ class Admin extends AuthService
|
|||||||
];
|
];
|
||||||
|
|
||||||
$this->session->set($authKey, $authInfo);
|
$this->session->set($authKey, $authInfo);
|
||||||
|
|
||||||
|
return $authInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function clearAuthInfo()
|
public function clearAuthInfo()
|
||||||
|
@ -39,6 +39,8 @@ class Home extends AuthService
|
|||||||
];
|
];
|
||||||
|
|
||||||
$this->session->set($authKey, $authInfo);
|
$this->session->set($authKey, $authInfo);
|
||||||
|
|
||||||
|
return $authInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function clearAuthInfo()
|
public function clearAuthInfo()
|
||||||
|
@ -10,7 +10,6 @@ namespace App\Services\Logic\Chapter;
|
|||||||
use App\Models\Chapter as ChapterModel;
|
use App\Models\Chapter as ChapterModel;
|
||||||
use App\Models\ChapterUser as ChapterUserModel;
|
use App\Models\ChapterUser as ChapterUserModel;
|
||||||
use App\Models\Course as CourseModel;
|
use App\Models\Course as CourseModel;
|
||||||
use App\Models\CourseUser as CourseUserModel;
|
|
||||||
use App\Models\User as UserModel;
|
use App\Models\User as UserModel;
|
||||||
use App\Repos\ChapterLike as ChapterLikeRepo;
|
use App\Repos\ChapterLike as ChapterLikeRepo;
|
||||||
use App\Services\Logic\ChapterTrait;
|
use App\Services\Logic\ChapterTrait;
|
||||||
@ -94,15 +93,7 @@ class ChapterInfo extends LogicService
|
|||||||
|
|
||||||
if (!$this->ownedCourse) return;
|
if (!$this->ownedCourse) return;
|
||||||
|
|
||||||
$sourceType = CourseUserModel::SOURCE_FREE;
|
$sourceType = $this->getFreeSourceType($course, $user);
|
||||||
|
|
||||||
if ($course->market_price > 0) {
|
|
||||||
if ($course->vip_price == 0 && $user->vip == 1) {
|
|
||||||
$sourceType = CourseUserModel::SOURCE_VIP;
|
|
||||||
} else {
|
|
||||||
$sourceType = CourseUserModel::SOURCE_TRIAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$courseUser = $this->createCourseUser($course, $user, 0, $sourceType);
|
$courseUser = $this->createCourseUser($course, $user, 0, $sourceType);
|
||||||
|
|
||||||
@ -199,7 +190,6 @@ class ChapterInfo extends LogicService
|
|||||||
$parent->user_count += 1;
|
$parent->user_count += 1;
|
||||||
|
|
||||||
$parent->update();
|
$parent->update();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ namespace App\Services\Logic\Comment;
|
|||||||
|
|
||||||
use App\Models\Comment as CommentModel;
|
use App\Models\Comment as CommentModel;
|
||||||
use App\Models\User as UserModel;
|
use App\Models\User as UserModel;
|
||||||
use App\Repos\AnswerLike as AnswerLikeRepo;
|
use App\Repos\CommentLike as CommentLikeRepo;
|
||||||
use App\Services\Logic\CommentTrait;
|
use App\Services\Logic\CommentTrait;
|
||||||
use App\Services\Logic\Service as LogicService;
|
use App\Services\Logic\Service as LogicService;
|
||||||
use App\Services\Logic\User\ShallowUserInfo;
|
use App\Services\Logic\User\ShallowUserInfo;
|
||||||
@ -84,9 +84,9 @@ class CommentInfo extends LogicService
|
|||||||
|
|
||||||
$me['logged'] = 1;
|
$me['logged'] = 1;
|
||||||
|
|
||||||
$likeRepo = new AnswerLikeRepo();
|
$likeRepo = new CommentLikeRepo();
|
||||||
|
|
||||||
$like = $likeRepo->findAnswerLike($comment->id, $user->id);
|
$like = $likeRepo->findCommentLike($comment->id, $user->id);
|
||||||
|
|
||||||
if ($like && $like->deleted == 0) {
|
if ($like && $like->deleted == 0) {
|
||||||
$me['liked'] = 1;
|
$me['liked'] = 1;
|
||||||
|
@ -50,7 +50,7 @@ trait CourseUserTrait
|
|||||||
|
|
||||||
$this->ownedCourse = true;
|
$this->ownedCourse = true;
|
||||||
|
|
||||||
} elseif ($course->market_price > 0 && $course->vip_price == 0 && $user->vip == 1) {
|
} elseif ($course->vip_price == 0 && $user->vip == 1) {
|
||||||
|
|
||||||
$this->ownedCourse = true;
|
$this->ownedCourse = true;
|
||||||
|
|
||||||
@ -80,19 +80,22 @@ trait CourseUserTrait
|
|||||||
|
|
||||||
protected function assignUserCourse(CourseModel $course, UserModel $user, int $expiryTime, int $sourceType)
|
protected function assignUserCourse(CourseModel $course, UserModel $user, int $expiryTime, int $sourceType)
|
||||||
{
|
{
|
||||||
|
if ($this->allowFreeAccess($course, $user)) return;
|
||||||
|
|
||||||
$courseUserRepo = new CourseUserRepo();
|
$courseUserRepo = new CourseUserRepo();
|
||||||
|
|
||||||
$relation = $courseUserRepo->findCourseUser($course->id, $user->id);
|
$relation = $courseUserRepo->findCourseUser($course->id, $user->id);
|
||||||
|
|
||||||
if (!$relation) {
|
if (!$relation) {
|
||||||
|
|
||||||
$relation = $this->createCourseUser($course, $user, $expiryTime, $sourceType);
|
$this->createCourseUser($course, $user, $expiryTime, $sourceType);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
switch ($relation->source_type) {
|
switch ($relation->source_type) {
|
||||||
case CourseUserModel::SOURCE_FREE:
|
case CourseUserModel::SOURCE_FREE:
|
||||||
case CourseUserModel::SOURCE_TRIAL:
|
case CourseUserModel::SOURCE_TRIAL:
|
||||||
|
case CourseUserModel::SOURCE_VIP:
|
||||||
$this->createCourseUser($course, $user, $expiryTime, $sourceType);
|
$this->createCourseUser($course, $user, $expiryTime, $sourceType);
|
||||||
$this->deleteCourseUser($relation);
|
$this->deleteCourseUser($relation);
|
||||||
break;
|
break;
|
||||||
@ -113,8 +116,6 @@ trait CourseUserTrait
|
|||||||
|
|
||||||
$this->recountCourseUsers($course);
|
$this->recountCourseUsers($course);
|
||||||
$this->recountUserCourses($user);
|
$this->recountUserCourses($user);
|
||||||
|
|
||||||
return $relation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createCourseUser(CourseModel $course, UserModel $user, int $expiryTime, int $sourceType)
|
protected function createCourseUser(CourseModel $course, UserModel $user, int $expiryTime, int $sourceType)
|
||||||
@ -160,4 +161,32 @@ trait CourseUserTrait
|
|||||||
$user->update();
|
$user->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function allowFreeAccess(CourseModel $course, UserModel $user)
|
||||||
|
{
|
||||||
|
$result = false;
|
||||||
|
|
||||||
|
if ($course->market_price == 0) {
|
||||||
|
$result = true;
|
||||||
|
} elseif ($course->vip_price == 0 && $user->vip == 1) {
|
||||||
|
$result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getFreeSourceType(CourseModel $course, UserModel $user)
|
||||||
|
{
|
||||||
|
$sourceType = CourseUserModel::SOURCE_FREE;
|
||||||
|
|
||||||
|
if ($course->market_price > 0) {
|
||||||
|
if ($course->vip_price == 0 && $user->vip == 1) {
|
||||||
|
$sourceType = CourseUserModel::SOURCE_VIP;
|
||||||
|
} else {
|
||||||
|
$sourceType = CourseUserModel::SOURCE_TRIAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sourceType;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class Security extends Validator
|
|||||||
$postToken = $this->request->getPost('csrf_token');
|
$postToken = $this->request->getPost('csrf_token');
|
||||||
|
|
||||||
if (in_array($route->getName(), $this->getCsrfWhitelist())) {
|
if (in_array($route->getName(), $this->getCsrfWhitelist())) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$service = new CsrfTokenService();
|
$service = new CsrfTokenService();
|
||||||
@ -38,6 +38,8 @@ class Security extends Validator
|
|||||||
if (!$result) {
|
if (!$result) {
|
||||||
throw new BadRequestException('security.invalid_csrf_token');
|
throw new BadRequestException('security.invalid_csrf_token');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkHttpReferer()
|
public function checkHttpReferer()
|
||||||
|
@ -55,6 +55,7 @@ layui.use(['jquery'], function () {
|
|||||||
*/
|
*/
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
editor.sync();
|
editor.sync();
|
||||||
|
if (!$form.attr('action').includes('update')) return;
|
||||||
if ($textarea.val().length > 30) {
|
if ($textarea.val().length > 30) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
|
@ -53,6 +53,7 @@ layui.use(['jquery'], function () {
|
|||||||
*/
|
*/
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
editor.sync();
|
editor.sync();
|
||||||
|
if (!$form.attr('action').includes('update')) return;
|
||||||
if ($textarea.val().length > 30) {
|
if ($textarea.val().length > 30) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
|
@ -36,6 +36,17 @@ layui.use(['jquery', 'helper', 'util'], function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var showDouYinCode = function () {
|
||||||
|
var content = '<div class="qrcode"><img src="' + window.contact.douyin + '" alt="扫码关注"></div>';
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
title: false,
|
||||||
|
closeBtn: 0,
|
||||||
|
shadeClose: true,
|
||||||
|
content: content,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var bars = [];
|
var bars = [];
|
||||||
|
|
||||||
if (window.contact.wechat) {
|
if (window.contact.wechat) {
|
||||||
@ -75,4 +86,8 @@ layui.use(['jquery', 'helper', 'util'], function () {
|
|||||||
showTouTiaoCode();
|
showTouTiaoCode();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.icon-douyin').on('click', function () {
|
||||||
|
showDouYinCode();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
@ -1,18 +1,22 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont"; /* Project id 2760791 */
|
font-family: "iconfont"; /* Project id 2760791 */
|
||||||
src: url('iconfont.woff2?t=1716885700001') format('woff2'),
|
src: url('iconfont.woff2?t=1731240803792') format('woff2'),
|
||||||
url('iconfont.woff?t=1716885700001') format('woff'),
|
url('iconfont.woff?t=1731240803792') format('woff'),
|
||||||
url('iconfont.ttf?t=1716885700001') format('truetype');
|
url('iconfont.ttf?t=1731240803792') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
font-family: "iconfont", serif !important;
|
font-family: "iconfont" !important;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-douyin:before {
|
||||||
|
content: "\e610";
|
||||||
|
}
|
||||||
|
|
||||||
.icon-pdf:before {
|
.icon-pdf:before {
|
||||||
content: "\e7b8";
|
content: "\e7b8";
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user