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

Merge branch 'koogua/v1.5.8' into demo

This commit is contained in:
koogua 2022-08-27 19:33:50 +08:00
commit 871fc92ffe
36 changed files with 702 additions and 942 deletions

View File

@ -1,4 +1,12 @@
### [v1.5.7](https://gitee.com/koogua/course-tencent-cloud/releases/v1.5.7)(2022-08-28) ### [v1.5.8](https://gitee.com/koogua/course-tencent-cloud/releases/v1.5.8)(2022-08-28)
- 整理migrations
- 更新自动安装脚本
- 优化登录/注册/忘记密码页
- 修复移动端首页课程缓存刷新
- sitemap条目增加过滤条件
### [v1.5.7](https://gitee.com/koogua/course-tencent-cloud/releases/v1.5.7)(2022-08-18)
- 清理群组残留 - 清理群组残留
- 升级腾讯云存储SDK到v2.5.6 - 升级腾讯云存储SDK到v2.5.6

View File

@ -39,6 +39,8 @@ class SitemapTask extends Task
$filename = tmp_path('sitemap.xml'); $filename = tmp_path('sitemap.xml');
echo '------ start sitemap task ------' . PHP_EOL;
$this->addIndex(); $this->addIndex();
$this->addCourses(); $this->addCourses();
$this->addArticles(); $this->addArticles();
@ -50,6 +52,8 @@ class SitemapTask extends Task
$this->addOthers(); $this->addOthers();
$this->sitemap->build($filename); $this->sitemap->build($filename);
echo '------ end sitemap task ------' . PHP_EOL;
} }
protected function getSiteUrl() protected function getSiteUrl()
@ -73,6 +77,7 @@ class SitemapTask extends Task
*/ */
$courses = CourseModel::query() $courses = CourseModel::query()
->where('published = 1') ->where('published = 1')
->andWhere('deleted = 0')
->orderBy('id DESC') ->orderBy('id DESC')
->limit(500) ->limit(500)
->execute(); ->execute();
@ -92,6 +97,7 @@ class SitemapTask extends Task
*/ */
$articles = ArticleModel::query() $articles = ArticleModel::query()
->where('published = :published:', ['published' => ArticleModel::PUBLISH_APPROVED]) ->where('published = :published:', ['published' => ArticleModel::PUBLISH_APPROVED])
->andWhere('deleted = 0')
->orderBy('id DESC') ->orderBy('id DESC')
->limit(500) ->limit(500)
->execute(); ->execute();
@ -111,6 +117,7 @@ class SitemapTask extends Task
*/ */
$questions = QuestionModel::query() $questions = QuestionModel::query()
->where('published = :published:', ['published' => QuestionModel::PUBLISH_APPROVED]) ->where('published = :published:', ['published' => QuestionModel::PUBLISH_APPROVED])
->andWhere('deleted = 0')
->orderBy('id DESC') ->orderBy('id DESC')
->limit(500) ->limit(500)
->execute(); ->execute();
@ -128,7 +135,10 @@ class SitemapTask extends Task
/** /**
* @var Resultset|UserModel[] $teachers * @var Resultset|UserModel[] $teachers
*/ */
$teachers = UserModel::query()->where('edu_role = 2')->execute(); $teachers = UserModel::query()
->where('edu_role = :edu_role:', ['edu_role' => UserModel::EDU_ROLE_TEACHER])
->andWhere('deleted = 0')
->execute();
if ($teachers->count() == 0) return; if ($teachers->count() == 0) return;
@ -143,7 +153,10 @@ class SitemapTask extends Task
/** /**
* @var Resultset|TopicModel[] $topics * @var Resultset|TopicModel[] $topics
*/ */
$topics = TopicModel::query()->where('published = 1')->execute(); $topics = TopicModel::query()
->where('published = 1')
->andWhere('deleted = 0')
->execute();
if ($topics->count() == 0) return; if ($topics->count() == 0) return;
@ -158,7 +171,10 @@ class SitemapTask extends Task
/** /**
* @var Resultset|PageModel[] $pages * @var Resultset|PageModel[] $pages
*/ */
$pages = PageModel::query()->where('published = 1')->execute(); $pages = PageModel::query()
->where('published = 1')
->andWhere('deleted = 0')
->execute();
if ($pages->count() == 0) return; if ($pages->count() == 0) return;
@ -173,7 +189,10 @@ class SitemapTask extends Task
/** /**
* @var Resultset|HelpModel[] $helps * @var Resultset|HelpModel[] $helps
*/ */
$helps = HelpModel::query()->where('published = 1')->execute(); $helps = HelpModel::query()
->where('published = 1')
->andWhere('deleted = 0')
->execute();
if ($helps->count() == 0) return; if ($helps->count() == 0) return;

View File

@ -51,25 +51,6 @@ class AccountController extends Controller
$this->view->setVar('captcha', $captcha); $this->view->setVar('captcha', $captcha);
} }
/**
* @Post("/register", name="home.account.do_register")
*/
public function doRegisterAction()
{
$service = new AccountService();
$service->register();
$returnUrl = $this->request->getPost('return_url', 'string');
$content = [
'location' => $returnUrl ?: '/',
'msg' => '注册成功',
];
return $this->jsonSuccess($content);
}
/** /**
* @Get("/login", name="home.account.login") * @Get("/login", name="home.account.login")
*/ */
@ -103,6 +84,62 @@ class AccountController extends Controller
$this->view->setVar('captcha', $captcha); $this->view->setVar('captcha', $captcha);
} }
/**
* @Get("/logout", name="home.account.logout")
*/
public function logoutAction()
{
$service = new AccountService();
$service->logout();
return $this->response->redirect(['for' => 'home.index']);
}
/**
* @Get("/forget", name="home.account.forget")
*/
public function forgetAction()
{
$service = new FullH5UrlService();
if ($service->isMobileBrowser() && $service->h5Enabled()) {
$location = $service->getAccountForgetUrl();
return $this->response->redirect($location);
}
if ($this->authUser->id > 0) {
return $this->response->redirect(['for' => 'home.index']);
}
$service = new AccountService();
$captcha = $service->getSettings('captcha');
$this->seo->prependTitle('重置密码');
$this->view->setVar('captcha', $captcha);
}
/**
* @Post("/register", name="home.account.do_register")
*/
public function doRegisterAction()
{
$service = new AccountService();
$service->register();
$returnUrl = $this->request->getPost('return_url', 'string');
$content = [
'location' => $returnUrl ?: '/',
'msg' => '注册成功',
];
return $this->jsonSuccess($content);
}
/** /**
* @Post("/password/login", name="home.account.pwd_login") * @Post("/password/login", name="home.account.pwd_login")
*/ */
@ -135,44 +172,6 @@ class AccountController extends Controller
return $this->jsonSuccess(['location' => $location]); return $this->jsonSuccess(['location' => $location]);
} }
/**
* @Get("/logout", name="home.account.logout")
*/
public function logoutAction()
{
$service = new AccountService();
$service->logout();
return $this->response->redirect(['for' => 'home.index']);
}
/**
* @Get("/password/forget", name="home.account.forget_pwd")
*/
public function forgetPasswordAction()
{
$service = new FullH5UrlService();
if ($service->isMobileBrowser() && $service->h5Enabled()) {
$location = $service->getAccountForgetUrl();
return $this->response->redirect($location);
}
if ($this->authUser->id > 0) {
return $this->response->redirect(['for' => 'home.index']);
}
$service = new AccountService();
$captcha = $service->getSettings('captcha');
$this->seo->prependTitle('忘记密码');
$this->view->pick('account/forget_password');
$this->view->setVar('captcha', $captcha);
}
/** /**
* @Post("/password/reset", name="home.account.reset_pwd") * @Post("/password/reset", name="home.account.reset_pwd")
*/ */

