mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-28 21:31:37 +08:00
Merge branch 'koogua/v1.6.5' into demo
# Conflicts: # app/Library/AppInfo.php
This commit is contained in:
commit
cd05619876
@ -1,4 +1,10 @@
|
|||||||
### [v1.6.4](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.3)(2023-06-15)
|
### [v1.6.5](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.5)(2023-07-15)
|
||||||
|
|
||||||
|
- 升级layui-v2.8.8
|
||||||
|
- 使用本地图像验证码
|
||||||
|
- 清理无用的计划任务
|
||||||
|
|
||||||
|
### [v1.6.4](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.4)(2023-06-15)
|
||||||
|
|
||||||
- 增加推荐课程等Widget
|
- 增加推荐课程等Widget
|
||||||
- 更新Composer包
|
- 更新Composer包
|
||||||
|
@ -55,7 +55,7 @@ Tips: 请用手机注册一个新账号,用户中心 -> 关注订阅,扫码
|
|||||||
### 项目组件
|
### 项目组件
|
||||||
|
|
||||||
- 后台框架:[phalcon 3.4.5](https://phalcon.io)
|
- 后台框架:[phalcon 3.4.5](https://phalcon.io)
|
||||||
- 前端框架:[layui 2.8.2](https://layui.com)
|
- 前端框架:[layui 2.8.8](https://layui.com)
|
||||||
- 全文检索:[xunsearch 1.4.9](http://www.xunsearch.com)
|
- 全文检索:[xunsearch 1.4.9](http://www.xunsearch.com)
|
||||||
- 即时通讯:[workerman 3.5.22](https://workerman.net)
|
- 即时通讯:[workerman 3.5.22](https://workerman.net)
|
||||||
- 基础依赖:[php7.3](https://php.net), [mysql5.7](https://mysql.com), [redis5.0](https://redis.io)
|
- 基础依赖:[php7.3](https://php.net), [mysql5.7](https://mysql.com), [redis5.0](https://redis.io)
|
||||||
|
@ -223,36 +223,6 @@ class SettingController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/captcha", name="admin.setting.captcha")
|
|
||||||
*/
|
|
||||||
public function captchaAction()
|
|
||||||
{
|
|
||||||
$section = 'captcha';
|
|
||||||
|
|
||||||
$settingService = new SettingService();
|
|
||||||
|
|
||||||
if ($this->request->isPost()) {
|
|
||||||
|
|
||||||
$data = $this->request->getPost();
|
|
||||||
|
|
||||||
$settingService->updateSettings($section, $data);
|
|
||||||
|
|
||||||
$content = [
|
|
||||||
'location' => $this->request->getHTTPReferer(),
|
|
||||||
'msg' => '更新配置成功',
|
|
||||||
];
|
|
||||||
|
|
||||||
return $this->jsonSuccess($content);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
$captcha = $settingService->getSettings($section);
|
|
||||||
|
|
||||||
$this->view->setVar('captcha', $captcha);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/point", name="admin.setting.point")
|
* @Route("/point", name="admin.setting.point")
|
||||||
*/
|
*/
|
||||||
|
@ -1200,12 +1200,6 @@ class AuthNode extends Service
|
|||||||
'type' => 'menu',
|
'type' => 'menu',
|
||||||
'route' => 'admin.setting.sms',
|
'route' => 'admin.setting.sms',
|
||||||
],
|
],
|
||||||
[
|
|
||||||
'id' => '5-2-3',
|
|
||||||
'title' => '验证码设置',
|
|
||||||
'type' => 'menu',
|
|
||||||
'route' => 'admin.setting.captcha',
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
'id' => '5-2-4',
|
'id' => '5-2-4',
|
||||||
'title' => '存储设置',
|
'title' => '存储设置',
|
||||||
|
@ -1,124 +0,0 @@
|
|||||||
{% extends 'templates/main.volt' %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
{% set captcha_display = captcha.enabled == 1 ? 'display:block' : 'display:none' %}
|
|
||||||
|
|
||||||
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.setting.captcha'}) }}">
|
|
||||||
<fieldset class="layui-elem-field layui-field-title">
|
|
||||||
<legend>验证码配置</legend>
|
|
||||||
</fieldset>
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label">开启服务</label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<input type="radio" name="enabled" value="1" title="是" lay-filter="captcha_enabled" {% if captcha.enabled == 1 %}checked="checked"{% endif %}>
|
|
||||||
<input type="radio" name="enabled" value="0" title="否" lay-filter="captcha_enabled" {% if captcha.enabled == 0 %}checked="checked"{% endif %}>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="captcha-block" style="{{ captcha_display }}">
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label">App Id</label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<input class="layui-input" type="text" name="app_id" value="{{ captcha.app_id }}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label">Secret Key</label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<input class="layui-input" type="text" name="secret_key" value="{{ captcha.secret_key }}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label"></label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
|
|
||||||
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.test.captcha'}) }}">
|
|
||||||
<fieldset class="layui-elem-field layui-field-title">
|
|
||||||
<legend>验证码测试</legend>
|
|
||||||
</fieldset>
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label"><i class="layui-icon layui-icon-vercode"></i></label>
|
|
||||||
<div class="layui-input-inline" style="width:200px;">
|
|
||||||
<button type="button" id="front-captcha-btn" class="layui-btn layui-btn-primary layui-btn-fluid" data-app-id="{{ captcha.app_id }}">前台验证</button>
|
|
||||||
<button type="button" id="front-verify-tips" class="kg-verify-btn layui-btn layui-btn-primary layui-btn-fluid layui-btn-disabled layui-hide"><i class="layui-icon layui-icon-ok"></i>前台验证成功</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label"><i class="layui-icon layui-icon-vercode"></i></label>
|
|
||||||
<div class="layui-input-inline" style="width:200px;">
|
|
||||||
<button type="button" id="back-verify-btn" class="layui-btn layui-btn-primary layui-btn-fluid" disabled="disabled" lay-submit="true" lay-filter="back_verify">后台验证</button>
|
|
||||||
<button type="button" id="back-verify-tips" class="kg-verify-btn layui-btn layui-btn-primary layui-btn-fluid layui-btn-disabled layui-hide"><i class="layui-icon layui-icon-ok"></i>后台验证成功</button>
|
|
||||||
<input type="hidden" name="ticket">
|
|
||||||
<input type="hidden" name="rand">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block inline_js %}
|
|
||||||
|
|
||||||
<script src="https://ssl.captcha.qq.com/TCaptcha.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
layui.use(['jquery', 'form', 'layer'], function () {
|
|
||||||
|
|
||||||
var $ = layui.jquery;
|
|
||||||
var form = layui.form;
|
|
||||||
var layer = layui.layer;
|
|
||||||
|
|
||||||
var captcha = new TencentCaptcha(
|
|
||||||
$('#front-captcha-btn')[0],
|
|
||||||
$('#front-captcha-btn').data('app-id'),
|
|
||||||
function (res) {
|
|
||||||
if (res.ret === 0) {
|
|
||||||
$('input[name=ticket]').val(res.ticket);
|
|
||||||
$('input[name=rand]').val(res.randstr);
|
|
||||||
$('#front-captcha-btn').remove();
|
|
||||||
$('#back-verify-btn').removeAttr('disabled');
|
|
||||||
$('#front-verify-tips').removeClass('layui-hide');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
form.on('radio(captcha_enabled)', function (data) {
|
|
||||||
var block = $('#captcha-block');
|
|
||||||
if (data.value === '1') {
|
|
||||||
block.show();
|
|
||||||
} else {
|
|
||||||
block.hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
form.on('submit(back_verify)', function (data) {
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: data.form.action,
|
|
||||||
data: data.field,
|
|
||||||
success: function (res) {
|
|
||||||
if (res.code === 0) {
|
|
||||||
$('#back-verify-btn').remove();
|
|
||||||
$('#back-verify-tips').removeClass('layui-hide');
|
|
||||||
}
|
|
||||||
layer.msg(res.msg, {icon: 1});
|
|
||||||
},
|
|
||||||
error: function (xhr) {
|
|
||||||
var json = JSON.parse(xhr.responseText);
|
|
||||||
layer.msg(json.msg, {icon: 2});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
@ -16,7 +16,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">Webhook</label>
|
<label class="layui-form-label">Webhook</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input class="layui-input" type="text" name="app_token" value="{{ robot.webhook_url }}" lay-verify="required">
|
<input class="layui-input" type="text" name="webhook_url" value="{{ robot.webhook_url }}" lay-verify="required">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
|
@ -7,9 +7,10 @@
|
|||||||
|
|
||||||
namespace App\Http\Api\Controllers;
|
namespace App\Http\Api\Controllers;
|
||||||
|
|
||||||
use App\Services\Logic\Verify\MailCode as MailCodeService;
|
use App\Services\Logic\Verify\Captcha as VerifyCaptchaService;
|
||||||
use App\Services\Logic\Verify\SmsCode as SmsCodeService;
|
use App\Services\Logic\Verify\Code as VerifyCodeService;
|
||||||
use App\Services\Logic\Verify\Ticket as TicketService;
|
use App\Services\Logic\Verify\MailCode as VerifyMailCodeService;
|
||||||
|
use App\Services\Logic\Verify\SmsCode as VerifySmsCodeService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @RoutePrefix("/api/verify")
|
* @RoutePrefix("/api/verify")
|
||||||
@ -18,15 +19,27 @@ class VerifyController extends Controller
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Post("/ticket", name="api.verify.ticket")
|
* @Get("/captcha", name="api.verify.captcha")
|
||||||
*/
|
*/
|
||||||
public function ticketAction()
|
public function captchaAction()
|
||||||
{
|
{
|
||||||
$service = new TicketService();
|
$service = new VerifyCaptchaService();
|
||||||
|
|
||||||
$ticket = $service->handle();
|
$captcha = $service->handle();
|
||||||
|
|
||||||
return $this->jsonSuccess(['ticket' => $ticket]);
|
return $this->jsonSuccess(['captcha' => $captcha]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Post("/code", name="api.verify.code")
|
||||||
|
*/
|
||||||
|
public function codeAction()
|
||||||
|
{
|
||||||
|
$service = new VerifyCodeService();
|
||||||
|
|
||||||
|
$service->handle();
|
||||||
|
|
||||||
|
return $this->jsonSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,7 +47,7 @@ class VerifyController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function smsCodeAction()
|
public function smsCodeAction()
|
||||||
{
|
{
|
||||||
$service = new SmsCodeService();
|
$service = new VerifySmsCodeService();
|
||||||
|
|
||||||
$service->handle();
|
$service->handle();
|
||||||
|
|
||||||
@ -46,7 +59,7 @@ class VerifyController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function mailCodeAction()
|
public function mailCodeAction()
|
||||||
{
|
{
|
||||||
$service = new MailCodeService();
|
$service = new VerifyMailCodeService();
|
||||||
|
|
||||||
$service->handle();
|
$service->handle();
|
||||||
|
|
||||||
|
@ -15,6 +15,9 @@ use App\Services\Logic\Account\PasswordReset as PasswordResetService;
|
|||||||
use App\Services\Logic\Account\PasswordUpdate as PasswordUpdateService;
|
use App\Services\Logic\Account\PasswordUpdate as PasswordUpdateService;
|
||||||
use App\Services\Logic\Account\PhoneUpdate as PhoneUpdateService;
|
use App\Services\Logic\Account\PhoneUpdate as PhoneUpdateService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @RoutePrefix("/account")
|
||||||
|
*/
|
||||||
class AccountController extends Controller
|
class AccountController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -40,15 +43,10 @@ class AccountController extends Controller
|
|||||||
|
|
||||||
$oauthProvider = $service->handle();
|
$oauthProvider = $service->handle();
|
||||||
|
|
||||||
$service = new AccountService();
|
|
||||||
|
|
||||||
$captcha = $service->getSettings('captcha');
|
|
||||||
|
|
||||||
$this->seo->prependTitle('用户注册');
|
$this->seo->prependTitle('用户注册');
|
||||||
|
|
||||||
$this->view->setVar('return_url', $returnUrl);
|
$this->view->setVar('return_url', $returnUrl);
|
||||||
$this->view->setVar('local_oauth', $oauthProvider['local']);
|
$this->view->setVar('local_oauth', $oauthProvider['local']);
|
||||||
$this->view->setVar('captcha', $captcha);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,10 +65,6 @@ class AccountController extends Controller
|
|||||||
return $this->response->redirect('/');
|
return $this->response->redirect('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
$service = new AccountService();
|
|
||||||
|
|
||||||
$captcha = $service->getSettings('captcha');
|
|
||||||
|
|
||||||
$service = new OAuthProviderService();
|
$service = new OAuthProviderService();
|
||||||
|
|
||||||
$oauthProvider = $service->handle();
|
$oauthProvider = $service->handle();
|
||||||
@ -81,7 +75,6 @@ class AccountController extends Controller
|
|||||||
|
|
||||||
$this->view->setVar('oauth_provider', $oauthProvider);
|
$this->view->setVar('oauth_provider', $oauthProvider);
|
||||||
$this->view->setVar('return_url', $returnUrl);
|
$this->view->setVar('return_url', $returnUrl);
|
||||||
$this->view->setVar('captcha', $captcha);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,13 +105,7 @@ class AccountController extends Controller
|
|||||||
return $this->response->redirect(['for' => 'home.index']);
|
return $this->response->redirect(['for' => 'home.index']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$service = new AccountService();
|
|
||||||
|
|
||||||
$captcha = $service->getSettings('captcha');
|
|
||||||
|
|
||||||
$this->seo->prependTitle('重置密码');
|
$this->seo->prependTitle('重置密码');
|
||||||
|
|
||||||
$this->view->setVar('captcha', $captcha);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,40 +7,22 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Services\Logic\Verify\MailCode as MailCodeService;
|
|
||||||
use App\Services\Logic\Verify\SmsCode as SmsCodeService;
|
|
||||||
use App\Traits\Response as ResponseTrait;
|
use App\Traits\Response as ResponseTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @RoutePrefix("/verify")
|
* @RoutePrefix("/verify")
|
||||||
*/
|
*/
|
||||||
class VerifyController extends \Phalcon\Mvc\Controller
|
class VerifyController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
use ResponseTrait;
|
use ResponseTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Post("/sms/code", name="home.verify.sms_code")
|
* @Get("/captcha", name="home.verify.captcha")
|
||||||
*/
|
*/
|
||||||
public function smsCodeAction()
|
public function captchaAction()
|
||||||
{
|
{
|
||||||
$service = new SmsCodeService();
|
$this->view->pick('verify/captcha');
|
||||||
|
|
||||||
$service->handle();
|
|
||||||
|
|
||||||
return $this->jsonSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Post("/mail/code", name="home.verify.mail_code")
|
|
||||||
*/
|
|
||||||
public function mailCodeAction()
|
|
||||||
{
|
|
||||||
$service = new MailCodeService();
|
|
||||||
|
|
||||||
$service->handle();
|
|
||||||
|
|
||||||
return $this->jsonSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -62,18 +62,6 @@ class Account extends Service
|
|||||||
|
|
||||||
$validator->checkIfAllowLogin($user);
|
$validator->checkIfAllowLogin($user);
|
||||||
|
|
||||||
$captcha = $this->getSettings('captcha');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证码是一次性的,放到最后检查,减少第三方调用
|
|
||||||
*/
|
|
||||||
if ($captcha['enabled'] == 1) {
|
|
||||||
|
|
||||||
$validator = new CaptchaValidator();
|
|
||||||
|
|
||||||
$validator->checkCode($post['captcha']['ticket'], $post['captcha']['rand']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->auth->saveAuthInfo($user);
|
$this->auth->saveAuthInfo($user);
|
||||||
|
|
||||||
$this->eventsManager->fire('Account:afterLogin', $this, $user);
|
$this->eventsManager->fire('Account:afterLogin', $this, $user);
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
|
|
||||||
{% block include_js %}
|
{% 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.phone.js') }}
|
||||||
{{ js_include('home/js/captcha.verify.email.js') }}
|
{{ js_include('home/js/captcha.verify.email.js') }}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-icon layui-icon-password"></label>
|
<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">
|
<input class="layui-input" type="password" name="new_password" autocomplete="off" placeholder="新密码" lay-verify="required">
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-inline verify-input-inline">
|
<div class="layui-input-inline verify-input-inline">
|
||||||
@ -19,8 +19,6 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<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>
|
<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-ticket" type="hidden" name="captcha[ticket]">
|
||||||
<input id="cv-email-captcha-rand" type="hidden" name="captcha[rand]">
|
<input id="cv-email-captcha-rand" type="hidden" name="captcha[rand]">
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-icon layui-icon-password"></label>
|
<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">
|
<input class="layui-input" type="password" name="new_password" autocomplete="off" placeholder="新密码" lay-verify="required">
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-inline verify-input-inline">
|
<div class="layui-input-inline verify-input-inline">
|
||||||
@ -19,8 +19,6 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<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>
|
<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-ticket" type="hidden" name="captcha[ticket]">
|
||||||
<input id="cv-phone-captcha-rand" type="hidden" name="captcha[rand]">
|
<input id="cv-phone-captcha-rand" type="hidden" name="captcha[rand]">
|
||||||
</div>
|
</div>
|
||||||
|
@ -44,8 +44,6 @@
|
|||||||
|
|
||||||
{% block include_js %}
|
{% block include_js %}
|
||||||
|
|
||||||
{{ js_include('https://ssl.captcha.qq.com/TCaptcha.js',false) }}
|
|
||||||
{{ js_include('home/js/captcha.login.js') }}
|
|
||||||
{{ js_include('home/js/captcha.verify.js') }}
|
{{ js_include('home/js/captcha.verify.js') }}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
{% set disabled_submit = captcha.enabled == 1 ? 'disabled="disabled"' : '' %}
|
|
||||||
{% set disabled_class = captcha.enabled == 1 ? 'layui-btn-disabled' : '' %}
|
|
||||||
|
|
||||||
<form class="layui-form account-form" method="POST" action="{{ url({'for':'home.account.pwd_login'}) }}">
|
<form class="layui-form account-form" method="POST" action="{{ url({'for':'home.account.pwd_login'}) }}">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-icon layui-icon-username"></label>
|
<label class="layui-icon layui-icon-username"></label>
|
||||||
@ -10,21 +7,10 @@
|
|||||||
<label class="layui-icon layui-icon-password"></label>
|
<label class="layui-icon layui-icon-password"></label>
|
||||||
<input class="layui-input" type="password" name="password" value="123456" autocomplete="off" placeholder="密码" lay-verify="required">
|
<input class="layui-input" type="password" name="password" value="123456" autocomplete="off" placeholder="密码" lay-verify="required">
|
||||||
</div>
|
</div>
|
||||||
{% if captcha.enabled == 1 %}
|
|
||||||
<div id="captcha-block" class="layui-form-item">
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<button id="cl-emit-btn" class="layui-btn layui-btn-fluid" type="button">点击完成验证</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<button id="cl-submit-btn" class="layui-btn layui-btn-fluid {{ disabled_class }}" {{ disabled_submit }} lay-submit="true" lay-filter="go">立即登录</button>
|
<button id="cl-submit-btn" class="layui-btn layui-btn-fluid" lay-submit="true" lay-filter="go">立即登录</button>
|
||||||
<input type="hidden" name="return_url" value="{{ return_url }}">
|
<input type="hidden" name="return_url" value="{{ return_url }}">
|
||||||
<input id="cl-captcha-enabled" type="hidden" value="{{ captcha.enabled }}">
|
|
||||||
<input id="cl-captcha-appId" type="hidden" value="{{ captcha.app_id }}">
|
|
||||||
<input id="cl-captcha-ticket" type="hidden" name="captcha[ticket]">
|
|
||||||
<input id="cl-captcha-rand" type="hidden" name="captcha[rand]">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
@ -15,11 +15,9 @@
|
|||||||
<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-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-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-ticket" type="hidden" name="captcha[ticket]">
|
||||||
<input id="cv-captcha-rand" type="hidden" name="captcha[rand]">
|
<input id="cv-captcha-rand" type="hidden" name="captcha[rand]">
|
||||||
|
<input type="hidden" name="return_url" value="{{ return_url }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
@ -39,7 +39,6 @@
|
|||||||
|
|
||||||
{% block include_js %}
|
{% block include_js %}
|
||||||
|
|
||||||
{{ js_include('https://ssl.captcha.qq.com/TCaptcha.js',false) }}
|
|
||||||
{{ js_include('home/js/account.register.js') }}
|
{{ js_include('home/js/account.register.js') }}
|
||||||
{{ js_include('home/js/captcha.verify.phone.js') }}
|
{{ js_include('home/js/captcha.verify.phone.js') }}
|
||||||
{{ js_include('home/js/captcha.verify.email.js') }}
|
{{ js_include('home/js/captcha.verify.email.js') }}
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
<form class="layui-form account-form" method="POST" action="{{ action_url }}">
|
<form class="layui-form account-form" method="POST" action="{{ action_url }}">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-icon layui-icon-email"></label>
|
<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">
|
<input id="cv-email" class="layui-input" type="text" name="email" autocomplete="off" placeholder="邮箱" lay-verify="required|email">
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-icon layui-icon-password"></label>
|
<label class="layui-icon layui-icon-password"></label>
|
||||||
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码(字母数字特殊字符6-16位)" lay-verify="required">
|
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码" lay-verify="required">
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-inline verify-input-inline">
|
<div class="layui-input-inline verify-input-inline">
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<div class="agree">
|
<div class="agree">
|
||||||
<div class="left"><input id="cv-email-agree" type="checkbox" name="agree" lay-skin="primary"></div>
|
<div class="left"><input id="cv-email-agree" type="checkbox" name="agree" checked="checked" lay-skin="primary"></div>
|
||||||
<div class="right">我已阅读并同意<a href="{{ terms_url }}" target="_blank">《用户协议》</a>和<a href="{{ privacy_url }}" target="_blank">《隐私政策》</a></div>
|
<div class="right">我已阅读并同意<a href="{{ terms_url }}" target="_blank">《用户协议》</a>和<a href="{{ privacy_url }}" target="_blank">《隐私政策》</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -28,11 +28,9 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<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>
|
<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-ticket" type="hidden" name="captcha[ticket]">
|
||||||
<input id="cv-email-captcha-rand" type="hidden" name="captcha[rand]">
|
<input id="cv-email-captcha-rand" type="hidden" name="captcha[rand]">
|
||||||
|
<input type="hidden" name="return_url" value="{{ return_url }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
<form class="layui-form account-form" method="POST" action="{{ action_url }}">
|
<form class="layui-form account-form" method="POST" action="{{ action_url }}">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-icon layui-icon-cellphone"></label>
|
<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">
|
<input id="cv-phone" class="layui-input" type="text" name="phone" autocomplete="off" placeholder="手机" lay-verify="required|phone">
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-icon layui-icon-password"></label>
|
<label class="layui-icon layui-icon-password"></label>
|
||||||
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码(字母数字特殊字符6-16位)" lay-verify="required">
|
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码" lay-verify="required">
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-inline verify-input-inline">
|
<div class="layui-input-inline verify-input-inline">
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<div class="agree">
|
<div class="agree">
|
||||||
<div class="left"><input id="cv-phone-agree" type="checkbox" name="agree" lay-skin="primary"></div>
|
<div class="left"><input id="cv-phone-agree" type="checkbox" name="agree" checked="checked" lay-skin="primary"></div>
|
||||||
<div class="right">我已阅读并同意<a href="{{ terms_url }}" target="_blank">《用户协议》</a>和<a href="{{ privacy_url }}" target="_blank">《隐私政策》</a></div>
|
<div class="right">我已阅读并同意<a href="{{ terms_url }}" target="_blank">《用户协议》</a>和<a href="{{ privacy_url }}" target="_blank">《隐私政策》</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -28,11 +28,9 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<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>
|
<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-ticket" type="hidden" name="captcha[ticket]">
|
||||||
<input id="cv-phone-captcha-rand" type="hidden" name="captcha[rand]">
|
<input id="cv-phone-captcha-rand" type="hidden" name="captcha[rand]">
|
||||||
|
<input type="hidden" name="return_url" value="{{ return_url }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
{% set share_url = full_url('chapter',chapter.id,auth_user.id) %}
|
{% set share_url = share_url('chapter',chapter.id,auth_user.id) %}
|
||||||
{% set qrcode_url = url({'for':'home.qrcode'},{'text':share_url}) %}
|
{% set qrcode_url = url({'for':'home.qrcode'},{'text':share_url}) %}
|
||||||
{% set course_url = url({'for':'home.course.show','id':chapter.course.id}) %}
|
{% set course_url = url({'for':'home.course.show','id':chapter.course.id}) %}
|
||||||
{% set learning_url = url({'for':'home.chapter.learning','id':chapter.id}) %}
|
{% set learning_url = url({'for':'home.chapter.learning','id':chapter.id}) %}
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
{% block include_js %}
|
{% block include_js %}
|
||||||
|
|
||||||
{{ js_include('https://ssl.captcha.qq.com/TCaptcha.js',false) }}
|
|
||||||
{{ js_include('home/js/connect.bind.js') }}
|
{{ js_include('home/js/connect.bind.js') }}
|
||||||
{{ js_include('home/js/captcha.verify.js') }}
|
{{ js_include('home/js/captcha.verify.js') }}
|
||||||
|
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
<form class="layui-form account-form" method="POST" action="{{ url({'for':'home.oauth.bind_login'}) }}">
|
<form class="layui-form account-form" method="POST" action="{{ url({'for':'home.oauth.bind_login'}) }}">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<label class="layui-icon layui-icon-username"></label>
|
||||||
<input class="layui-input" type="text" name="account" autocomplete="off" placeholder="手机 / 邮箱" lay-verify="required">
|
<input class="layui-input" type="text" name="account" autocomplete="off" placeholder="手机 / 邮箱" lay-verify="required">
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<label class="layui-icon layui-icon-password"></label>
|
||||||
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码" lay-verify="required">
|
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码" lay-verify="required">
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<div class="agree">
|
<div class="agree">
|
||||||
<div class="left"><input id="login-agree" type="checkbox" name="agree" lay-skin="primary"></div>
|
<div class="left"><input id="login-agree" type="checkbox" name="agree" checked="checked" lay-skin="primary"></div>
|
||||||
<div class="right">我已阅读并同意<a href="{{ terms_url }}" target="_blank">《用户协议》</a>和<a href="{{ privacy_url }}" target="_blank">《隐私政策》</a></div>
|
<div class="right">我已阅读并同意<a href="{{ terms_url }}" target="_blank">《用户协议》</a>和<a href="{{ privacy_url }}" target="_blank">《隐私政策》</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
<form class="layui-form account-form" method="POST" action="{{ url({'for':'home.oauth.bind_register'}) }}">
|
<form class="layui-form account-form" method="POST" action="{{ url({'for':'home.oauth.bind_register'}) }}">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<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">
|
<input id="cv-account" class="layui-input" type="text" name="account" autocomplete="off" placeholder="手机 / 邮箱" lay-verify="required">
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<label class="layui-icon layui-icon-password"></label>
|
||||||
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码(字母数字特殊字符6-16位)" lay-verify="required">
|
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码" lay-verify="required">
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-inline verify-input-inline">
|
<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">
|
<input class="layui-input" type="text" name="verify_code" placeholder="验证码" lay-verify="required">
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-input-inline verify-btn-inline">
|
<div class="layui-input-inline verify-btn-inline">
|
||||||
@ -20,7 +19,7 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<div class="agree">
|
<div class="agree">
|
||||||
<div class="left"><input id="register-agree" type="checkbox" name="agree" lay-skin="primary"></div>
|
<div class="left"><input id="register-agree" type="checkbox" name="agree" checked="checked" lay-skin="primary"></div>
|
||||||
<div class="right">我已阅读并同意<a href="{{ terms_url }}" target="_blank">《用户协议》</a>和<a href="{{ privacy_url }}" target="_blank">《隐私政策》</a></div>
|
<div class="right">我已阅读并同意<a href="{{ terms_url }}" target="_blank">《用户协议》</a>和<a href="{{ privacy_url }}" target="_blank">《隐私政策》</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -28,14 +27,12 @@
|
|||||||
<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-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">注册并绑定帐号</button>
|
||||||
|
<input id="cv-captcha-ticket" type="hidden" name="ticket">
|
||||||
|
<input id="cv-captcha-rand" type="hidden" name="rand">
|
||||||
<input type="hidden" name="provider" value="{{ provider }}">
|
<input type="hidden" name="provider" value="{{ provider }}">
|
||||||
<input type="hidden" name="code" value="{{ request.get('code') }}">
|
<input type="hidden" name="code" value="{{ request.get('code') }}">
|
||||||
<input type="hidden" name="state" value="{{ request.get('state') }}">
|
<input type="hidden" name="state" value="{{ request.get('state') }}">
|
||||||
<input type="hidden" name="open_user" value='{{ open_user|json_encode }}'>
|
<input type="hidden" name="open_user" value='{{ open_user|json_encode }}'>
|
||||||
<input id="cv-enabled" type="hidden" value="{{ captcha.enabled }}">
|
|
||||||
<input id="cv-app-id" type="hidden" value="{{ captcha.app_id }}">
|
|
||||||
<input id="cv-ticket" type="hidden" name="ticket">
|
|
||||||
<input id="cv-rand" type="hidden" name="rand">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
@ -10,16 +10,18 @@
|
|||||||
<span class="title">账号安全 - 修改邮箱</span>
|
<span class="title">账号安全 - 修改邮箱</span>
|
||||||
</div>
|
</div>
|
||||||
<form class="layui-form security-form" method="POST" action="{{ url({'for':'home.account.update_email'}) }}">
|
<form class="layui-form security-form" method="POST" action="{{ url({'for':'home.account.update_email'}) }}">
|
||||||
<div class="layui-form-item">
|
{% if account.password|length > 0 %}
|
||||||
<label class="layui-form-label">登录密码</label>
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<label class="layui-form-label">登录密码</label>
|
||||||
<input class="layui-input" type="password" name="login_password" autocomplete="off" lay-verify="required">
|
<div class="layui-input-block">
|
||||||
|
<input class="layui-input" type="password" name="login_password" autocomplete="off" placeholder="请输入当前登录密码" lay-verify="required">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
<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-email" class="layui-input" type="text" name="email" lay-verify="required">
|
<input id="cv-email" class="layui-input" type="text" name="email" placeholder="请输入新设邮箱地址" lay-verify="required|email">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
@ -34,8 +36,6 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<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>
|
<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-ticket" type="hidden" name="captcha[ticket]">
|
||||||
<input id="cv-email-captcha-rand" type="hidden" name="captcha[rand]">
|
<input id="cv-email-captcha-rand" type="hidden" name="captcha[rand]">
|
||||||
</div>
|
</div>
|
||||||
@ -49,7 +49,6 @@
|
|||||||
|
|
||||||
{% block include_js %}
|
{% block include_js %}
|
||||||
|
|
||||||
{{ js_include('https://ssl.captcha.qq.com/TCaptcha.js',false) }}
|
|
||||||
{{ js_include('home/js/captcha.verify.email.js') }}
|
{{ js_include('home/js/captcha.verify.email.js') }}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -10,16 +10,18 @@
|
|||||||
<span class="title">账号安全 - 修改手机</span>
|
<span class="title">账号安全 - 修改手机</span>
|
||||||
</div>
|
</div>
|
||||||
<form class="layui-form security-form" method="POST" action="{{ url({'for':'home.account.update_phone'}) }}">
|
<form class="layui-form security-form" method="POST" action="{{ url({'for':'home.account.update_phone'}) }}">
|
||||||
<div class="layui-form-item">
|
{% if account.password|length > 0 %}
|
||||||
<label class="layui-form-label">登录密码</label>
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<label class="layui-form-label">登录密码</label>
|
||||||
<input class="layui-input" type="password" name="login_password" autocomplete="off" lay-verify="required">
|
<div class="layui-input-block">
|
||||||
|
<input class="layui-input" type="password" name="login_password" autocomplete="off" placeholder="请输入当前登录密码" lay-verify="required">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
<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-phone" class="layui-input" type="text" name="phone" lay-verify="required">
|
<input id="cv-phone" class="layui-input" type="text" name="phone" placeholder="请输入新设手机号码" lay-verify="required|phone">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
@ -34,8 +36,6 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<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>
|
<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-ticket" type="hidden" name="captcha[ticket]">
|
||||||
<input id="cv-phone-captcha-rand" type="hidden" name="captcha[rand]">
|
<input id="cv-phone-captcha-rand" type="hidden" name="captcha[rand]">
|
||||||
</div>
|
</div>
|
||||||
@ -49,7 +49,6 @@
|
|||||||
|
|
||||||
{% block include_js %}
|
{% 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.phone.js') }}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
105
app/Http/Home/Views/verify/captcha.volt
Normal file
105
app/Http/Home/Views/verify/captcha.volt
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
{% extends 'templates/layer.volt' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<form class="layui-form">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">验证算式</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<img id="img-captcha" class="pointer" title="刷新表达式" alt="验证表达式" width="200" height="50">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">计算结果</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input class="layui-input" type="text" name="rand">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label"></label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<button class="layui-btn" lay-submit="true" lay-filter="captcha">提交</button>
|
||||||
|
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="layui-hide">
|
||||||
|
<input type="hidden" name="account" value="{{ request.get('account') }}">
|
||||||
|
<input type="hidden" name="type" value="{{ request.get('type') }}">
|
||||||
|
<input type="hidden" name="ticket">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block include_js %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
layui.use(['jquery', 'form', 'layer', 'helper'], function () {
|
||||||
|
|
||||||
|
var $ = layui.jquery;
|
||||||
|
var form = layui.form;
|
||||||
|
var layer = layui.layer;
|
||||||
|
var index = parent.layer.getFrameIndex(window.name);
|
||||||
|
|
||||||
|
var verify = {
|
||||||
|
account: $('input[name=account]').val(),
|
||||||
|
type: $('input[name=type]').val(),
|
||||||
|
}
|
||||||
|
|
||||||
|
var showCaptchaImage = function () {
|
||||||
|
$.get('/api/verify/captcha', function (res) {
|
||||||
|
$('#img-captcha').attr('src', res.captcha.content);
|
||||||
|
$('input[name=ticket]').val(res.captcha.ticket);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$('#img-captcha').on('click', function () {
|
||||||
|
showCaptchaImage();
|
||||||
|
});
|
||||||
|
|
||||||
|
form.on('submit(captcha)', function (data) {
|
||||||
|
var submit = $(this);
|
||||||
|
var account = $('input[name=account]').val();
|
||||||
|
var ticket = $('input[name=ticket]').val();
|
||||||
|
var rand = $('input[name=rand]').val();
|
||||||
|
submit.attr('disabled', 'disabled').addClass('layui-btn-disabled');
|
||||||
|
if (verify.type === 'phone') {
|
||||||
|
parent.layui.$('#cv-phone-submit-btn').removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||||
|
parent.layui.$('#cv-phone-captcha-ticket').val(ticket);
|
||||||
|
parent.layui.$('#cv-phone-captcha-rand').val(rand);
|
||||||
|
} else if (verify.type === 'mail') {
|
||||||
|
parent.layui.$('#cv-mail-submit-btn').removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||||
|
parent.layui.$('#cv-mail-captcha-ticket').val(ticket);
|
||||||
|
parent.layui.$('#cv-mail-captcha-rand').val(rand);
|
||||||
|
} else {
|
||||||
|
parent.layui.$('#cv-submit-btn').removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||||
|
parent.layui.$('#cv-captcha-ticket').val(ticket);
|
||||||
|
parent.layui.$('#cv-captcha-rand').val(rand);
|
||||||
|
}
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: '/api/verify/code',
|
||||||
|
data: {
|
||||||
|
account: account,
|
||||||
|
ticket: ticket,
|
||||||
|
rand: rand,
|
||||||
|
},
|
||||||
|
success: function () {
|
||||||
|
layer.msg('发送验证码成功', {icon: 1});
|
||||||
|
setTimeout(function () {
|
||||||
|
parent.layer.close(index);
|
||||||
|
}, 1500);
|
||||||
|
}, error: function () {
|
||||||
|
submit.removeAttr('disabled').removeClass('layui-btn-disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
showCaptchaImage();
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -16,7 +16,7 @@ class AppInfo
|
|||||||
|
|
||||||
protected $link = 'https://www.koogua.com';
|
protected $link = 'https://www.koogua.com';
|
||||||
|
|
||||||
protected $version = '1.6.4';
|
protected $version = '1.6.5';
|
||||||
|
|
||||||
public function __get($name)
|
public function __get($name)
|
||||||
{
|
{
|
||||||
|
139
app/Library/Captcha.php
Normal file
139
app/Library/Captcha.php
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||||
|
* @license https://opensource.org/licenses/GPL-2.0
|
||||||
|
* @link https://www.koogua.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Library;
|
||||||
|
|
||||||
|
use Phalcon\Di;
|
||||||
|
use Phalcon\Text;
|
||||||
|
|
||||||
|
class Captcha
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Cache\Backend\Redis
|
||||||
|
*/
|
||||||
|
protected $cache;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->cache = Di::getDefault()->get('cache');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generate()
|
||||||
|
{
|
||||||
|
$ticket = $this->getRandTicket();
|
||||||
|
|
||||||
|
$cacheKey = $this->getCacheKey($ticket);
|
||||||
|
|
||||||
|
$expression = $this->getExpression();
|
||||||
|
|
||||||
|
$this->cache->save($cacheKey, $expression['result'], 600);
|
||||||
|
|
||||||
|
$width = 100;
|
||||||
|
$height = 25;
|
||||||
|
|
||||||
|
$im = imagecreate($width, $height);
|
||||||
|
|
||||||
|
$white = imagecolorallocate($im, 255, 255, 255);
|
||||||
|
$gray = imagecolorallocate($im, 118, 151, 199);
|
||||||
|
$bgColor = imagecolorallocate($im, rand(0, 100), rand(0, 100), rand(0, 100));
|
||||||
|
|
||||||
|
imagefilledrectangle($im, 0, 0, $width, $height, $bgColor);
|
||||||
|
|
||||||
|
for ($i = 0; $i < 200; $i++) {
|
||||||
|
imagesetpixel($im, rand(0, $width), rand(0, $height), $gray);
|
||||||
|
}
|
||||||
|
|
||||||
|
imagestring($im, 5, 5, 4, $expression['num1'], $white);
|
||||||
|
imagestring($im, 5, 30, 3, $expression['operator'], $white);
|
||||||
|
imagestring($im, 5, 45, 4, $expression['num2'], $white);
|
||||||
|
imagestring($im, 5, 70, 3, '=', $white);
|
||||||
|
imagestring($im, 5, 85, 3, '?', $white);
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
imagepng($im);
|
||||||
|
|
||||||
|
$content = ob_get_clean();
|
||||||
|
|
||||||
|
imagedestroy($im);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'ticket' => $ticket,
|
||||||
|
'content' => $this->base64Encode($content),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function check($ticket, $rand)
|
||||||
|
{
|
||||||
|
if (!$ticket) return false;
|
||||||
|
|
||||||
|
if (!$rand) return false;
|
||||||
|
|
||||||
|
$key = $this->getCacheKey($ticket);
|
||||||
|
|
||||||
|
$content = $this->cache->get($key);
|
||||||
|
|
||||||
|
return $content == $rand;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getExpression()
|
||||||
|
{
|
||||||
|
$operators = ['+', '-', '*', '/'];
|
||||||
|
|
||||||
|
$index = array_rand($operators);
|
||||||
|
|
||||||
|
$operator = $operators[$index];
|
||||||
|
|
||||||
|
switch ($operator) {
|
||||||
|
case '+':
|
||||||
|
$num1 = rand(10, 50);
|
||||||
|
$num2 = rand(10, 50);
|
||||||
|
$result = $num1 + $num2;
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
$num1 = rand(50, 100);
|
||||||
|
$num2 = rand(10, 50);
|
||||||
|
$result = $num1 - $num2;
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
$num1 = rand(1, 10);
|
||||||
|
$num2 = rand(1, 10);
|
||||||
|
$result = $num1 * $num2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$multiple = rand(2, 10);
|
||||||
|
$num1 = $multiple * rand(1, 10);
|
||||||
|
$num2 = $multiple;
|
||||||
|
$result = $num1 / $num2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'num1' => $num1,
|
||||||
|
'num2' => $num2,
|
||||||
|
'operator' => $operator,
|
||||||
|
'result' => $result,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function base64Encode($content)
|
||||||
|
{
|
||||||
|
return sprintf('data:image/png;base64,%s', base64_encode($content));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getRandTicket()
|
||||||
|
{
|
||||||
|
return Text::random(Text::RANDOM_ALNUM, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCacheKey($key)
|
||||||
|
{
|
||||||
|
return "captcha:{$key}";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,131 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
|
||||||
* @license https://opensource.org/licenses/GPL-2.0
|
|
||||||
* @link https://www.koogua.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Services;
|
|
||||||
|
|
||||||
use Phalcon\Logger\Adapter\File as FileLogger;
|
|
||||||
use TencentCloud\Captcha\V20190722\CaptchaClient;
|
|
||||||
use TencentCloud\Captcha\V20190722\Models\DescribeCaptchaResultRequest;
|
|
||||||
use TencentCloud\Common\Credential;
|
|
||||||
use TencentCloud\Common\Exception\TencentCloudSDKException;
|
|
||||||
use TencentCloud\Common\Profile\ClientProfile;
|
|
||||||
use TencentCloud\Common\Profile\HttpProfile;
|
|
||||||
|
|
||||||
class Captcha extends Service
|
|
||||||
{
|
|
||||||
|
|
||||||
const END_POINT = 'captcha.tencentcloudapi.com';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var FileLogger
|
|
||||||
*/
|
|
||||||
protected $logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var CaptchaClient
|
|
||||||
*/
|
|
||||||
protected $client;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->settings = $this->getSettings('captcha');
|
|
||||||
|
|
||||||
$this->logger = $this->getLogger('captcha');
|
|
||||||
|
|
||||||
$this->client = $this->getCaptchaClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验验证码
|
|
||||||
*
|
|
||||||
* @param string $ticket
|
|
||||||
* @param string $rand
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
function verify($ticket, $rand)
|
|
||||||
{
|
|
||||||
$userIp = $this->request->getClientAddress();
|
|
||||||
|
|
||||||
$appId = $this->settings['app_id'];
|
|
||||||
$secretKey = $this->settings['secret_key'];
|
|
||||||
$captchaType = 9;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
$request = new DescribeCaptchaResultRequest();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 注意:CaptchaType和CaptchaAppId强类型要求
|
|
||||||
*/
|
|
||||||
$params = json_encode([
|
|
||||||
'Ticket' => $ticket,
|
|
||||||
'Randstr' => $rand,
|
|
||||||
'UserIp' => $userIp,
|
|
||||||
'CaptchaType' => (int)$captchaType,
|
|
||||||
'CaptchaAppId' => (int)$appId,
|
|
||||||
'AppSecretKey' => $secretKey,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$request->fromJsonString($params);
|
|
||||||
|
|
||||||
$this->logger->debug('Describe Captcha Result Request ' . $params);
|
|
||||||
|
|
||||||
$response = $this->client->DescribeCaptchaResult($request);
|
|
||||||
|
|
||||||
$this->logger->debug('Describe Captcha Result Response ' . $response->toJsonString());
|
|
||||||
|
|
||||||
$data = json_decode($response->toJsonString(), true);
|
|
||||||
|
|
||||||
$result = $data['CaptchaCode'] == 1;
|
|
||||||
|
|
||||||
} catch (TencentCloudSDKException $e) {
|
|
||||||
|
|
||||||
$this->logger->error('Describe Captcha Result Exception ' . kg_json_encode([
|
|
||||||
'code' => $e->getErrorCode(),
|
|
||||||
'message' => $e->getMessage(),
|
|
||||||
'requestId' => $e->getRequestId(),
|
|
||||||
]));
|
|
||||||
|
|
||||||
$result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取CaptchaClient
|
|
||||||
*
|
|
||||||
* @return CaptchaClient
|
|
||||||
*/
|
|
||||||
public function getCaptchaClient()
|
|
||||||
{
|
|
||||||
$secret = $this->getSettings('secret');
|
|
||||||
|
|
||||||
$secretId = $secret['secret_id'];
|
|
||||||
$secretKey = $secret['secret_key'];
|
|
||||||
|
|
||||||
$region = $this->settings['region'] ?? 'ap-guangzhou';
|
|
||||||
|
|
||||||
$credential = new Credential($secretId, $secretKey);
|
|
||||||
|
|
||||||
$httpProfile = new HttpProfile();
|
|
||||||
|
|
||||||
$httpProfile->setEndpoint(self::END_POINT);
|
|
||||||
|
|
||||||
$clientProfile = new ClientProfile();
|
|
||||||
|
|
||||||
$clientProfile->setHttpProfile($httpProfile);
|
|
||||||
|
|
||||||
return new CaptchaClient($credential, $region, $clientProfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -33,7 +33,12 @@ class EmailUpdate extends LogicService
|
|||||||
$accountValidator->checkIfEmailTaken($post['email']);
|
$accountValidator->checkIfEmailTaken($post['email']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$accountValidator->checkLoginPassword($account, $post['login_password']);
|
/**
|
||||||
|
* 未设置过密码不检查原密码
|
||||||
|
*/
|
||||||
|
if (!empty($account->password)) {
|
||||||
|
$accountValidator->checkLoginPassword($account, $post['login_password']);
|
||||||
|
}
|
||||||
|
|
||||||
$verifyValidator = new VerifyValidator();
|
$verifyValidator = new VerifyValidator();
|
||||||
|
|
||||||
|
@ -33,7 +33,12 @@ class PhoneUpdate extends LogicService
|
|||||||
$accountValidator->checkIfPhoneTaken($post['phone']);
|
$accountValidator->checkIfPhoneTaken($post['phone']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$accountValidator->checkLoginPassword($account, $post['login_password']);
|
/**
|
||||||
|
* 未设置过密码不检查原密码
|
||||||
|
*/
|
||||||
|
if (!empty($account->password)) {
|
||||||
|
$accountValidator->checkLoginPassword($account, $post['login_password']);
|
||||||
|
}
|
||||||
|
|
||||||
$verifyValidator = new VerifyValidator();
|
$verifyValidator = new VerifyValidator();
|
||||||
|
|
||||||
|
23
app/Services/Logic/Verify/Captcha.php
Normal file
23
app/Services/Logic/Verify/Captcha.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||||
|
* @license https://opensource.org/licenses/GPL-2.0
|
||||||
|
* @link https://www.koogua.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Services\Logic\Verify;
|
||||||
|
|
||||||
|
use App\Library\Captcha as AppCaptcha;
|
||||||
|
use App\Services\Logic\Service as LogicService;
|
||||||
|
|
||||||
|
class Captcha extends LogicService
|
||||||
|
{
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$captcha = new AppCaptcha();
|
||||||
|
|
||||||
|
return $captcha->generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
42
app/Services/Logic/Verify/Code.php
Normal file
42
app/Services/Logic/Verify/Code.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||||
|
* @license https://opensource.org/licenses/GPL-2.0
|
||||||
|
* @link https://www.koogua.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Services\Logic\Verify;
|
||||||
|
|
||||||
|
use App\Library\Validators\Common as CommonValidator;
|
||||||
|
use App\Services\Logic\Notice\External\Mail\Verify as MailVerifyService;
|
||||||
|
use App\Services\Logic\Notice\External\Sms\Verify as SmsVerifyService;
|
||||||
|
use App\Services\Logic\Service as LogicService;
|
||||||
|
use App\Validators\Captcha as CaptchaValidator;
|
||||||
|
use App\Validators\Verify as VerifyValidator;
|
||||||
|
|
||||||
|
class Code extends LogicService
|
||||||
|
{
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$post = $this->request->getPost();
|
||||||
|
|
||||||
|
$verifyValidator = new VerifyValidator();
|
||||||
|
$captchaValidator = new CaptchaValidator();
|
||||||
|
|
||||||
|
$captchaValidator->checkCode($post['ticket'], $post['rand']);
|
||||||
|
|
||||||
|
$isMail = CommonValidator::email($post['account']);
|
||||||
|
|
||||||
|
if ($isMail) {
|
||||||
|
$account = $verifyValidator->checkEmail($post['account']);
|
||||||
|
$service = new MailVerifyService();
|
||||||
|
} else {
|
||||||
|
$account = $verifyValidator->checkPhone($post['account']);
|
||||||
|
$service = new SmsVerifyService();
|
||||||
|
}
|
||||||
|
|
||||||
|
$service->handle($account);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -21,20 +21,15 @@ class MailCode extends LogicService
|
|||||||
|
|
||||||
$validator = new VerifyValidator();
|
$validator = new VerifyValidator();
|
||||||
|
|
||||||
$post['email'] = $validator->checkEmail($post['email']);
|
$email = $validator->checkEmail($post['email']);
|
||||||
|
|
||||||
$captcha = $this->getSettings('captcha');
|
$validator = new CaptchaValidator();
|
||||||
|
|
||||||
if ($captcha['enabled'] == 1) {
|
$validator->checkCode($post['ticket'], $post['rand']);
|
||||||
|
|
||||||
$validator = new CaptchaValidator();
|
|
||||||
|
|
||||||
$validator->checkCode($post['captcha']['ticket'], $post['captcha']['rand']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$service = new MailVerifyService();
|
$service = new MailVerifyService();
|
||||||
|
|
||||||
$service->handle($post['email']);
|
$service->handle($email);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,20 +21,15 @@ class SmsCode extends LogicService
|
|||||||
|
|
||||||
$validator = new VerifyValidator();
|
$validator = new VerifyValidator();
|
||||||
|
|
||||||
$post['phone'] = $validator->checkPhone($post['phone']);
|
$phone = $validator->checkPhone($post['phone']);
|
||||||
|
|
||||||
$captcha = $this->getSettings('captcha');
|
$validator = new CaptchaValidator();
|
||||||
|
|
||||||
if ($captcha['enabled'] == 1) {
|
$validator->checkCode($post['ticket'], $post['rand']);
|
||||||
|
|
||||||
$validator = new CaptchaValidator();
|
|
||||||
|
|
||||||
$validator->checkCode($post['captcha']['ticket'], $post['captcha']['rand']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$service = new SmsVerifyService();
|
$service = new SmsVerifyService();
|
||||||
|
|
||||||
$service->handle($post['phone']);
|
$service->handle($phone);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,16 +8,16 @@
|
|||||||
namespace App\Validators;
|
namespace App\Validators;
|
||||||
|
|
||||||
use App\Exceptions\BadRequest as BadRequestException;
|
use App\Exceptions\BadRequest as BadRequestException;
|
||||||
use App\Services\Captcha as CaptchaService;
|
use App\Library\Captcha as ImageCaptcha;
|
||||||
|
|
||||||
class Captcha extends Validator
|
class Captcha extends Validator
|
||||||
{
|
{
|
||||||
|
|
||||||
public function checkCode($ticket, $rand)
|
public function checkCode($ticket, $rand)
|
||||||
{
|
{
|
||||||
$service = new CaptchaService();
|
$captcha = new ImageCaptcha();
|
||||||
|
|
||||||
$result = $service->verify($ticket, $rand);
|
$result = $captcha->check($ticket, $rand);
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
throw new BadRequestException('captcha.invalid_code');
|
throw new BadRequestException('captcha.invalid_code');
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-fileinfo": "*",
|
"ext-fileinfo": "*",
|
||||||
|
"ext-gd": "*",
|
||||||
"phalcon/incubator": "^3.4",
|
"phalcon/incubator": "^3.4",
|
||||||
"guzzlehttp/guzzle": "^6.5",
|
"guzzlehttp/guzzle": "^6.5",
|
||||||
"swiftmailer/swiftmailer": "^6.0",
|
"swiftmailer/swiftmailer": "^6.0",
|
||||||
|
26
db/migrations/20230625182830.php
Normal file
26
db/migrations/20230625182830.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2023 深圳市酷瓜软件有限公司
|
||||||
|
* @license https://opensource.org/licenses/GPL-2.0
|
||||||
|
* @link https://www.koogua.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
final class V20230625182830 extends AbstractMigration
|
||||||
|
{
|
||||||
|
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->deleteCaptchaSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function deleteCaptchaSettings()
|
||||||
|
{
|
||||||
|
$this->getQueryBuilder()
|
||||||
|
->delete('kg_setting')
|
||||||
|
->where(['section' => 'captcha'])
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
layui.config({
|
layui.extend({
|
||||||
base: '/static/lib/layui/extends/'
|
kgDropdown: '/static/lib/layui/extends/kg-dropdown',
|
||||||
}).extend({
|
helper: '/static/lib/layui/extends/helper',
|
||||||
kgDropdown: 'kg-dropdown'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
layui.use(['jquery', 'form', 'element', 'layer', 'kgDropdown'], function () {
|
layui.use(['jquery', 'form', 'element', 'layer', 'kgDropdown'], function () {
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
layui.use(['jquery'], function () {
|
|
||||||
|
|
||||||
var $ = layui.jquery;
|
|
||||||
|
|
||||||
if ($('#cl-captcha-enabled').val() === '1') {
|
|
||||||
var captcha = new TencentCaptcha(
|
|
||||||
$('#cl-emit-btn')[0],
|
|
||||||
$('#cl-captcha-appId').val(),
|
|
||||||
function (res) {
|
|
||||||
if (res.ret === 0) {
|
|
||||||
$('#cl-captcha-ticket').val(res.ticket);
|
|
||||||
$('#cl-captcha-rand').val(res.randstr);
|
|
||||||
$('#cl-submit-btn').removeClass('layui-btn-disabled').removeAttr('disabled');
|
|
||||||
$('#captcha-block').hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
@ -1,80 +1,30 @@
|
|||||||
layui.use(['jquery', 'layer', 'util', 'helper'], function () {
|
layui.use(['jquery', 'layer', 'helper'], function () {
|
||||||
|
|
||||||
var $ = layui.jquery;
|
var $ = layui.jquery;
|
||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
var util = layui.util;
|
|
||||||
var helper = layui.helper;
|
var helper = layui.helper;
|
||||||
|
|
||||||
var timeCounting = false;
|
|
||||||
var $account = $('#cv-email');
|
var $account = $('#cv-email');
|
||||||
var $emit = $('#cv-email-emit-btn');
|
var $emit = $('#cv-email-emit-btn');
|
||||||
var $submit = $('#cv-email-submit-btn');
|
|
||||||
|
|
||||||
if ($('#cv-email-captcha-enabled').val() === '1') {
|
$emit.on('click', function () {
|
||||||
var captcha = new TencentCaptcha(
|
var url = '/verify/captcha?type=mail&account=' + $account.val();
|
||||||
$emit[0],
|
layer.open({
|
||||||
$('#cv-email-captcha-appId').val(),
|
type: 2,
|
||||||
function (res) {
|
title: '获取验证码',
|
||||||
if (res.ret === 0) {
|
area: ['500px', '250px'],
|
||||||
$('#cv-email-captcha-ticket').val(res.ticket);
|
content: [url, 'no'],
|
||||||
$('#cv-email-captcha-rand').val(res.randstr);
|
|
||||||
sendVerifyCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$emit.on('click', function () {
|
|
||||||
sendVerifyCode();
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
$account.on('keyup', function () {
|
$account.on('keyup', function () {
|
||||||
var account = $(this).val();
|
var account = $(this).val();
|
||||||
var accountOk = helper.isEmail(account);
|
var accountOk = helper.isEmail(account);
|
||||||
if (accountOk && !timeCounting) {
|
if (accountOk) {
|
||||||
$emit.removeClass('layui-btn-disabled').removeAttr('disabled');
|
$emit.removeClass('layui-btn-disabled').removeAttr('disabled');
|
||||||
} else {
|
} else {
|
||||||
$emit.addClass('layui-btn-disabled').attr('disabled', 'disabled');
|
$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;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
@ -1,86 +1,30 @@
|
|||||||
layui.use(['jquery', 'layer', 'util', 'helper'], function () {
|
layui.use(['jquery', 'layer', 'helper'], function () {
|
||||||
|
|
||||||
var $ = layui.jquery;
|
var $ = layui.jquery;
|
||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
var util = layui.util;
|
|
||||||
var helper = layui.helper;
|
var helper = layui.helper;
|
||||||
|
|
||||||
var timeCounting = false;
|
|
||||||
var $account = $('#cv-account');
|
var $account = $('#cv-account');
|
||||||
var $emit = $('#cv-emit-btn');
|
var $emit = $('#cv-emit-btn');
|
||||||
var $submit = $('#cv-submit-btn');
|
|
||||||
|
|
||||||
if ($('#cv-captcha-enabled').val() === '1') {
|
$emit.on('click', function () {
|
||||||
var captcha = new TencentCaptcha(
|
var url = '/verify/captcha?type=all&account=' + $account.val();
|
||||||
$emit[0],
|
layer.open({
|
||||||
$('#cv-captcha-appId').val(),
|
type: 2,
|
||||||
function (res) {
|
title: '获取验证码',
|
||||||
if (res.ret === 0) {
|
area: ['500px', '250px'],
|
||||||
$('#cv-captcha-ticket').val(res.ticket);
|
content: [url, 'no'],
|
||||||
$('#cv-captcha-rand').val(res.randstr);
|
|
||||||
sendVerifyCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$emit.on('click', function () {
|
|
||||||
sendVerifyCode();
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
$account.on('keyup', function () {
|
$account.on('keyup', function () {
|
||||||
var account = $(this).val();
|
var account = $(this).val();
|
||||||
var accountOk = helper.isPhone(account) || helper.isEmail(account);
|
var accountOk = helper.isPhone(account) || helper.isEmail(account);
|
||||||
if (accountOk && !timeCounting) {
|
if (accountOk) {
|
||||||
$emit.removeClass('layui-btn-disabled').removeAttr('disabled');
|
$emit.removeClass('layui-btn-disabled').removeAttr('disabled');
|
||||||
} else {
|
} else {
|
||||||
$emit.addClass('layui-btn-disabled').attr('disabled', 'disabled');
|
$emit.addClass('layui-btn-disabled').attr('disabled', 'disabled');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function sendVerifyCode() {
|
|
||||||
if (helper.isEmail($account.val()) || helper.isPhone($account.val())) {
|
|
||||||
var postUrl;
|
|
||||||
var postData = {
|
|
||||||
captcha: {
|
|
||||||
ticket: $('#cv-captcha-ticket').val(),
|
|
||||||
rand: $('#cv-captcha-rand').val(),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (helper.isPhone($account.val())) {
|
|
||||||
postData.phone = $account.val();
|
|
||||||
postUrl = '/verify/sms/code';
|
|
||||||
} else if (helper.isEmail($account.val())) {
|
|
||||||
postData.email = $account.val();
|
|
||||||
postUrl = '/verify/mail/code';
|
|
||||||
}
|
|
||||||
$.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
@ -1,80 +1,30 @@
|
|||||||
layui.use(['jquery', 'layer', 'util', 'helper'], function () {
|
layui.use(['jquery', 'layer', 'helper'], function () {
|
||||||
|
|
||||||
var $ = layui.jquery;
|
var $ = layui.jquery;
|
||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
var util = layui.util;
|
|
||||||
var helper = layui.helper;
|
var helper = layui.helper;
|
||||||
|
|
||||||
var timeCounting = false;
|
|
||||||
var $account = $('#cv-phone');
|
var $account = $('#cv-phone');
|
||||||
var $emit = $('#cv-phone-emit-btn');
|
var $emit = $('#cv-phone-emit-btn');
|
||||||
var $submit = $('#cv-phone-submit-btn');
|
|
||||||
|
|
||||||
if ($('#cv-phone-captcha-enabled').val() === '1') {
|
$emit.on('click', function () {
|
||||||
var captcha = new TencentCaptcha(
|
var url = '/verify/captcha?type=phone&account=' + $account.val();
|
||||||
$emit[0],
|
layer.open({
|
||||||
$('#cv-phone-captcha-appId').val(),
|
type: 2,
|
||||||
function (res) {
|
title: '获取验证码',
|
||||||
if (res.ret === 0) {
|
area: ['500px', '250px'],
|
||||||
$('#cv-phone-captcha-ticket').val(res.ticket);
|
content: [url, 'no'],
|
||||||
$('#cv-phone-captcha-rand').val(res.randstr);
|
|
||||||
sendVerifyCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$emit.on('click', function () {
|
|
||||||
sendVerifyCode();
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
$account.on('keyup', function () {
|
$account.on('keyup', function () {
|
||||||
var account = $(this).val();
|
var account = $(this).val();
|
||||||
var accountOk = helper.isPhone(account);
|
var accountOk = helper.isPhone(account);
|
||||||
if (accountOk && !timeCounting) {
|
if (accountOk) {
|
||||||
$emit.removeClass('layui-btn-disabled').removeAttr('disabled');
|
$emit.removeClass('layui-btn-disabled').removeAttr('disabled');
|
||||||
} else {
|
} else {
|
||||||
$emit.addClass('layui-btn-disabled').attr('disabled', 'disabled');
|
$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;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
@ -1,8 +1,4 @@
|
|||||||
layui.config({
|
layui.extend({
|
||||||
layimPath: '/static/lib/layui/extends/layim/',
|
|
||||||
layimAssetsPath: '/static/lib/layui/extends/layim/assets/',
|
|
||||||
}).extend({
|
|
||||||
layim: layui.cache.layimPath + 'layim',
|
|
||||||
layarea: '/static/lib/layui/extends/layarea',
|
layarea: '/static/lib/layui/extends/layarea',
|
||||||
helper: '/static/lib/layui/extends/helper',
|
helper: '/static/lib/layui/extends/helper',
|
||||||
});
|
});
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -51,26 +51,20 @@ $scheduler->php($script, $bin, ['--task' => 'refund', '--action' => 'main'])
|
|||||||
$scheduler->php($script, $bin, ['--task' => 'sync_course_index', '--action' => 'main'])
|
$scheduler->php($script, $bin, ['--task' => 'sync_course_index', '--action' => 'main'])
|
||||||
->hourly(11);
|
->hourly(11);
|
||||||
|
|
||||||
$scheduler->php($script, $bin, ['--task' => 'sync_group_index', '--action' => 'main'])
|
|
||||||
->hourly(17);
|
|
||||||
|
|
||||||
$scheduler->php($script, $bin, ['--task' => 'sync_user_index', '--action' => 'main'])
|
|
||||||
->hourly(23);
|
|
||||||
|
|
||||||
$scheduler->php($script, $bin, ['--task' => 'sync_article_index', '--action' => 'main'])
|
$scheduler->php($script, $bin, ['--task' => 'sync_article_index', '--action' => 'main'])
|
||||||
->hourly(27);
|
->hourly(13);
|
||||||
|
|
||||||
$scheduler->php($script, $bin, ['--task' => 'sync_question_index', '--action' => 'main'])
|
$scheduler->php($script, $bin, ['--task' => 'sync_question_index', '--action' => 'main'])
|
||||||
->hourly(29);
|
->hourly(17);
|
||||||
|
|
||||||
$scheduler->php($script, $bin, ['--task' => 'sync_course_score', '--action' => 'main'])
|
$scheduler->php($script, $bin, ['--task' => 'sync_course_score', '--action' => 'main'])
|
||||||
->hourly(31);
|
->hourly(19);
|
||||||
|
|
||||||
$scheduler->php($script, $bin, ['--task' => 'sync_article_score', '--action' => 'main'])
|
$scheduler->php($script, $bin, ['--task' => 'sync_article_score', '--action' => 'main'])
|
||||||
->hourly(33);
|
->hourly(23);
|
||||||
|
|
||||||
$scheduler->php($script, $bin, ['--task' => 'sync_question_score', '--action' => 'main'])
|
$scheduler->php($script, $bin, ['--task' => 'sync_question_score', '--action' => 'main'])
|
||||||
->hourly(37);
|
->hourly(29);
|
||||||
|
|
||||||
$scheduler->php($script, $bin, ['--task' => 'reset_demo_account', '--action' => 'main'])
|
$scheduler->php($script, $bin, ['--task' => 'reset_demo_account', '--action' => 'main'])
|
||||||
->hourly(59);
|
->hourly(59);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user