View File

@ -47,6 +47,15 @@ class Account extends Service
{ {
$post = $this->request->getPost(); $post = $this->request->getPost();
/**
* 使用[account|phone|email]做账户名字段兼容
*/
if (isset($post['phone'])) {
$post['account'] = $post['phone'];
} elseif (isset($post['email'])) {
$post['account'] = $post['email'];
}
$validator = new AccountValidator(); $validator = new AccountValidator();
$user = $validator->checkUserLogin($post['account'], $post['password']); $user = $validator->checkUserLogin($post['account'], $post['password']);
@ -74,6 +83,15 @@ class Account extends Service
{ {
$post = $this->request->getPost(); $post = $this->request->getPost();
/**
* 使用[account|phone|email]做账户名字段兼容
*/
if (isset($post['phone'])) {
$post['account'] = $post['phone'];
} elseif (isset($post['email'])) {
$post['account'] = $post['email'];
}
$validator = new AccountValidator(); $validator = new AccountValidator();
$user = $validator->checkVerifyLogin($post['account'], $post['verify_code']); $user = $validator->checkVerifyLogin($post['account'], $post['verify_code']);

View File

@ -0,0 +1,42 @@
{% extends 'templates/main.volt' %}
{% block content %}
{% set action_url = url({'for':'home.account.reset_pwd'}) %}
<div class="layui-breadcrumb breadcrumb">
<a href="/">首页</a>
<a><cite>重置密码</cite></a>
</div>
<div class="login-wrap wrap">
<div class="layui-tab layui-tab-brief login-tab">
<ul class="layui-tab-title login-tab-title">
<li class="layui-this">手机方式</li>
<li>邮箱方式</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
{{ partial('account/forget_by_phone') }}
</div>
<div class="layui-tab-item">
{{ partial('account/forget_by_email') }}
</div>
</div>
</div>
<div class="link">
<a class="login-link" href="{{ url({'for':'home.account.login'}) }}">用户登录</a>
<span class="separator">·</span>
<a class="forget-link" href="{{ url({'for':'home.account.register'}) }}">用户注册</a>
</div>
</div>
{% endblock %}
{% block include_js %}
{{ js_include('https://ssl.captcha.qq.com/TCaptcha.js',false) }}
{{ js_include('home/js/captcha.verify.phone.js') }}
{{ js_include('home/js/captcha.verify.email.js') }}
{% endblock %}

View File

@ -0,0 +1,28 @@
<form class="layui-form account-form" method="POST" action="{{ action_url }}">
<div class="layui-form-item">
<label class="layui-icon layui-icon-email"></label>
<input id="cv-email" class="layui-input" type="text" name="email" autocomplete="off" placeholder="邮箱" lay-verify="email">
</div>
<div class="layui-form-item">
<label class="layui-icon layui-icon-password"></label>
<input class="layui-input" type="password" name="new_password" autocomplete="off" placeholder="新密码字母数字特殊字符6-16位" lay-verify="required">
</div>
<div class="layui-form-item">
<div class="layui-input-inline verify-input-inline">
<label class="layui-icon layui-icon-vercode"></label>
<input class="layui-input" type="text" name="verify_code" autocomplete="off" placeholder="验证码" lay-verify="required">
</div>
<div class="layui-input-inline verify-btn-inline">
<button id="cv-email-emit-btn" class="layui-btn layui-btn-disabled" type="button" disabled="disabled">获取验证码</button>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button id="cv-email-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">重置密码</button>
<input id="cv-email-captcha-enabled" type="hidden" value="{{ captcha.enabled }}">
<input id="cv-email-captcha-appId" type="hidden" value="{{ captcha.app_id }}">
<input id="cv-email-captcha-ticket" type="hidden" name="captcha[ticket]">
<input id="cv-email-captcha-rand" type="hidden" name="captcha[rand]">
</div>
</div>
</form>

View File

@ -0,0 +1,28 @@
<form class="layui-form account-form" method="POST" action="{{ action_url }}">
<div class="layui-form-item">
<label class="layui-icon layui-icon-cellphone"></label>
<input id="cv-phone" class="layui-input" type="text" name="phone" autocomplete="off" placeholder="手机" lay-verify="phone">
</div>
<div class="layui-form-item">
<label class="layui-icon layui-icon-password"></label>
<input class="layui-input" type="password" name="new_password" autocomplete="off" placeholder="新密码字母数字特殊字符6-16位" lay-verify="required">
</div>
<div class="layui-form-item">
<div class="layui-input-inline verify-input-inline">
<label class="layui-icon layui-icon-vercode"></label>
<input class="layui-input" type="text" name="verify_code" autocomplete="off" placeholder="验证码" lay-verify="required">
</div>
<div class="layui-input-inline verify-btn-inline">
<button id="cv-phone-emit-btn" class="layui-btn layui-btn-disabled" type="button" disabled="disabled">获取验证码</button>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button id="cv-phone-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">重置密码</button>
<input id="cv-phone-captcha-enabled" type="hidden" value="{{ captcha.enabled }}">
<input id="cv-phone-captcha-appId" type="hidden" value="{{ captcha.app_id }}">
<input id="cv-phone-captcha-ticket" type="hidden" name="captcha[ticket]">
<input id="cv-phone-captcha-rand" type="hidden" name="captcha[rand]">
</div>
</div>
</form>

View File

@ -1,48 +0,0 @@
{% extends 'templates/main.volt' %}
{% block content %}
<div class="layui-breadcrumb breadcrumb">
<a href="/">首页</a>
<a><cite>忘记密码</cite></a>
</div>
<div class="account-wrap wrap">
<form class="layui-form account-form" method="POST" action="{{ url({'for':'home.account.reset_pwd'}) }}">
<div class="layui-form-item">
<label class="layui-icon layui-icon-username"></label>
<input id="cv-account" class="layui-input" type="text" name="account" autocomplete="off" placeholder="手机 / 邮箱" lay-verify="required">
</div>
<div class="layui-form-item">
<label class="layui-icon layui-icon-password"></label>
<input class="layui-input" type="password" name="new_password" autocomplete="off" placeholder="新密码字母数字特殊字符6-16位" lay-verify="required">
</div>
<div class="layui-form-item">
<div class="layui-input-inline verify-input-inline">
<label class="layui-icon layui-icon-vercode"></label>
<input class="layui-input" type="text" name="verify_code" autocomplete="off" placeholder="验证码" lay-verify="required">
</div>
<div class="layui-input-inline verify-btn-inline">
<button id="cv-emit-btn" class="layui-btn layui-btn-disabled" type="button" disabled="disabled">获取验证码</button>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button id="cv-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">重置密码</button>
<input id="cv-captcha-enabled" type="hidden" value="{{ captcha.enabled }}">
<input id="cv-captcha-appId" type="hidden" value="{{ captcha.app_id }}">
<input id="cv-captcha-ticket" type="hidden" name="captcha[ticket]">
<input id="cv-captcha-rand" type="hidden" name="captcha[rand]">
</div>
</div>
</form>
</div>
{% endblock %}
{% block include_js %}
{{ js_include('https://ssl.captcha.qq.com/TCaptcha.js',false) }}
{{ js_include('home/js/captcha.verify.js') }}
{% endblock %}

View File

@ -4,7 +4,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 class="login-wrap wrap"> <div class="login-wrap wrap">
@ -23,9 +23,9 @@
</div> </div>
</div> </div>
<div class="link"> <div class="link">
<a class="login-link" href="{{ url({'for':'home.account.register'}) }}">免费注册</a> <a class="login-link" href="{{ url({'for':'home.account.register'}) }}">用户注册</a>
<span class="separator">·</span> <span class="separator">·</span>
<a class="forget-link" href="{{ url({'for':'home.account.forget_pwd'}) }}">忘记密码</a> <a class="forget-link" href="{{ url({'for':'home.account.forget'}) }}">忘记密码</a>
</div> </div>
<div class="oauth"> <div class="oauth">
{% if oauth_provider.qq.enabled == 1 %} {% if oauth_provider.qq.enabled == 1 %}

View File

@ -4,54 +4,33 @@
{% set register_with_phone = local_oauth.register_with_phone == 1 %} {% set register_with_phone = local_oauth.register_with_phone == 1 %}
{% set register_with_email = local_oauth.register_with_email == 1 %} {% set register_with_email = local_oauth.register_with_email == 1 %}
{% set action_url = url({'for':'home.account.do_register'}) %}
<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 class="account-wrap wrap"> <div class="login-wrap wrap">
<form class="layui-form account-form" method="POST" action="{{ url({'for':'home.account.do_register'}) }}"> <div class="layui-tab layui-tab-brief login-tab">
{% if register_with_phone and register_with_email %} <ul class="layui-tab-title login-tab-title">
<div class="layui-form-item"> <li class="layui-this">手机注册</li>
<label class="layui-icon layui-icon-username"></label> <li>邮箱注册</li>
<input id="cv-account" class="layui-input" type="text" name="account" autocomplete="off" placeholder="手机 / 邮箱" lay-verify="required"> </ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
{{ partial('account/register_by_phone') }}
</div> </div>
{% elseif register_with_email %} <div class="layui-tab-item">
<div class="layui-form-item"> {{ partial('account/register_by_email') }}
<label class="layui-icon layui-icon-email"></label>
<input id="cv-account" class="layui-input" type="text" name="account" autocomplete="off" placeholder="邮箱" lay-verify="email">
</div>
{% else %}
<div class="layui-form-item">
<label class="layui-icon layui-icon-cellphone"></label>
<input id="cv-account" class="layui-input" type="text" name="account" autocomplete="off" placeholder="手机" lay-verify="phone">
</div>
{% endif %}
<div class="layui-form-item">
<label class="layui-icon layui-icon-password"></label>
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码字母数字特殊字符6-16位" lay-verify="required">
</div>
<div class="layui-form-item">
<div class="layui-input-inline verify-input-inline">
<label class="layui-icon layui-icon-vercode"></label>
<input class="layui-input" type="text" name="verify_code" placeholder="验证码" lay-verify="required">
</div>
<div class="layui-input-inline verify-btn-inline">
<button id="cv-emit-btn" class="layui-btn layui-btn-disabled" type="button" disabled="disabled">获取验证码</button>
</div> </div>
</div> </div>
<div class="layui-form-item"> </div>
<div class="layui-input-block"> <div class="link">
<button id="cv-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">注册帐号</button> <a class="login-link" href="{{ url({'for':'home.account.login'}) }}">用户登录</a>
<input type="hidden" name="return_url" value="{{ return_url }}"> <span class="separator">·</span>
<input id="cv-captcha-enabled" type="hidden" value="{{ captcha.enabled }}"> <a class="forget-link" href="{{ url({'for':'home.account.forget'}) }}">忘记密码</a>
<input id="cv-captcha-appId" type="hidden" value="{{ captcha.app_id }}"> </div>
<input id="cv-captcha-ticket" type="hidden" name="captcha[ticket]">
<input id="cv-captcha-rand" type="hidden" name="captcha[rand]">
</div>
</div>
</form>
</div> </div>
{% endblock %} {% endblock %}
@ -59,6 +38,7 @@
{% block include_js %} {% block include_js %}
{{ js_include('https://ssl.captcha.qq.com/TCaptcha.js',false) }} {{ js_include('https://ssl.captcha.qq.com/TCaptcha.js',false) }}
{{ js_include('home/js/captcha.verify.js') }} {{ js_include('home/js/captcha.verify.phone.js') }}
{{ js_include('home/js/captcha.verify.email.js') }}
{% endblock %} {% endblock %}

View File

@ -0,0 +1,35 @@
{% if register_with_email %}
<form class="layui-form account-form" method="POST" action="{{ action_url }}">
<div class="layui-form-item">
<label class="layui-icon layui-icon-email"></label>
<input id="cv-email" class="layui-input" type="text" name="email" autocomplete="off" placeholder="邮箱" lay-verify="email">
</div>
<div class="layui-form-item">
<label class="layui-icon layui-icon-password"></label>
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码字母数字特殊字符6-16位" lay-verify="required">
</div>
<div class="layui-form-item">
<div class="layui-input-inline verify-input-inline">
<label class="layui-icon layui-icon-vercode"></label>
<input class="layui-input" type="text" name="verify_code" placeholder="验证码" lay-verify="required">
</div>
<div class="layui-input-inline verify-btn-inline">
<button id="cv-email-emit-btn" class="layui-btn layui-btn-disabled" type="button" disabled="disabled">获取验证码</button>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button id="cv-email-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">注册帐号</button>
<input type="hidden" name="return_url" value="{{ return_url }}">
<input id="cv-email-captcha-enabled" type="hidden" value="{{ captcha.enabled }}">
<input id="cv-email-captcha-appId" type="hidden" value="{{ captcha.app_id }}">
<input id="cv-email-captcha-ticket" type="hidden" name="captcha[ticket]">
<input id="cv-email-captcha-rand" type="hidden" name="captcha[rand]">
</div>
</div>
</form>
{% else %}
<div class="register-close-tips">
<i class="layui-icon layui-icon-tips"></i> 邮箱注册已关闭
</div>
{% endif %}

View File

@ -0,0 +1,35 @@
{% if register_with_phone == 1 %}
<form class="layui-form account-form" method="POST" action="{{ action_url }}">
<div class="layui-form-item">
<label class="layui-icon layui-icon-cellphone"></label>
<input id="cv-phone" class="layui-input" type="text" name="phone" autocomplete="off" placeholder="手机" lay-verify="phone">
</div>
<div class="layui-form-item">
<label class="layui-icon layui-icon-password"></label>
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码字母数字特殊字符6-16位" lay-verify="required">
</div>
<div class="layui-form-item">
<div class="layui-input-inline verify-input-inline">
<label class="layui-icon layui-icon-vercode"></label>
<input class="layui-input" type="text" name="verify_code" placeholder="验证码" lay-verify="required">
</div>
<div class="layui-input-inline verify-btn-inline">
<button id="cv-phone-emit-btn" class="layui-btn layui-btn-disabled" type="button" disabled="disabled">获取验证码</button>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button id="cv-phone-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">注册帐号</button>
<input type="hidden" name="return_url" value="{{ return_url }}">
<input id="cv-phone-captcha-enabled" type="hidden" value="{{ captcha.enabled }}">
<input id="cv-phone-captcha-appId" type="hidden" value="{{ captcha.app_id }}">
<input id="cv-phone-captcha-ticket" type="hidden" name="captcha[ticket]">
<input id="cv-phone-captcha-rand" type="hidden" name="captcha[rand]">
</div>
</div>
</form>
{% else %}
<div class="register-close-tips">
<i class="layui-icon layui-icon-tips"></i> 手机注册已关闭
</div>
{% endif %}

View File

@ -19,7 +19,7 @@
<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 id="cv-account" class="layui-input" type="text" name="email" data-type="email" lay-verify="required"> <input id="cv-email" class="layui-input" type="text" name="email" lay-verify="required">
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
@ -28,16 +28,16 @@
<input class="layui-input" type="text" name="verify_code" lay-verify="required"> <input class="layui-input" type="text" name="verify_code" lay-verify="required">
</div> </div>
<div class="layui-input-inline verify-btn-inline"> <div class="layui-input-inline verify-btn-inline">
<button id="cv-emit-btn" class="layui-btn layui-btn-disabled" type="button" disabled="disabled">获取验证码</button> <button id="cv-email-emit-btn" class="layui-btn layui-btn-disabled" type="button" disabled="disabled">获取验证码</button>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
<div class="layui-input-block"> <div class="layui-input-block">
<button id="cv-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">提交修改</button> <button id="cv-email-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">提交修改</button>
<input id="cv-captcha-enabled" type="hidden" value="{{ captcha.enabled }}"> <input id="cv-email-captcha-enabled" type="hidden" value="{{ captcha.enabled }}">
<input id="cv-captcha-appId" type="hidden" value="{{ captcha.app_id }}"> <input id="cv-email-captcha-appId" type="hidden" value="{{ captcha.app_id }}">
<input id="cv-captcha-ticket" type="hidden" name="captcha[ticket]"> <input id="cv-email-captcha-ticket" type="hidden" name="captcha[ticket]">
<input id="cv-captcha-rand" type="hidden" name="captcha[rand]"> <input id="cv-email-captcha-rand" type="hidden" name="captcha[rand]">
</div> </div>
</div> </div>
</form> </form>

View File

@ -19,7 +19,7 @@
<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 id="cv-account" class="layui-input" type="text" name="phone" data-type="phone" lay-verify="required"> <input id="cv-phone" class="layui-input" type="text" name="phone" lay-verify="required">
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
@ -28,16 +28,16 @@
<input class="layui-input" type="text" name="verify_code" lay-verify="required"> <input class="layui-input" type="text" name="verify_code" lay-verify="required">
</div> </div>
<div class="layui-input-inline verify-btn-inline"> <div class="layui-input-inline verify-btn-inline">
<button id="cv-emit-btn" class="layui-btn layui-btn-disabled" type="button" disabled="disabled">获取验证码</button> <button id="cv-phone-emit-btn" class="layui-btn layui-btn-disabled" type="button" disabled="disabled">获取验证码</button>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
<div class="layui-input-block"> <div class="layui-input-block">
<button id="cv-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">提交修改</button> <button id="cv-phone-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">提交修改</button>
<input id="cv-captcha-enabled" type="hidden" value="{{ captcha.enabled }}"> <input id="cv-phone-captcha-enabled" type="hidden" value="{{ captcha.enabled }}">
<input id="cv-captcha-appId" type="hidden" value="{{ captcha.app_id }}"> <input id="cv-phone-captcha-appId" type="hidden" value="{{ captcha.app_id }}">
<input id="cv-captcha-ticket" type="hidden" name="captcha[ticket]"> <input id="cv-phone-captcha-ticket" type="hidden" name="captcha[ticket]">
<input id="cv-captcha-rand" type="hidden" name="captcha[rand]"> <input id="cv-phone-captcha-rand" type="hidden" name="captcha[rand]">
</div> </div>
</div> </div>
</form> </form>

View File

@ -19,6 +19,15 @@ class PasswordReset extends LogicService
{ {
$post = $this->request->getPost(); $post = $this->request->getPost();
/**
* 使用[account|phone|email]做账户名字段兼容
*/
if (isset($post['phone'])) {
$post['account'] = $post['phone'];
} elseif (isset($post['email'])) {
$post['account'] = $post['email'];
}
$accountValidator = new AccountValidator(); $accountValidator = new AccountValidator();
$account = $accountValidator->checkAccount($post['account']); $account = $accountValidator->checkAccount($post['account']);

View File

@ -21,6 +21,15 @@ class Register extends LogicService
{ {
$post = $this->request->getPost(); $post = $this->request->getPost();
/**
* 使用[account|phone|email]做账户名字段兼容
*/
if (isset($post['phone'])) {
$post['account'] = $post['phone'];
} elseif (isset($post['email'])) {
$post['account'] = $post['email'];
}
$verifyValidator = new VerifyValidator(); $verifyValidator = new VerifyValidator();
$verifyValidator->checkCode($post['account'], $post['verify_code']); $verifyValidator->checkCode($post['account'], $post['verify_code']);

View File

@ -22,48 +22,36 @@ class IndexCourseCache extends AppService
public function rebuild($section = null) public function rebuild($section = null)
{ {
$site = $this->getSettings('site');
$type = $site['index_tpl_type'] ?: 'full';
if (!$section || $section == 'featured_course') { if (!$section || $section == 'featured_course') {
if ($type == 'full') { $cache = new IndexFeaturedCourseListCache();
$cache = new IndexFeaturedCourseListCache(); $cache->rebuild();
$cache->rebuild();
} else { $cache = new IndexSimpleFeaturedCourseListCache();
$cache = new IndexSimpleFeaturedCourseListCache(); $cache->rebuild();
$cache->rebuild();
}
} }
if (!$section || $section == 'new_course') { if (!$section || $section == 'new_course') {
if ($type == 'full') { $cache = new IndexNewCourseListCache();
$cache = new IndexNewCourseListCache(); $cache->rebuild();
$cache->rebuild();
} else { $cache = new IndexSimpleNewCourseListCache();
$cache = new IndexSimpleNewCourseListCache(); $cache->rebuild();
$cache->rebuild();
}
} }
if (!$section || $section == 'free_course') { if (!$section || $section == 'free_course') {
if ($type == 'full') { $cache = new IndexFreeCourseListCache();
$cache = new IndexFreeCourseListCache(); $cache->rebuild();
$cache->rebuild();
} else { $cache = new IndexSimpleFreeCourseListCache();
$cache = new IndexSimpleFreeCourseListCache(); $cache->rebuild();
$cache->rebuild();
}
} }
if (!$section || $section == 'vip_course') { if (!$section || $section == 'vip_course') {
if ($type == 'full') { $cache = new IndexVipCourseListCache();
$cache = new IndexVipCourseListCache(); $cache->rebuild();
$cache->rebuild();
} else { $cache = new IndexSimpleVipCourseListCache();
$cache = new IndexSimpleVipCourseListCache(); $cache->rebuild();
$cache->rebuild();
}
} }
} }

View File

@ -3268,619 +3268,6 @@ final class V20210324064239 extends AbstractMigration
'after' => 'create_time', 'after' => 'create_time',
]) ])
->create(); ->create();
$this->table('kg_im_friend_group', [
'id' => false,
'primary_key' => ['id'],
'engine' => 'InnoDB',
'encoding' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'comment' => '',
'row_format' => 'DYNAMIC',
])
->addColumn('id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'identity' => 'enable',
'comment' => '主键编号',
])
->addColumn('user_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '用户编号',
'after' => 'id',
])
->addColumn('name', 'string', [
'null' => false,
'default' => '',
'limit' => 100,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '名称',
'after' => 'user_id',
])
->addColumn('priority', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '优先级',
'after' => 'name',
])
->addColumn('deleted', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '删除标识',
'after' => 'priority',
])
->addColumn('user_count', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '成员数',
'after' => 'deleted',
])
->addColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'user_count',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->addIndex(['user_id'], [
'name' => 'user_id',
'unique' => true,
])
->create();
$this->table('kg_im_friend_user', [
'id' => false,
'primary_key' => ['id'],
'engine' => 'InnoDB',
'encoding' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'comment' => '',
'row_format' => 'DYNAMIC',
])
->addColumn('id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'identity' => 'enable',
'comment' => '主键编号',
])
->addColumn('user_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '用户编号',
'after' => 'id',
])
->addColumn('friend_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '目标编号',
'after' => 'user_id',
])
->addColumn('group_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '分组编号',
'after' => 'friend_id',
])
->addColumn('msg_count', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '消息数',
'after' => 'group_id',
])
->addColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'msg_count',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->addIndex(['user_id', 'friend_id'], [
'name' => 'user_friend',
'unique' => false,
])
->create();
$this->table('kg_im_group', [
'id' => false,
'primary_key' => ['id'],
'engine' => 'InnoDB',
'encoding' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'comment' => '',
'row_format' => 'DYNAMIC',
])
->addColumn('id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'identity' => 'enable',
'comment' => '主键编号',
])
->addColumn('owner_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '群主编号',
'after' => 'id',
])
->addColumn('course_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '课程编号',
'after' => 'owner_id',
])
->addColumn('type', 'integer', [
'null' => false,
'default' => '1',
'limit' => MysqlAdapter::INT_REGULAR,
'comment' => '类型',
'after' => 'course_id',
])
->addColumn('name', 'string', [
'null' => false,
'default' => '',
'limit' => 100,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '名称',
'after' => 'type',
])
->addColumn('avatar', 'string', [
'null' => false,
'default' => '',
'limit' => 100,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '头像',
'after' => 'name',
])
->addColumn('about', 'string', [
'null' => false,
'default' => '',
'limit' => 255,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '简介',
'after' => 'avatar',
])
->addColumn('published', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '发布标识',
'after' => 'about',
])
->addColumn('deleted', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '删除标识',
'after' => 'published',
])
->addColumn('user_count', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '成员数',
'after' => 'deleted',
])
->addColumn('msg_count', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '消息数',
'after' => 'user_count',
])
->addColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'msg_count',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->create();
$this->table('kg_im_group_user', [
'id' => false,
'primary_key' => ['id'],
'engine' => 'InnoDB',
'encoding' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'comment' => '',
'row_format' => 'DYNAMIC',
])
->addColumn('id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'identity' => 'enable',
'comment' => '主键编号',
])
->addColumn('group_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '群组编号',
'after' => 'id',
])
->addColumn('user_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '用户编号',
'after' => 'group_id',
])
->addColumn('priority', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '优先级',
'after' => 'user_id',
])
->addColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'priority',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->addIndex(['group_id'], [
'name' => 'group_id',
'unique' => false,
])
->addIndex(['group_id', 'user_id'], [
'name' => 'group_user',
'unique' => false,
])
->addIndex(['user_id'], [
'name' => 'user_id',
'unique' => false,
])
->create();
$this->table('kg_im_message', [
'id' => false,
'primary_key' => ['id'],
'engine' => 'InnoDB',
'encoding' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'comment' => '',
'row_format' => 'DYNAMIC',
])
->addColumn('id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'identity' => 'enable',
'comment' => '主键编号',
])
->addColumn('chat_id', 'string', [
'null' => false,
'default' => '',
'limit' => 30,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '对话编号',
'after' => 'id',
])
->addColumn('sender_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '发送方',
'after' => 'chat_id',
])
->addColumn('receiver_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '接收方',
'after' => 'sender_id',
])
->addColumn('receiver_type', 'integer', [
'null' => false,
'default' => '1',
'limit' => MysqlAdapter::INT_REGULAR,
'comment' => '接收方类型',
'after' => 'receiver_id',
])
->addColumn('content', 'string', [
'null' => false,
'default' => '',
'limit' => 3000,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '内容',
'after' => 'receiver_type',
])
->addColumn('viewed', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '已读标识',
'after' => 'content',
])
->addColumn('deleted', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '删除标识',
'after' => 'viewed',
])
->addColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'deleted',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->addIndex(['chat_id'], [
'name' => 'chat_id',
'unique' => false,
])
->addIndex(['receiver_id', 'receiver_type'], [
'name' => 'receiver',
'unique' => false,
])
->create();
$this->table('kg_im_notice', [
'id' => false,
'primary_key' => ['id'],
'engine' => 'InnoDB',
'encoding' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'comment' => '',
'row_format' => 'DYNAMIC',
])
->addColumn('id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'identity' => 'enable',
'comment' => '主键编号',
])
->addColumn('sender_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '发送方',
'after' => 'id',
])
->addColumn('receiver_id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '接收方',
'after' => 'sender_id',
])
->addColumn('item_type', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '条目类型',
'after' => 'receiver_id',
])
->addColumn('item_info', 'string', [
'null' => false,
'default' => '',
'limit' => 1500,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '条目内容',
'after' => 'item_type',
])
->addColumn('viewed', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '已读标识',
'after' => 'item_info',
])
->addColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'viewed',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->addIndex(['receiver_id'], [
'name' => 'receiver_id',
'unique' => false,
])
->addIndex(['sender_id'], [
'name' => 'sender_id',
'unique' => false,
])
->create();
$this->table('kg_im_user', [
'id' => false,
'primary_key' => ['id'],
'engine' => 'InnoDB',
'encoding' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'comment' => '',
'row_format' => 'DYNAMIC',
])
->addColumn('id', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '主键编号',
])
->addColumn('name', 'string', [
'null' => false,
'default' => '',
'limit' => 30,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '名称',
'after' => 'id',
])
->addColumn('avatar', 'string', [
'null' => false,
'default' => '',
'limit' => 100,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '头像',
'after' => 'name',
])
->addColumn('sign', 'string', [
'null' => false,
'default' => '',
'limit' => 30,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '签名',
'after' => 'avatar',
])
->addColumn('skin', 'string', [
'null' => false,
'default' => '',
'limit' => 100,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '皮肤',
'after' => 'sign',
])
->addColumn('status', 'string', [
'null' => false,
'default' => 'hide',
'limit' => 15,
'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4',
'comment' => '在线状态',
'after' => 'skin',
])
->addColumn('deleted', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '删除标识',
'after' => 'status',
])
->addColumn('friend_count', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '好友数',
'after' => 'deleted',
])
->addColumn('group_count', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '群组数',
'after' => 'friend_count',
])
->addColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'group_count',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->create();
$this->table('kg_learning', [ $this->table('kg_learning', [
'id' => false, 'id' => false,
'primary_key' => ['id'], 'primary_key' => ['id'],

View File

@ -46,15 +46,6 @@ final class V20210403184518 extends AbstractMigration
]; ];
$this->table('kg_user')->insert($user)->saveData(); $this->table('kg_user')->insert($user)->saveData();
$imUser = [
'id' => $user['id'],
'name' => $user['name'],
'avatar' => $user['avatar'],
'create_time' => $now,
];
$this->table('kg_im_user')->insert($imUser)->saveData();
} }
protected function initRoleData() protected function initRoleData()
@ -949,7 +940,6 @@ final class V20210403184518 extends AbstractMigration
'course_review' => ['enabled' => 1, 'point' => 50], 'course_review' => ['enabled' => 1, 'point' => 50],
'chapter_study' => ['enabled' => 1, 'point' => 10], 'chapter_study' => ['enabled' => 1, 'point' => 10],
'site_visit' => ['enabled' => 1, 'point' => 10], 'site_visit' => ['enabled' => 1, 'point' => 10],
'im_discuss' => ['enabled' => 1, 'point' => 10],
'article_post' => ['enabled' => 1, 'point' => 20, 'limit' => 50], 'article_post' => ['enabled' => 1, 'point' => 20, 'limit' => 50],
'question_post' => ['enabled' => 1, 'point' => 5, 'limit' => 50], 'question_post' => ['enabled' => 1, 'point' => 5, 'limit' => 50],
'answer_post' => ['enabled' => 1, 'point' => 5, 'limit' => 50], 'answer_post' => ['enabled' => 1, 'point' => 5, 'limit' => 50],

View File

@ -27,7 +27,13 @@ final class V20210720153027 extends AbstractMigration
protected function createCourseTagTable() protected function createCourseTagTable()
{ {
$this->table('kg_course_tag', [ $tableName = 'kg_course_tag';
if ($this->table($tableName)->exists()) {
return;
}
$this->table($tableName, [
'id' => false, 'id' => false,
'primary_key' => ['id'], 'primary_key' => ['id'],
'engine' => 'InnoDB', 'engine' => 'InnoDB',
@ -80,8 +86,10 @@ final class V20210720153027 extends AbstractMigration
protected function alterCourseTable() protected function alterCourseTable()
{ {
$this->table('kg_course') $table = $this->table('kg_course');
->addColumn('tags', 'string', [
if ($table->hasColumn('tags') == false) {
$table->addColumn('tags', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
'limit' => 255, 'limit' => 255,
@ -89,13 +97,18 @@ final class V20210720153027 extends AbstractMigration
'encoding' => 'utf8mb4', 'encoding' => 'utf8mb4',
'comment' => '标签', 'comment' => '标签',
'after' => 'summary', 'after' => 'summary',
])->save(); ]);
}
$table->save();
} }
protected function alterCategoryTable() protected function alterCategoryTable()
{ {
$this->table('kg_category') $table = $this->table('kg_category');
->addColumn('alias', 'string', [
if ($table->hasColumn('alias') == false) {
$table->addColumn('alias', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
'limit' => 30, 'limit' => 30,
@ -103,7 +116,11 @@ final class V20210720153027 extends AbstractMigration
'encoding' => 'utf8mb4', 'encoding' => 'utf8mb4',
'comment' => '别名', 'comment' => '别名',
'after' => 'name', 'after' => 'name',
])->addColumn('icon', 'string', [ ]);
}
if ($table->hasColumn('icon') == false) {
$table->addColumn('icon', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
'limit' => 100, 'limit' => 100,
@ -111,13 +128,19 @@ final class V20210720153027 extends AbstractMigration
'encoding' => 'utf8mb4', 'encoding' => 'utf8mb4',
'comment' => '图标', 'comment' => '图标',
'after' => 'name', 'after' => 'name',
])->save(); ]);
}
$table->save();
} }
protected function alterTagTable() protected function alterTagTable()
{ {
$this->table('kg_tag') $table = $this->table('kg_tag');
->addColumn('scopes', 'string', [
if ($table->hasColumn('scopes') == false) {
$table->addColumn('scopes', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
'limit' => 100, 'limit' => 100,
@ -125,32 +148,43 @@ final class V20210720153027 extends AbstractMigration
'encoding' => 'utf8mb4', 'encoding' => 'utf8mb4',
'comment' => '范围', 'comment' => '范围',
'after' => 'icon', 'after' => 'icon',
]) ]);
->addColumn('course_count', 'integer', [ }
if ($table->hasColumn('course_count') == false) {
$table->addColumn('course_count', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR, 'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false, 'signed' => false,
'comment' => '课程数', 'comment' => '课程数',
'after' => 'follow_count', 'after' => 'follow_count',
]) ]);
->addColumn('article_count', 'integer', [ }
if ($table->hasColumn('article_count') == false) {
$table->addColumn('article_count', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR, 'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false, 'signed' => false,
'comment' => '文章数', 'comment' => '文章数',
'after' => 'course_count', 'after' => 'course_count',
]) ]);
->addColumn('question_count', 'integer', [ }
if ($table->hasColumn('question_count') == false) {
$table->addColumn('question_count', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR, 'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false, 'signed' => false,
'comment' => '问题数', 'comment' => '问题数',
'after' => 'article_count', 'after' => 'article_count',
]) ]);
->save(); }
$table->save();
} }
protected function handleCourseTags() protected function handleCourseTags()

View File

@ -17,8 +17,10 @@ final class V20210802021814 extends AbstractMigration
protected function alterPageTable() protected function alterPageTable()
{ {
$this->table('kg_page') $table = $this->table('kg_page');
->addColumn('alias', 'string', [
if ($table->hasColumn('alias') == false) {
$table->addColumn('alias', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
'limit' => 50, 'limit' => 50,
@ -26,7 +28,10 @@ final class V20210802021814 extends AbstractMigration
'encoding' => 'utf8mb4', 'encoding' => 'utf8mb4',
'comment' => '别名', 'comment' => '别名',
'after' => 'title', 'after' => 'title',
])->save(); ]);
}
$table->save();
} }
} }

View File

@ -5,19 +5,22 @@
* @link https://www.koogua.com * @link https://www.koogua.com
*/ */
require_once 'SettingTrait.php';
use Phinx\Migration\AbstractMigration; use Phinx\Migration\AbstractMigration;
final class V20210809153030 extends AbstractMigration final class V20210809153030 extends AbstractMigration
{ {
use SettingTrait;
public function up() public function up()
{ {
$this->handleVodSetting(); $this->handleVodSettings();
$this->handleImSetting();
$this->handleRemotePlayUrl(); $this->handleRemotePlayUrl();
} }
protected function handleVodSetting() protected function handleVodSettings()
{ {
$rows = [ $rows = [
[ [
@ -32,18 +35,7 @@ final class V20210809153030 extends AbstractMigration
], ],
]; ];
$this->table('kg_setting')->insert($rows)->save(); $this->insertSettings($rows);
}
protected function handleImSetting()
{
$row = [
'section' => 'im.main',
'item_key' => 'enabled',
'item_value' => '1',
];
$this->table('kg_setting')->insert($row)->saveData();
} }
protected function handleRemotePlayUrl() protected function handleRemotePlayUrl()

View File

@ -5,17 +5,21 @@
* @link https://www.koogua.com * @link https://www.koogua.com
*/ */
require_once 'SettingTrait.php';
use Phinx\Migration\AbstractMigration; use Phinx\Migration\AbstractMigration;
final class V20210820064755 extends AbstractMigration final class V20210820064755 extends AbstractMigration
{ {
use SettingTrait;
public function up() public function up()
{ {
$this->handleContactSetting(); $this->handleContactSettings();
} }
protected function handleContactSetting() protected function handleContactSettings()
{ {
$rows = [ $rows = [
[ [
@ -65,7 +69,7 @@ final class V20210820064755 extends AbstractMigration
], ],
]; ];
$this->table('kg_setting')->insert($rows)->save(); $this->insertSettings($rows);
} }
} }

View File

@ -19,9 +19,11 @@ final class V20210825111618 extends AbstractMigration
{ {
$table = $this->table('kg_upload'); $table = $this->table('kg_upload');
$table->removeIndexByName('md5')->save(); if ($table->hasIndexByName('md5')) {
$table->removeIndexByName('md5')->save();
$table->addIndex('md5')->save();
}
$table->addIndex('md5')->save();
} }
} }

View File

@ -5,17 +5,21 @@
* @link https://www.koogua.com * @link https://www.koogua.com
*/ */
require_once 'SettingTrait.php';
use Phinx\Migration\AbstractMigration; use Phinx\Migration\AbstractMigration;
final class V20210903040558 extends AbstractMigration final class V20210903040558 extends AbstractMigration
{ {
use SettingTrait;
public function up() public function up()
{ {
$this->handleVodSetting(); $this->handleVodSettings();
} }
protected function handleVodSetting() protected function handleVodSettings()
{ {
$row = $this->getQueryBuilder() $row = $this->getQueryBuilder()
->select('*') ->select('*')

View File

@ -7,15 +7,19 @@
use Phinx\Migration\AbstractMigration; use Phinx\Migration\AbstractMigration;
require_once 'SettingTrait.php';
final class V20210916072842 extends AbstractMigration final class V20210916072842 extends AbstractMigration
{ {
use SettingTrait;
public function up() public function up()
{ {
$this->handleLocalAuthSetting(); $this->handleLocalAuthSettings();
} }
protected function handleLocalAuthSetting() protected function handleLocalAuthSettings()
{ {
$rows = [ $rows = [
[ [
@ -30,7 +34,7 @@ final class V20210916072842 extends AbstractMigration
] ]
]; ];
$this->table('kg_setting')->insert($rows)->save(); $this->insertSettings($rows);
} }
} }

View File

@ -5,16 +5,20 @@
* @link https://www.koogua.com * @link https://www.koogua.com
*/ */
require_once 'SettingTrait.php';
use Phinx\Db\Adapter\MysqlAdapter; use Phinx\Db\Adapter\MysqlAdapter;
class V20210917093354 extends Phinx\Migration\AbstractMigration class V20210917093354 extends Phinx\Migration\AbstractMigration
{ {
use SettingTrait;
public function up() public function up()
{ {
$this->alterConnectTable(); $this->alterConnectTable();
$this->alterWechatSubscribeTable(); $this->alterWechatSubscribeTable();
$this->handleLocalAuthSetting(); $this->handleLocalAuthSettings();
} }
protected function alterConnectTable() protected function alterConnectTable()
@ -92,7 +96,7 @@ class V20210917093354 extends Phinx\Migration\AbstractMigration
$table->save(); $table->save();
} }
protected function handleLocalAuthSetting() protected function handleLocalAuthSettings()
{ {
$rows = [ $rows = [
[ [
@ -107,7 +111,7 @@ class V20210917093354 extends Phinx\Migration\AbstractMigration
] ]
]; ];
$this->table('kg_setting')->insert($rows)->save(); $this->insertSettings($rows);
} }
} }

View File

@ -18,15 +18,20 @@ final class V20211017085325 extends AbstractMigration
protected function alterCourseTable() protected function alterCourseTable()
{ {
$this->table('kg_course') $table = $this->table('kg_course');
->addColumn('fake_user_count', 'integer', [
if ($table->hasColumn('fake_user_count') == false) {
$table->addColumn('fake_user_count', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR, 'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false, 'signed' => false,
'comment' => '伪造用户数', 'comment' => '伪造用户数',
'after' => 'user_count', 'after' => 'user_count',
])->save(); ]);
}
$table->save();
} }
} }

View File

@ -19,28 +19,38 @@ final class V20211019093522 extends AbstractMigration
protected function alterUserSessionTable() protected function alterUserSessionTable()
{ {
$this->table('kg_user_session') $table = $this->table('kg_user_session');
->addColumn('deleted', 'integer', [
if ($table->hasColumn('deleted') == false) {
$table->addColumn('deleted', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR, 'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false, 'signed' => false,
'comment' => '删除标识', 'comment' => '删除标识',
'after' => 'client_ip', 'after' => 'client_ip',
])->save(); ]);
}
$table->save();
} }
protected function alterUserTokenTable() protected function alterUserTokenTable()
{ {
$this->table('kg_user_token') $table = $this->table('kg_user_token');
->addColumn('deleted', 'integer', [
if ($table->hasColumn('deleted') == false) {
$table->addColumn('deleted', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR, 'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false, 'signed' => false,
'comment' => '删除标识', 'comment' => '删除标识',
'after' => 'client_ip', 'after' => 'client_ip',
])->save(); ]);
}
$table->save();
} }
} }

View File

@ -2,26 +2,29 @@
use Phinx\Migration\AbstractMigration; use Phinx\Migration\AbstractMigration;
require_once 'SettingTrait.php';
final class V20211231013226 extends AbstractMigration final class V20211231013226 extends AbstractMigration
{ {
use SettingTrait;
public function up() public function up()
{ {
$this->handleSmsSetting(); $this->handleSmsSettings();
} }
protected function handleSmsSetting() protected function handleSmsSettings()
{ {
$row = $rows = [
[ [
[ 'section' => 'sms',
'section' => 'sms', 'item_key' => 'region',
'item_key' => 'region', 'item_value' => 'ap-guangzhou',
'item_value' => 'ap-guangzhou', ]
] ];
];
$this->table('kg_setting')->insert($row)->save(); $this->insertSettings($rows);
} }
} }

View File

@ -21,29 +21,28 @@ final class V20220607014823 extends AbstractMigration
protected function handleSiteSettings() protected function handleSiteSettings()
{ {
$rows = $rows = [
[ [
[ 'section' => 'site',
'section' => 'site', 'item_key' => 'isp_sn',
'item_key' => 'isp_sn', 'item_value' => '',
'item_value' => '', ],
], [
[ 'section' => 'site',
'section' => 'site', 'item_key' => 'isp_link',
'item_key' => 'isp_link', 'item_value' => 'https://dxzhgl.miit.gov.cn',
'item_value' => 'https://dxzhgl.miit.gov.cn', ],
], [
[ 'section' => 'site',
'section' => 'site', 'item_key' => 'company_sn',
'item_key' => 'company_sn', 'item_value' => '',
'item_value' => '', ],
], [
[ 'section' => 'site',
'section' => 'site', 'item_key' => 'company_sn_link',
'item_key' => 'company_sn_link', 'item_value' => '',
'item_value' => '', ],
], ];
];
$this->insertSettings($rows); $this->insertSettings($rows);
} }

View File

@ -20,7 +20,13 @@ class V20220801025747 extends Phinx\Migration\AbstractMigration
protected function createMigrationTaskTable() protected function createMigrationTaskTable()
{ {
$this->table('kg_migration_task', [ $tableName = 'kg_migration_task';
if ($this->table($tableName)->exists()) {
return;
}
$this->table($tableName, [
'id' => false, 'id' => false,
'primary_key' => ['id'], 'primary_key' => ['id'],
'engine' => 'InnoDB', 'engine' => 'InnoDB',
@ -70,13 +76,21 @@ class V20220801025747 extends Phinx\Migration\AbstractMigration
protected function dropImTables() protected function dropImTables()
{ {
$this->table('kg_im_friend_group')->drop()->save(); $tableNames = [
$this->table('kg_im_friend_user')->drop()->save(); 'kg_im_friend_group',
$this->table('kg_im_group')->drop()->save(); 'kg_im_friend_user',
$this->table('kg_im_group_user')->drop()->save(); 'kg_im_group',
$this->table('kg_im_message')->drop()->save(); 'kg_im_group_user',
$this->table('kg_im_notice')->drop()->save(); 'kg_im_message',
$this->table('kg_im_user')->drop()->save(); 'kg_im_notice',
'kg_im_user',
];
foreach ($tableNames as $tableName) {
if ($this->table($tableName)->exists()) {
$this->table($tableName)->drop()->save();
}
}
} }
protected function deleteImGroupNav() protected function deleteImGroupNav()

View File

@ -0,0 +1,80 @@
layui.use(['jquery', 'layer', 'util', 'helper'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var util = layui.util;
var helper = layui.helper;
var timeCounting = false;
var $account = $('#cv-email');
var $emit = $('#cv-email-emit-btn');
var $submit = $('#cv-email-submit-btn');
if ($('#cv-email-captcha-enabled').val() === '1') {
var captcha = new TencentCaptcha(
$emit[0],
$('#cv-email-captcha-appId').val(),
function (res) {
if (res.ret === 0) {
$('#cv-email-captcha-ticket').val(res.ticket);
$('#cv-email-captcha-rand').val(res.randstr);
sendVerifyCode();
}
}
);
} else {
$emit.on('click', function () {
sendVerifyCode();
});
}
$account.on('keyup', function () {
var account = $(this).val();
var accountOk = helper.isEmail(account);
if (accountOk && !timeCounting) {
$emit.removeClass('layui-btn-disabled').removeAttr('disabled');
} else {
$emit.addClass('layui-btn-disabled').attr('disabled', 'disabled');
}
});
function sendVerifyCode() {
if (helper.isEmail($account.val())) {
var postUrl = '/verify/mail/code';
var postData = {
email: $account.val(),
captcha: {
ticket: $('#cv-email-captcha-ticket').val(),
rand: $('#cv-email-captcha-rand').val(),
}
};
$.ajax({
type: 'POST',
url: postUrl,
data: postData,
success: function () {
layer.msg('发送验证码成功', {icon: 1});
}
});
$submit.removeClass('layui-btn-disabled').removeAttr('disabled');
$emit.addClass('layui-btn-disabled').attr('disabled', 'disabled');
showCountDown($emit);
}
}
function showCountDown() {
var serverTime = new Date().getTime();
var endTime = serverTime + 60 * 1000;
util.countdown(endTime, serverTime, function (date, serverTime, timer) {
var left = date[0] * 86400 + date[1] * 3600 + date[2] * 60 + date[3];
$emit.text(left + '秒');
if (left === 0) {
$emit.removeClass('layui-btn-disabled').removeAttr('disabled').text('重新发送');
clearInterval(timer);
timeCounting = false;
}
});
timeCounting = true;
}
});

View File

@ -1,8 +1,9 @@
layui.use(['jquery', 'layer', 'util'], function () { layui.use(['jquery', 'layer', 'util', 'helper'], function () {
var $ = layui.jquery; var $ = layui.jquery;
var layer = layui.layer; var layer = layui.layer;
var util = layui.util; var util = layui.util;
var helper = layui.helper;
var timeCounting = false; var timeCounting = false;
var $account = $('#cv-account'); var $account = $('#cv-account');
@ -28,16 +29,8 @@ layui.use(['jquery', 'layer', 'util'], function () {
} }
$account.on('keyup', function () { $account.on('keyup', function () {
var accountOk;
var type = $(this).data('type');
var account = $(this).val(); var account = $(this).val();
if (type === 'phone') { var accountOk = helper.isPhone(account) || helper.isEmail(account);
accountOk = isPhone(account);
} else if (type === 'email') {
accountOk = isEmail(account);
} else {
accountOk = isPhone(account) || isEmail(account);
}
if (accountOk && !timeCounting) { if (accountOk && !timeCounting) {
$emit.removeClass('layui-btn-disabled').removeAttr('disabled'); $emit.removeClass('layui-btn-disabled').removeAttr('disabled');
} else { } else {
@ -46,7 +39,7 @@ layui.use(['jquery', 'layer', 'util'], function () {
}); });
function sendVerifyCode() { function sendVerifyCode() {
if (isEmail($account.val()) || isPhone($account.val())) { if (helper.isEmail($account.val()) || helper.isPhone($account.val())) {
var postUrl; var postUrl;
var postData = { var postData = {
captcha: { captcha: {
@ -54,10 +47,10 @@ layui.use(['jquery', 'layer', 'util'], function () {
rand: $('#cv-captcha-rand').val(), rand: $('#cv-captcha-rand').val(),
} }
}; };
if (isPhone($account.val())) { if (helper.isPhone($account.val())) {
postData.phone = $account.val(); postData.phone = $account.val();
postUrl = '/verify/sms/code'; postUrl = '/verify/sms/code';
} else if (isEmail($account.val())) { } else if (helper.isEmail($account.val())) {
postData.email = $account.val(); postData.email = $account.val();
postUrl = '/verify/mail/code'; postUrl = '/verify/mail/code';
} }
@ -90,12 +83,4 @@ layui.use(['jquery', 'layer', 'util'], function () {
timeCounting = true; timeCounting = true;
} }
function isEmail(email) {
return /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(email);
}
function isPhone(phone) {
return /^1(3|4|5|6|7|8|9)\d{9}$/.test(phone);
}
}); });

View File

@ -0,0 +1,80 @@
layui.use(['jquery', 'layer', 'util', 'helper'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var util = layui.util;
var helper = layui.helper;
var timeCounting = false;
var $account = $('#cv-phone');
var $emit = $('#cv-phone-emit-btn');
var $submit = $('#cv-phone-submit-btn');
if ($('#cv-phone-captcha-enabled').val() === '1') {
var captcha = new TencentCaptcha(
$emit[0],
$('#cv-phone-captcha-appId').val(),
function (res) {
if (res.ret === 0) {
$('#cv-phone-captcha-ticket').val(res.ticket);
$('#cv-phone-captcha-rand').val(res.randstr);
sendVerifyCode();
}
}
);
} else {
$emit.on('click', function () {
sendVerifyCode();
});
}
$account.on('keyup', function () {
var account = $(this).val();
var accountOk = helper.isPhone(account);
if (accountOk && !timeCounting) {
$emit.removeClass('layui-btn-disabled').removeAttr('disabled');
} else {
$emit.addClass('layui-btn-disabled').attr('disabled', 'disabled');
}
});
function sendVerifyCode() {
if (helper.isPhone($account.val())) {
var postUrl = '/verify/sms/code';
var postData = {
phone: $account.val(),
captcha: {
ticket: $('#cv-phone-captcha-ticket').val(),
rand: $('#cv-phone-captcha-rand').val(),
}
};
$.ajax({
type: 'POST',
url: postUrl,
data: postData,
success: function () {
layer.msg('发送验证码成功', {icon: 1});
}
});
$submit.removeClass('layui-btn-disabled').removeAttr('disabled');
$emit.addClass('layui-btn-disabled').attr('disabled', 'disabled');
showCountDown($emit);
}
}
function showCountDown() {
var serverTime = new Date().getTime();
var endTime = serverTime + 60 * 1000;
util.countdown(endTime, serverTime, function (date, serverTime, timer) {
var left = date[0] * 86400 + date[1] * 3600 + date[2] * 60 + date[3];
$emit.text(left + '秒');
if (left === 0) {
$emit.removeClass('layui-btn-disabled').removeAttr('disabled').text('重新发送');
clearInterval(timer);
timeCounting = false;
}
});
timeCounting = true;
}
});

View File

@ -6,6 +6,14 @@ layui.define(['jquery', 'layer'], function (exports) {
var helper = {}; var helper = {};
helper.isEmail = function (email) {
return /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(email);
};
helper.isPhone = function (phone) {
return /^1(3|4|5|6|7|8|9)\d{9}$/.test(phone);
};
helper.getRequestId = function () { helper.getRequestId = function () {
var id = Date.now().toString(36); var id = Date.now().toString(36);
id += Math.random().toString(36).substr(3); id += Math.random().toString(36).substr(3);