mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-26 20:52:44 +08:00
Merge branch 'koogua/v1.7.1'
This commit is contained in:
commit
f66dab48ec
19
CHANGELOG.md
19
CHANGELOG.md
@ -1,3 +1,22 @@
|
||||
### [v1.7.1](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.1)(2024-06-31)
|
||||
|
||||
- 更新layui-v2.9.10
|
||||
- 更新docker国内镜像地址
|
||||
- 增加导入镜像构建容器的方式
|
||||
- 调整微信公众号模板消息
|
||||
- 移除加载富文本编辑器初始化的语言文件
|
||||
- 移除consult中多余的chapter_id属性
|
||||
- 修正课程列表顶部过滤条件区块不能收缩问题
|
||||
- 用户中心第三方登录列表增加过滤条件
|
||||
- 后台增加打开/关闭左侧菜单提示
|
||||
- 优化整理文件mimeType
|
||||
- iconfont资源本地化
|
||||
- 优化UploadController
|
||||
- 优化富文本内容显示样式
|
||||
- 简化内容图片放大监听
|
||||
- 去除课程打赏相关内容
|
||||
- 课程增加能否发布检查
|
||||
|
||||
### [v1.7.0](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.0)(2024-05-15)
|
||||
|
||||
- 升级layui-2.9.8
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
友情提示:
|
||||
|
||||
- 演示系统配置低(1Core,1G,1M 跑多个容器)切莫压测
|
||||
- 演示系统配置低(2核,2G,1M 跑多个容器)切莫压测
|
||||
- 课程数据来源于网络(无实质内容)切莫购买
|
||||
- 管理后台已禁止数据提交,私密配置已过滤
|
||||
|
||||
@ -49,7 +49,7 @@ Tips: 请用手机注册一个新账号,用户中心 -> 关注订阅,扫码
|
||||
### 项目组件
|
||||
|
||||
- 后台框架:[phalcon 3.4.5](https://phalcon.io)
|
||||
- 前端框架:[layui 2.9.3](https://layui.dev)
|
||||
- 前端框架:[layui 2.9.10](https://layui.dev)
|
||||
- 全文检索:[xunsearch 1.4.17](http://www.xunsearch.com)
|
||||
- 基础依赖:[php7.3](https://php.net), [mysql5.7](https://mysql.com), [redis5.0](https://redis.io)
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
use App\Repos\Chapter as ChapterRepo;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
|
||||
@ -54,23 +53,6 @@ class ConsultList extends Builder
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getChapters(array $consults)
|
||||
{
|
||||
$ids = kg_array_column($consults, 'chapter_id');
|
||||
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$chapters = $chapterRepo->findByIds($ids, ['id', 'title']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($chapters->toArray() as $chapter) {
|
||||
$result[$chapter['id']] = $chapter;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getUsers(array $consults)
|
||||
{
|
||||
$ownerIds = kg_array_column($consults, 'owner_id');
|
||||
|
@ -113,8 +113,13 @@ class OrderList extends Builder
|
||||
$me['allow_refund'] = $refundStatusOk && $refundTimeOk ? 1 : 0;
|
||||
}
|
||||
|
||||
$me['allow_pay'] = $payStatusOk;
|
||||
$me['allow_cancel'] = $cancelStatusOk;
|
||||
if ($payStatusOk == 1) {
|
||||
$me['allow_pay'] = 1;
|
||||
}
|
||||
|
||||
if ($cancelStatusOk == 1) {
|
||||
$me['allow_cancel'] = 1;
|
||||
}
|
||||
|
||||
return $me;
|
||||
}
|
||||
@ -149,20 +154,6 @@ class OrderList extends Builder
|
||||
return $itemInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $itemInfo
|
||||
* @return mixed
|
||||
*/
|
||||
protected function handleRewardInfo($itemInfo)
|
||||
{
|
||||
if (!empty($itemInfo) && is_string($itemInfo)) {
|
||||
$itemInfo = json_decode($itemInfo, true);
|
||||
$itemInfo['course']['cover'] = $this->imgBaseUrl . $itemInfo['course']['cover'];
|
||||
}
|
||||
|
||||
return $itemInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $itemInfo
|
||||
* @return mixed
|
||||
|
48
app/Console/Migrations/V20240608145810.php
Normal file
48
app/Console/Migrations/V20240608145810.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2024 深圳市酷瓜软件有限公司
|
||||
* @license https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Console\Migrations;
|
||||
|
||||
use App\Models\Chapter as ChapterModel;
|
||||
use App\Models\Course as CourseModel;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class V20240608145810 extends Migration
|
||||
{
|
||||
|
||||
public function run()
|
||||
{
|
||||
$this->handleReadChapters();
|
||||
}
|
||||
|
||||
protected function handleReadChapters()
|
||||
{
|
||||
/**
|
||||
* @var $chapters Resultset|ChapterModel[]
|
||||
*/
|
||||
$chapters = ChapterModel::query()
|
||||
->where('model = :model:', ['model' => CourseModel::MODEL_READ])
|
||||
->andWhere('parent_id > 0')
|
||||
->execute();
|
||||
|
||||
if ($chapters->count() == 0) return;
|
||||
|
||||
foreach ($chapters as $chapter) {
|
||||
|
||||
$attrs = $chapter->attrs;
|
||||
|
||||
if (isset($attrs['format'])) continue;
|
||||
|
||||
$attrs['format'] = 'html';
|
||||
|
||||
$chapter->attrs = $attrs;
|
||||
|
||||
$chapter->update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -7,8 +7,8 @@
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Caches\CategoryList as CategoryListCache;
|
||||
use App\Caches\CategoryAllList as CategoryAllListCache;
|
||||
use App\Caches\CategoryList as CategoryListCache;
|
||||
use App\Caches\CategoryTreeList as CategoryTreeListCache;
|
||||
use App\Caches\IndexSlideList as IndexSlideListCache;
|
||||
use App\Models\Account as AccountModel;
|
||||
@ -39,8 +39,8 @@ class CleanDemoDataTask extends Task
|
||||
echo '------ start truncate tables ------' . PHP_EOL;
|
||||
|
||||
$excludeTables = [
|
||||
'kg_area', 'kg_migration', 'kg_migration_task', 'kg_nav', 'kg_page',
|
||||
'kg_reward', 'kg_role', 'kg_setting', 'kg_vip',
|
||||
'kg_area', 'kg_migration', 'kg_migration_task', 'kg_nav',
|
||||
'kg_page', 'kg_role', 'kg_setting', 'kg_vip',
|
||||
];
|
||||
|
||||
$tables = $this->db->listTables();
|
||||
|
@ -151,9 +151,6 @@ class RefundTask extends Task
|
||||
case OrderModel::ITEM_VIP:
|
||||
$this->handleVipOrderRefund($order);
|
||||
break;
|
||||
case OrderModel::ITEM_REWARD:
|
||||
$this->handleRewardOrderRefund($order);
|
||||
break;
|
||||
case OrderModel::ITEM_TEST:
|
||||
$this->handleTestOrderRefund($order);
|
||||
break;
|
||||
@ -230,16 +227,6 @@ class RefundTask extends Task
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理赞赏订单退款
|
||||
*
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
protected function handleRewardOrderRefund(OrderModel $order)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理测试订单退款
|
||||
*
|
||||
|
@ -40,8 +40,9 @@ class UploadController extends Controller
|
||||
}
|
||||
|
||||
$data = [
|
||||
'id' => $file->id,
|
||||
'name' => $file->name,
|
||||
'url' => $service->getImageUrl($file->path),
|
||||
'title' => $file->name,
|
||||
];
|
||||
|
||||
return $this->jsonSuccess(['data' => $data]);
|
||||
@ -61,8 +62,9 @@ class UploadController extends Controller
|
||||
}
|
||||
|
||||
$data = [
|
||||
'id' => $file->id,
|
||||
'name' => $file->name,
|
||||
'url' => $service->getImageUrl($file->path),
|
||||
'title' => $file->name,
|
||||
];
|
||||
|
||||
return $this->jsonSuccess(['data' => $data]);
|
||||
@ -82,8 +84,9 @@ class UploadController extends Controller
|
||||
}
|
||||
|
||||
$data = [
|
||||
'id' => $file->id,
|
||||
'name' => $file->name,
|
||||
'url' => $service->getImageUrl($file->path),
|
||||
'title' => $file->name,
|
||||
];
|
||||
|
||||
return $this->jsonSuccess(['data' => $data]);
|
||||
@ -100,7 +103,7 @@ class UploadController extends Controller
|
||||
|
||||
if (!$file) {
|
||||
return $this->jsonError([
|
||||
'message' => '上传图片失败',
|
||||
'message' => '上传文件失败',
|
||||
'error' => 1,
|
||||
]);
|
||||
}
|
||||
|
@ -163,6 +163,9 @@ class Course extends Service
|
||||
|
||||
if (isset($post['published'])) {
|
||||
$data['published'] = $validator->checkPublishStatus($post['published']);
|
||||
if ($post['published'] == 1) {
|
||||
$validator->checkPublishAbility($course);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($post['category_id']) && !empty($post['category_id'])) {
|
||||
|
@ -29,7 +29,6 @@
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('admin/js/content.editor.js') }}
|
||||
|
||||
{% endblock %}
|
@ -39,7 +39,6 @@
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('admin/js/content.editor.js') }}
|
||||
|
||||
{% endblock %}
|
@ -14,7 +14,7 @@
|
||||
<span><a href="{{ owner_url }}" target="_blank">{{ answer.owner.name }}</a></span>
|
||||
<span>{{ date('Y-m-d H:i:s',answer.create_time) }}</span>
|
||||
</div>
|
||||
<div class="content ke-content">{{ answer.content }}</div>
|
||||
<div class="content ke-content kg-zoom">{{ answer.content }}</div>
|
||||
</div>
|
||||
|
||||
<fieldset class="layui-elem-field layui-field-title">
|
||||
|
@ -25,7 +25,7 @@
|
||||
<span><a href="{{ owner_url }}" target="_blank">{{ answer.owner.name }}</a></span>
|
||||
<span>{{ date('Y-m-d H:i:s',answer.create_time) }}</span>
|
||||
</div>
|
||||
<div class="content ke-content">{{ answer.content }}</div>
|
||||
<div class="content ke-content kg-zoom">{{ answer.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
{{ js_include('lib/xm-select.js') }}
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('admin/js/content.editor.js') }}
|
||||
{{ js_include('admin/js/cover.upload.js') }}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
<span><a href="{{ owner_url }}" target="_blank">{{ article.owner.name }}</a></span>
|
||||
<span>{{ date('Y-m-d H:i:s',article.create_time) }}</span>
|
||||
</div>
|
||||
<div class="content ke-content">{{ article.content }}</div>
|
||||
<div class="content ke-content kg-zoom">{{ article.content }}</div>
|
||||
{% if article.tags %}
|
||||
<div class="tags">
|
||||
{% for item in article.tags %}
|
||||
|
@ -26,7 +26,7 @@
|
||||
<span><a href="{{ owner_url }}" target="_blank">{{ article.owner.name }}</a></span>
|
||||
<span>{{ date('Y-m-d H:i:s',article.create_time) }}</span>
|
||||
</div>
|
||||
<div class="content ke-content">{{ article.content }}</div>
|
||||
<div class="content ke-content kg-zoom">{{ article.content }}</div>
|
||||
{% if article.tags %}
|
||||
<div class="tags">
|
||||
{% for item in article.tags %}
|
||||
|
@ -48,7 +48,6 @@
|
||||
{% if chapter.model == 3 %}
|
||||
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('admin/js/content.editor.js') }}
|
||||
|
||||
{% elseif chapter.model == 1 %}
|
||||
|
@ -15,7 +15,7 @@
|
||||
<span><a href="{{ owner_url }}" target="_blank">{{ comment.owner.name }}</a></span>
|
||||
<span>{{ date('Y-m-d H:i:s',comment.create_time) }}</span>
|
||||
</div>
|
||||
<div class="content ke-content">{{ comment.content }}</div>
|
||||
<div class="content">{{ comment.content }}</div>
|
||||
</div>
|
||||
|
||||
<fieldset class="layui-elem-field layui-field-title">
|
||||
|
@ -24,7 +24,7 @@
|
||||
<span><a href="{{ owner_url }}" target="_blank">{{ comment.owner.name }}</a></span>
|
||||
<span>{{ date('Y-m-d H:i:s',comment.create_time) }}</span>
|
||||
</div>
|
||||
<div class="content ke-content">{{ comment.content }}</div>
|
||||
<div class="content">{{ comment.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
|
@ -50,7 +50,6 @@
|
||||
{{ js_include('lib/xm-select.js') }}
|
||||
{{ js_include('lib/cos-js-sdk-v5.min.js') }}
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('admin/js/content.editor.js') }}
|
||||
{{ js_include('admin/js/cover.upload.js') }}
|
||||
{{ js_include('admin/js/course.resource.js') }}
|
||||
|
@ -49,7 +49,6 @@
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('admin/js/content.editor.js') }}
|
||||
|
||||
{% endblock %}
|
@ -62,7 +62,6 @@
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('admin/js/content.editor.js') }}
|
||||
|
||||
{% endblock %}
|
@ -34,13 +34,6 @@
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% elseif order.item_type == 3 %}
|
||||
{% set course = order.item_info['course'] %}
|
||||
{% set reward = order.item_info['reward'] %}
|
||||
<div class="kg-order-item">
|
||||
<p>商品名称:{{ order.subject }}</p>
|
||||
<p>商品价格:{{ '¥%0.2f'|format(order.amount) }}</p>
|
||||
</div>
|
||||
{% elseif order.item_type == 4 %}
|
||||
{% set vip = order.item_info['vip'] %}
|
||||
<div class="kg-order-item">
|
||||
|
@ -32,7 +32,6 @@
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('admin/js/content.editor.js') }}
|
||||
|
||||
{% endblock %}
|
@ -51,7 +51,6 @@
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('admin/js/content.editor.js') }}
|
||||
|
||||
{% endblock %}
|
@ -18,7 +18,6 @@
|
||||
|
||||
{% if gift.type == 2 %}
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('admin/js/content.editor.js') }}
|
||||
{{ js_include('admin/js/cover.upload.js') }}
|
||||
{% endif %}
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
{{ js_include('lib/xm-select.js') }}
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('admin/js/content.editor.js') }}
|
||||
|
||||
{% endblock %}
|
||||
|
@ -14,7 +14,7 @@
|
||||
<span><a href="{{ owner_url }}" target="_blank">{{ question.owner.name }}</a></span>
|
||||
<span>{{ date('Y-m-d H:i:s',question.create_time) }}</span>
|
||||
</div>
|
||||
<div class="content ke-content">{{ question.content }}</div>
|
||||
<div class="content ke-content kg-zoom">{{ question.content }}</div>
|
||||
{% if question.tags %}
|
||||
<div class="tags">
|
||||
{% for item in question.tags %}
|
||||
|
@ -25,7 +25,7 @@
|
||||
<span><a href="{{ owner_url }}" target="_blank">{{ question.owner.name }}</a></span>
|
||||
<span>{{ date('Y-m-d H:i:s',question.create_time) }}</span>
|
||||
</div>
|
||||
<div class="content ke-content">{{ question.content }}</div>
|
||||
<div class="content ke-content kg-zoom">{{ question.content }}</div>
|
||||
{% if question.tags %}
|
||||
<div class="tags">
|
||||
{% for item in question.tags %}
|
||||
|
@ -47,6 +47,7 @@
|
||||
</td>
|
||||
<td><input class="layui-input" type="text" name="notice_template[refund_finish][id]" value="{{ notice_template.refund_finish.id }}" lay-verify="required"></td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr>
|
||||
<td>课程直播提醒</td>
|
||||
<td>
|
||||
@ -63,6 +64,7 @@
|
||||
</td>
|
||||
<td><input class="layui-input" type="text" name="notice_template[consult_reply][id]" value="{{ notice_template.consult_reply.id }}" lay-verify="required"></td>
|
||||
</tr>
|
||||
-->
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
|
@ -21,13 +21,6 @@
|
||||
<p>退款金额:{{ '¥%0.2f'|format(course.refund_amount) }},退款比例:{{ 100 * course.refund_percent }}%</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% elseif confirm.item_type == 3 %}
|
||||
{% set course = confirm.item_info.course %}
|
||||
{% set reward = confirm.item_info.reward %}
|
||||
<div class="kg-order-item">
|
||||
<p>课程名称:{{ course.title }}</p>
|
||||
<p>赞赏金额:{{ '¥%0.2f'|format(reward.price) }}</p>
|
||||
</div>
|
||||
{% elseif confirm.item_type == 4 %}
|
||||
{% set vip = confirm.item_info.vip %}
|
||||
<div class="kg-order-item">
|
||||
|
@ -29,7 +29,7 @@ class ConnectController extends Controller
|
||||
$service->setWechatRedirectCache($redirect);
|
||||
}
|
||||
|
||||
$url = $service->getAuthorizeUrl(ConnectModel::PROVIDER_WECHAT);
|
||||
$url = $service->getAuthorizeUrl(ConnectModel::PROVIDER_WECHAT_OA);
|
||||
|
||||
return $this->response->redirect($url, true);
|
||||
}
|
||||
@ -41,7 +41,7 @@ class ConnectController extends Controller
|
||||
{
|
||||
$service = new ConnectService();
|
||||
|
||||
$data = $service->handleCallback(ConnectModel::PROVIDER_WECHAT);
|
||||
$data = $service->handleCallback(ConnectModel::PROVIDER_WECHAT_OA);
|
||||
|
||||
$redirect = $service->getWechatRedirectCache();
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
namespace App\Http\Api\Controllers;
|
||||
|
||||
use App\Services\Logic\Reward\OptionList as RewardOptionList;
|
||||
use App\Services\Logic\Vip\OptionList as VipOptionList;
|
||||
use App\Services\Service as AppService;
|
||||
use App\Traits\Response as ResponseTrait;
|
||||
@ -94,18 +93,6 @@ class PublicController extends Controller
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/reward/options", name="api.public.reward_options")
|
||||
*/
|
||||
public function rewardOptionsAction()
|
||||
{
|
||||
$service = new RewardOptionList();
|
||||
|
||||
$options = $service->handle();
|
||||
|
||||
return $this->jsonSuccess(['options' => $options]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/vip/options", name="api.public.vip_options")
|
||||
*/
|
||||
|
@ -30,8 +30,9 @@ class UploadController extends Controller
|
||||
}
|
||||
|
||||
$data = [
|
||||
'id' => $file->id,
|
||||
'name' => $file->name,
|
||||
'url' => $service->getImageUrl($file->path),
|
||||
'title' => $file->name,
|
||||
];
|
||||
|
||||
return $this->jsonSuccess(['data' => $data]);
|
||||
|
@ -8,12 +8,12 @@
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\Account as AccountService;
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Services\Logic\Account\EmailUpdate as EmailUpdateService;
|
||||
use App\Services\Logic\Account\OAuthProvider as OAuthProviderService;
|
||||
use App\Services\Logic\Account\PasswordReset as PasswordResetService;
|
||||
use App\Services\Logic\Account\PasswordUpdate as PasswordUpdateService;
|
||||
use App\Services\Logic\Account\PhoneUpdate as PhoneUpdateService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/account")
|
||||
|
@ -8,7 +8,6 @@
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\Answer as AnswerService;
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Http\Home\Services\Question as QuestionService;
|
||||
use App\Models\Answer as AnswerModel;
|
||||
use App\Services\Logic\Answer\AnswerAccept as AnswerAcceptService;
|
||||
@ -17,6 +16,7 @@ use App\Services\Logic\Answer\AnswerDelete as AnswerDeleteService;
|
||||
use App\Services\Logic\Answer\AnswerInfo as AnswerInfoService;
|
||||
use App\Services\Logic\Answer\AnswerLike as AnswerLikeService;
|
||||
use App\Services\Logic\Answer\AnswerUpdate as AnswerUpdateService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
use Phalcon\Mvc\View;
|
||||
|
||||
/**
|
||||
|
@ -9,7 +9,6 @@ namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\Article as ArticleService;
|
||||
use App\Http\Home\Services\ArticleQuery as ArticleQueryService;
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Models\Article as ArticleModel;
|
||||
use App\Services\Logic\Article\ArticleClose as ArticleCloseService;
|
||||
use App\Services\Logic\Article\ArticleCreate as ArticleCreateService;
|
||||
@ -20,6 +19,7 @@ use App\Services\Logic\Article\ArticleLike as ArticleLikeService;
|
||||
use App\Services\Logic\Article\ArticleList as ArticleListService;
|
||||
use App\Services\Logic\Article\ArticleUpdate as ArticleUpdateService;
|
||||
use App\Services\Logic\Article\RelatedArticleList as RelatedArticleListService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
use Phalcon\Mvc\View;
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Models\ChapterLive as LiveModel;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Services\Logic\Chapter\ChapterInfo as ChapterInfoService;
|
||||
@ -15,6 +14,7 @@ use App\Services\Logic\Chapter\ChapterLike as ChapterLikeService;
|
||||
use App\Services\Logic\Chapter\Learning as ChapterLearningService;
|
||||
use App\Services\Logic\Course\BasicInfo as CourseInfoService;
|
||||
use App\Services\Logic\Course\ChapterList as CourseChapterListService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/chapter")
|
||||
|
@ -8,7 +8,6 @@
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\CourseQuery as CourseQueryService;
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Services\Logic\Course\ChapterList as CourseChapterListService;
|
||||
use App\Services\Logic\Course\ConsultList as CourseConsultListService;
|
||||
use App\Services\Logic\Course\CourseFavorite as CourseFavoriteService;
|
||||
@ -19,7 +18,7 @@ use App\Services\Logic\Course\RelatedList as CourseRelatedListService;
|
||||
use App\Services\Logic\Course\ResourceList as CourseResourceListService;
|
||||
use App\Services\Logic\Course\ReviewList as CourseReviewListService;
|
||||
use App\Services\Logic\Course\TopicList as CourseTopicListService;
|
||||
use App\Services\Logic\Reward\OptionList as RewardOptionList;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
use Phalcon\Mvc\View;
|
||||
|
||||
/**
|
||||
@ -104,17 +103,12 @@ class CourseController extends Controller
|
||||
|
||||
$chapters = $service->handle($id);
|
||||
|
||||
$service = new RewardOptionList();
|
||||
|
||||
$rewards = $service->handle();
|
||||
|
||||
$this->seo->prependTitle(['课程', $course['title']]);
|
||||
$this->seo->setKeywords($course['keywords']);
|
||||
$this->seo->setDescription($course['summary']);
|
||||
|
||||
$this->view->setVar('course', $course);
|
||||
$this->view->setVar('chapters', $chapters);
|
||||
$this->view->setVar('rewards', $rewards);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,9 +7,9 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Services\Logic\Help\HelpInfo as HelpInfoService;
|
||||
use App\Services\Logic\Help\HelpList as HelpListService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/help")
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Http\Home\Services\Index as IndexService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
|
@ -7,9 +7,9 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Http\Home\Services\Index as IndexService;
|
||||
use App\Services\Logic\Page\PageInfo as PageInfoService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/page")
|
||||
|
@ -11,6 +11,7 @@ use App\Services\Logic\Point\GiftInfo as GiftInfoService;
|
||||
use App\Services\Logic\Point\GiftList as GiftListService;
|
||||
use App\Services\Logic\Point\GiftRedeem as GiftRedeemService;
|
||||
use App\Services\Logic\Point\HotGiftList as HotGiftListService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
use App\Services\Logic\User\Console\BalanceInfo as BalanceInfoService;
|
||||
use Phalcon\Mvc\Dispatcher;
|
||||
use Phalcon\Mvc\View;
|
||||
@ -38,6 +39,13 @@ class PointGiftController extends Controller
|
||||
*/
|
||||
public function listAction()
|
||||
{
|
||||
$service = new FullH5UrlService();
|
||||
|
||||
if ($service->isMobileBrowser() && $service->h5Enabled()) {
|
||||
$location = $service->getPointGiftListUrl();
|
||||
return $this->response->redirect($location);
|
||||
}
|
||||
|
||||
$this->seo->prependTitle('积分商城');
|
||||
|
||||
$this->view->pick('point/gift/list');
|
||||
|
@ -7,10 +7,11 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\ShareUrl as ShareUrlService;
|
||||
use App\Library\CsrfToken as CsrfTokenService;
|
||||
use App\Repos\Upload as UploadRepo;
|
||||
use App\Services\LiveNotify as LiveNotifyService;
|
||||
use App\Services\Logic\Url\ShareUrl as ShareUrlService;
|
||||
use App\Services\Logic\WeChat\OfficialAccount as WeChatOAService;
|
||||
use App\Services\Pay\Alipay as AlipayService;
|
||||
use App\Services\Pay\Wxpay as WxpayService;
|
||||
use App\Services\Storage as StorageService;
|
||||
@ -150,6 +151,42 @@ class PublicController extends \Phalcon\Mvc\Controller
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/wechat/oa/notify", name="home.wechat_oa.verify")
|
||||
*/
|
||||
public function wechatOaVerifyAction()
|
||||
{
|
||||
$service = new WeChatOAService();
|
||||
|
||||
$app = $service->getOfficialAccount();
|
||||
|
||||
$response = $app->server->serve();
|
||||
|
||||
$response->send();
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/wechat/oa/notify", name="home.wechat_oa.notify")
|
||||
*/
|
||||
public function wechatOaNotifyAction()
|
||||
{
|
||||
$service = new WeChatOAService();
|
||||
|
||||
$app = $service->getOfficialAccount();
|
||||
|
||||
$app->server->push(function ($message) use ($service) {
|
||||
return $service->handleNotify($message);
|
||||
});
|
||||
|
||||
$response = $app->server->serve();
|
||||
|
||||
$response->send();
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/live/notify", name="home.live_notify")
|
||||
*/
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Http\Home\Services\Question as QuestionService;
|
||||
use App\Http\Home\Services\QuestionQuery as QuestionQueryService;
|
||||
use App\Models\Question as QuestionModel;
|
||||
@ -20,6 +19,7 @@ use App\Services\Logic\Question\QuestionLike as QuestionLikeService;
|
||||
use App\Services\Logic\Question\QuestionList as QuestionListService;
|
||||
use App\Services\Logic\Question\QuestionUpdate as QuestionUpdateService;
|
||||
use App\Services\Logic\Question\RelatedQuestionList as RelatedQuestionListService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
use Phalcon\Mvc\View;
|
||||
|
||||
/**
|
||||
|
@ -7,9 +7,9 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Services\Logic\Teacher\CourseList as TeacherCourseListService;
|
||||
use App\Services\Logic\Teacher\TeacherList as TeacherListService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
use App\Services\Logic\User\UserInfo as UserInfoService;
|
||||
use Phalcon\Mvc\View;
|
||||
|
||||
|
@ -39,17 +39,18 @@ class UploadController extends Controller
|
||||
}
|
||||
|
||||
$data = [
|
||||
'id' => $file->id,
|
||||
'name' => $file->name,
|
||||
'url' => $service->getImageUrl($file->path),
|
||||
'title' => $file->name,
|
||||
];
|
||||
|
||||
return $this->jsonSuccess(['data' => $data]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/editor/img", name="home.upload.editor_img")
|
||||
* @Post("/content/img", name="home.upload.content_img")
|
||||
*/
|
||||
public function uploadEditorImageAction()
|
||||
public function uploadContentImageAction()
|
||||
{
|
||||
$service = new StorageService();
|
||||
|
||||
@ -57,7 +58,7 @@ class UploadController extends Controller
|
||||
|
||||
if (!$file) {
|
||||
return $this->jsonError([
|
||||
'message' => '上传图片失败',
|
||||
'message' => '上传文件失败',
|
||||
'error' => 1,
|
||||
]);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
use App\Services\Logic\User\AnswerList as UserAnswerListService;
|
||||
use App\Services\Logic\User\ArticleList as UserArticleListService;
|
||||
use App\Services\Logic\User\CourseList as UserCourseListService;
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
||||
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||
use App\Services\Logic\Vip\CourseList as VipCourseListService;
|
||||
use App\Services\Logic\Vip\OptionList as VipOptionListService;
|
||||
use App\Services\Logic\Vip\UserList as VipUserListService;
|
||||
|
@ -7,31 +7,59 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\WeChatOfficialAccount as WeChatOAService;
|
||||
use App\Http\Home\Services\WeChatOfficialAccount as HomeWeChatOAService;
|
||||
use App\Services\Logic\WeChat\OfficialAccount as WeChatOAService;
|
||||
use App\Traits\Response as ResponseTrait;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/wechat/oa")
|
||||
*/
|
||||
class WeChatOfficialAccountController extends \Phalcon\Mvc\Controller
|
||||
class WeChatOfficialAccountController extends Controller
|
||||
{
|
||||
|
||||
use ResponseTrait;
|
||||
|
||||
/**
|
||||
* @Get("/subscribe/status", name="home.wechat_oa.sub_status")
|
||||
* @Get("/bind", name="home.wechat_oa.bind")
|
||||
*/
|
||||
public function subscribeStatusAction()
|
||||
public function bindAction()
|
||||
{
|
||||
$service = new WeChatOAService();
|
||||
$captcha = $this->getSettings('captcha');
|
||||
|
||||
$status = $service->getSubscribeStatus();
|
||||
$this->seo->prependTitle('绑定帐号');
|
||||
|
||||
return $this->jsonSuccess(['status' => $status]);
|
||||
$this->view->pick('wechat/oa/bind');
|
||||
$this->view->setVar('captcha', $captcha);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/subscribe/qrcode", name="home.wechat_oa.sub_qrcode")
|
||||
* @Get("/login/qrcode", name="home.wechat_oa.login_qrcode")
|
||||
*/
|
||||
public function loginQrCodeAction()
|
||||
{
|
||||
$service = new WeChatOAService();
|
||||
|
||||
$qrcode = $service->createLoginQrCode();
|
||||
|
||||
return $this->jsonSuccess(['qrcode' => $qrcode]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/login/status", name="home.wechat_oa.lgoin_status")
|
||||
*/
|
||||
public function loginStatusAction()
|
||||
{
|
||||
$ticket = $this->request->getQuery('ticket');
|
||||
|
||||
$service = new WeChatOAService();
|
||||
|
||||
$data = $service->getLoginStatus($ticket);
|
||||
|
||||
return $this->jsonSuccess(['data' => $data]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/subscribe/qrcode", name="home.wechat_oa.subscribe_qrcode")
|
||||
*/
|
||||
public function subscribeQrCodeAction()
|
||||
{
|
||||
@ -43,39 +71,63 @@ class WeChatOfficialAccountController extends \Phalcon\Mvc\Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/notify", name="home.wechat_oa.verify")
|
||||
* @Get("/subscribe/status", name="home.wechat_oa.subscribe_status")
|
||||
*/
|
||||
public function verifyAction()
|
||||
public function subscribeStatusAction()
|
||||
{
|
||||
$service = new WeChatOAService();
|
||||
|
||||
$app = $service->getOfficialAccount();
|
||||
$status = $service->getSubscribeStatus();
|
||||
|
||||
$response = $app->server->serve();
|
||||
|
||||
$response->send();
|
||||
|
||||
exit;
|
||||
return $this->jsonSuccess(['status' => $status]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/notify", name="home.wechat_oa.notify")
|
||||
* @Post("/auth/login", name="home.wechat_oa.auth_login")
|
||||
*/
|
||||
public function notifyAction()
|
||||
public function authLoginAction()
|
||||
{
|
||||
$service = new WeChatOAService();
|
||||
$service = new HomeWeChatOAService();
|
||||
|
||||
$app = $service->getOfficialAccount();
|
||||
$service->authLogin();
|
||||
|
||||
$app->server->push(function ($message) use ($service) {
|
||||
return $service->handleNotify($message);
|
||||
});
|
||||
$returnUrl = $this->request->getPost('return_url', 'string');
|
||||
|
||||
$response = $app->server->serve();
|
||||
$location = $returnUrl ?: $this->url->get(['for' => 'home.index']);
|
||||
|
||||
$response->send();
|
||||
return $this->jsonSuccess(['location' => $location]);
|
||||
}
|
||||
|
||||
exit;
|
||||
/**
|
||||
* @Post("/bind/login", name="home.wechat_oa.bind_login")
|
||||
*/
|
||||
public function bindLoginAction()
|
||||
{
|
||||
$service = new HomeWeChatOAService();
|
||||
|
||||
$service->bindLogin();
|
||||
|
||||
$returnUrl = $this->request->getPost('return_url', 'string');
|
||||
|
||||
$location = $returnUrl ?: $this->url->get(['for' => 'home.index']);
|
||||
|
||||
return $this->jsonSuccess(['location' => $location]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/bind/register", name="home.wechat_oa.bind_register")
|
||||
*/
|
||||
public function bindRegisterAction()
|
||||
{
|
||||
$service = new HomeWeChatOAService();
|
||||
|
||||
$service->bindRegister();
|
||||
|
||||
$returnUrl = $this->request->getPost('return_url', 'string');
|
||||
|
||||
$location = $returnUrl ?: $this->url->get(['for' => 'home.index']);
|
||||
|
||||
return $this->jsonSuccess(['location' => $location]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,6 +85,10 @@ class Connect extends Service
|
||||
|
||||
$user = $userRepo->findById($connect->user_id);
|
||||
|
||||
$validator = new AccountValidator();
|
||||
|
||||
$validator->checkIfAllowLogin($user);
|
||||
|
||||
$this->handleLoginNotice($user);
|
||||
|
||||
$auth = $this->getAppAuth();
|
||||
|
@ -1,153 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Http\Home\Services;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Repos\Chapter as ChapterRepo;
|
||||
use App\Traits\Client as ClientTrait;
|
||||
|
||||
class FullH5Url extends Service
|
||||
{
|
||||
|
||||
protected $baseUrl;
|
||||
|
||||
use ClientTrait;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->baseUrl = $this->getBaseUrl();
|
||||
}
|
||||
|
||||
public function getHomeUrl()
|
||||
{
|
||||
return sprintf('%s/index/index', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getAccountRegisterUrl()
|
||||
{
|
||||
return sprintf('%s/account/register', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getAccountLoginUrl()
|
||||
{
|
||||
return sprintf('%s/account/login', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getAccountForgetUrl()
|
||||
{
|
||||
return sprintf('%s/account/forget', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getVipIndexUrl()
|
||||
{
|
||||
return sprintf('%s/vip/index', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getHelpIndexUrl()
|
||||
{
|
||||
return sprintf('%s/help/index', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getCourseListUrl()
|
||||
{
|
||||
return sprintf('%s/course/list', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getArticleListUrl()
|
||||
{
|
||||
return sprintf('%s/article/list', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getQuestionListUrl()
|
||||
{
|
||||
return sprintf('%s/question/list', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getLiveListUrl()
|
||||
{
|
||||
return sprintf('%s/discovery/index', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getTeacherListUrl()
|
||||
{
|
||||
return sprintf('%s/discovery/index', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getPointGiftListUrl()
|
||||
{
|
||||
return sprintf('%s/point/gift/list', $this->baseUrl);
|
||||
}
|
||||
|
||||
public function getPageInfoUrl($id)
|
||||
{
|
||||
return sprintf('%s/page/info?id=%s', $this->baseUrl, $id);
|
||||
}
|
||||
|
||||
public function getHelpInfoUrl($id)
|
||||
{
|
||||
return sprintf('%s/help/info?id=%s', $this->baseUrl, $id);
|
||||
}
|
||||
|
||||
public function getArticleInfoUrl($id)
|
||||
{
|
||||
return sprintf('%s/article/info?id=%s', $this->baseUrl, $id);
|
||||
}
|
||||
|
||||
public function getQuestionInfoUrl($id)
|
||||
{
|
||||
return sprintf('%s/question/info?id=%s', $this->baseUrl, $id);
|
||||
}
|
||||
|
||||
public function getAnswerInfoUrl($id)
|
||||
{
|
||||
return sprintf('%s/answer/info?id=%s', $this->baseUrl, $id);
|
||||
}
|
||||
|
||||
public function getCourseInfoUrl($id)
|
||||
{
|
||||
return sprintf('%s/course/info?id=%s', $this->baseUrl, $id);
|
||||
}
|
||||
|
||||
public function getChapterInfoUrl($id)
|
||||
{
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$chapter = $chapterRepo->findById($id);
|
||||
|
||||
if ($chapter->model == CourseModel::MODEL_VOD) {
|
||||
return sprintf('%s/chapter/vod?id=%s', $this->baseUrl, $id);
|
||||
} elseif ($chapter->model == CourseModel::MODEL_LIVE) {
|
||||
return sprintf('%s/chapter/live?id=%s', $this->baseUrl, $id);
|
||||
} elseif ($chapter->model == CourseModel::MODEL_READ) {
|
||||
return sprintf('%s/chapter/read?id=%s', $this->baseUrl, $id);
|
||||
} else {
|
||||
return $this->getHomeUrl();
|
||||
}
|
||||
}
|
||||
|
||||
public function getUserIndexUrl($id)
|
||||
{
|
||||
return sprintf('%s/user/index?id=%s', $this->baseUrl, $id);
|
||||
}
|
||||
|
||||
public function getTeacherIndexUrl($id)
|
||||
{
|
||||
return sprintf('%s/teacher/index?id=%s', $this->baseUrl, $id);
|
||||
}
|
||||
|
||||
public function getPointGiftInfoUrl($id)
|
||||
{
|
||||
return sprintf('%s/point/gift/info?id=%s', $this->baseUrl, $id);
|
||||
}
|
||||
|
||||
protected function getBaseUrl()
|
||||
{
|
||||
return sprintf('%s/h5/#/pages', kg_site_url());
|
||||
}
|
||||
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Http\Home\Services;
|
||||
|
||||
class FullWebUrl extends Service
|
||||
{
|
||||
|
||||
protected $baseUrl;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->baseUrl = $this->getBaseUrl();
|
||||
}
|
||||
|
||||
public function getHomeUrl()
|
||||
{
|
||||
return $this->baseUrl;
|
||||
}
|
||||
|
||||
public function getArticleShowUrl($id)
|
||||
{
|
||||
$route = $this->url->get(['for' => 'home.article.show', 'id' => $id]);
|
||||
|
||||
return $this->baseUrl . $route;
|
||||
}
|
||||
|
||||
public function getQuestionShowUrl($id)
|
||||
{
|
||||
$route = $this->url->get(['for' => 'home.question.show', 'id' => $id]);
|
||||
|
||||
return $this->baseUrl . $route;
|
||||
}
|
||||
|
||||
public function getCourseShowUrl($id)
|
||||
{
|
||||
$route = $this->url->get(['for' => 'home.course.show', 'id' => $id]);
|
||||
|
||||
return $this->baseUrl . $route;
|
||||
}
|
||||
|
||||
public function getChapterShowUrl($id)
|
||||
{
|
||||
$route = $this->url->get(['for' => 'home.chapter.show', 'id' => $id]);
|
||||
|
||||
return $this->baseUrl . $route;
|
||||
}
|
||||
|
||||
public function getUserShowUrl($id)
|
||||
{
|
||||
$route = $this->url->get(['for' => 'home.user.show', 'id' => $id]);
|
||||
|
||||
return $this->baseUrl . $route;
|
||||
}
|
||||
|
||||
public function getTeacherShowUrl($id)
|
||||
{
|
||||
$route = $this->url->get(['for' => 'home.teacher.show', 'id' => $id]);
|
||||
|
||||
return $this->baseUrl . $route;
|
||||
}
|
||||
|
||||
public function getPointGiftShowUrl($id)
|
||||
{
|
||||
$route = $this->url->get(['for' => 'home.point_gift.show', 'id' => $id]);
|
||||
|
||||
return $this->baseUrl . $route;
|
||||
}
|
||||
|
||||
protected function getBaseUrl()
|
||||
{
|
||||
return kg_site_url();
|
||||
}
|
||||
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Http\Home\Services;
|
||||
|
||||
use App\Traits\Client as ClientTrait;
|
||||
|
||||
class ShareUrl extends Service
|
||||
{
|
||||
|
||||
/**
|
||||
* WEB站点URL
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fullWebUrl;
|
||||
|
||||
/**
|
||||
* H5站点URL
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fullH5Url;
|
||||
|
||||
use ClientTrait;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->fullWebUrl = new FullWebUrl();
|
||||
$this->fullH5Url = new FullH5Url();
|
||||
}
|
||||
|
||||
public function handle($id, $type)
|
||||
{
|
||||
if ($type == 'article') {
|
||||
$result = $this->getArticleUrl($id);
|
||||
} elseif ($type == 'question') {
|
||||
$result = $this->getQuestionUrl($id);
|
||||
} elseif ($type == 'course') {
|
||||
$result = $this->getCourseUrl($id);
|
||||
} elseif ($type == 'chapter') {
|
||||
$result = $this->getChapterUrl($id);
|
||||
} elseif ($type == 'user') {
|
||||
$result = $this->getUserUrl($id);
|
||||
} elseif ($type == 'teacher') {
|
||||
$result = $this->getTeacherUrl($id);
|
||||
} else {
|
||||
$result = $this->getHomeUrl();
|
||||
}
|
||||
|
||||
$gotoH5 = $this->h5Enabled() && $this->isMobileBrowser();
|
||||
|
||||
return $gotoH5 ? $result['h5'] : $result['web'];
|
||||
}
|
||||
|
||||
public function getHomeUrl()
|
||||
{
|
||||
$webUrl = $this->fullWebUrl->getHomeUrl();
|
||||
|
||||
$h5Url = $this->fullH5Url->getHomeUrl();
|
||||
|
||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
||||
}
|
||||
|
||||
public function getArticleUrl($id = 0)
|
||||
{
|
||||
$webUrl = $this->fullWebUrl->getArticleShowUrl($id);
|
||||
|
||||
$h5Url = $this->fullH5Url->getArticleInfoUrl($id);
|
||||
|
||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
||||
}
|
||||
|
||||
public function getQuestionUrl($id = 0)
|
||||
{
|
||||
$webUrl = $this->fullWebUrl->getQuestionShowUrl($id);
|
||||
|
||||
$h5Url = $this->fullH5Url->getQuestionInfoUrl($id);
|
||||
|
||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
||||
}
|
||||
|
||||
public function getCourseUrl($id = 0)
|
||||
{
|
||||
$webUrl = $this->fullWebUrl->getCourseShowUrl($id);
|
||||
|
||||
$h5Url = $this->fullH5Url->getCourseInfoUrl($id);
|
||||
|
||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
||||
}
|
||||
|
||||
public function getChapterUrl($id = 0)
|
||||
{
|
||||
$webUrl = $this->fullWebUrl->getChapterShowUrl($id);
|
||||
|
||||
$h5Url = $this->fullH5Url->getChapterInfoUrl($id);
|
||||
|
||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
||||
}
|
||||
|
||||
public function getUserUrl($id = 0)
|
||||
{
|
||||
$webUrl = $this->fullWebUrl->getUserShowUrl($id);
|
||||
|
||||
$h5Url = $this->fullH5Url->getUserIndexUrl($id);
|
||||
|
||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
||||
}
|
||||
|
||||
public function getTeacherUrl($id = 0)
|
||||
{
|
||||
$webUrl = $this->fullWebUrl->getTeacherShowUrl($id);
|
||||
|
||||
$h5Url = $this->fullH5Url->getTeacherIndexUrl($id);
|
||||
|
||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
||||
}
|
||||
|
||||
}
|
@ -7,242 +7,119 @@
|
||||
|
||||
namespace App\Http\Home\Services;
|
||||
|
||||
use App\Models\WeChatSubscribe as WeChatSubscribeModel;
|
||||
use App\Models\Connect as ConnectModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\Connect as ConnectRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
use App\Repos\WeChatSubscribe as WeChatSubscribeRepo;
|
||||
use App\Services\WeChat as WeChatService;
|
||||
use EasyWeChat\Kernel\Messages\Text as TextMessage;
|
||||
use App\Services\Auth\Home as AuthService;
|
||||
use App\Services\Logic\Account\Register as RegisterService;
|
||||
use App\Services\Logic\Notice\External\AccountLogin as AccountLoginNotice;
|
||||
use App\Validators\Account as AccountValidator;
|
||||
use App\Validators\WeChatOfficialAccount as WeChatOAValidator;
|
||||
|
||||
class WeChatOfficialAccount extends Service
|
||||
{
|
||||
|
||||
public function getOfficialAccount()
|
||||
public function authLogin()
|
||||
{
|
||||
$service = new WeChatService();
|
||||
$ticket = $this->request->getPost('ticket');
|
||||
|
||||
return $service->getOfficialAccount();
|
||||
}
|
||||
$validator = new WeChatOAValidator();
|
||||
|
||||
public function createSubscribeQrCode()
|
||||
{
|
||||
$user = $this->getLoginUser();
|
||||
$openId = $validator->checkLoginOpenId($ticket);
|
||||
|
||||
$app = $this->getOfficialAccount();
|
||||
$connectRepo = new ConnectRepo();
|
||||
|
||||
$result = $app->qrcode->temporary($user->id);
|
||||
|
||||
return $app->qrcode->url($result['ticket']);
|
||||
}
|
||||
|
||||
public function getSubscribeStatus()
|
||||
{
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$subscribeRepo = new WeChatSubscribeRepo();
|
||||
|
||||
$subscribe = $subscribeRepo->findByUserId($user->id);
|
||||
|
||||
return $subscribe ? 1 : 0;
|
||||
}
|
||||
|
||||
public function handleNotify($message)
|
||||
{
|
||||
$service = new WeChatService();
|
||||
|
||||
$service->logger->debug('Received Message ' . json_encode($message));
|
||||
|
||||
switch ($message['MsgType']) {
|
||||
case 'event':
|
||||
switch ($message['Event']) {
|
||||
case 'subscribe':
|
||||
return $this->handleSubscribeEvent($message);
|
||||
case 'unsubscribe':
|
||||
return $this->handleUnsubscribeEvent($message);
|
||||
case 'SCAN':
|
||||
return $this->handleScanEvent($message);
|
||||
case 'CLICK':
|
||||
return $this->handleClickEvent($message);
|
||||
case 'VIEW':
|
||||
return $this->handleViewEvent($message);
|
||||
case 'LOCATION':
|
||||
return $this->handleLocationEvent($message);
|
||||
default:
|
||||
return $this->noMatchReply();
|
||||
}
|
||||
case 'text':
|
||||
return $this->handleTextReply($message);
|
||||
case 'image':
|
||||
return $this->handleImageReply($message);
|
||||
case 'voice':
|
||||
return $this->handleVoiceReply($message);
|
||||
case 'video':
|
||||
return $this->handleVideoReply($message);
|
||||
case 'shortvideo':
|
||||
return $this->handleShortVideoReply($message);
|
||||
case 'location':
|
||||
return $this->handleLocationReply($message);
|
||||
case 'link':
|
||||
return $this->handleLinkReply($message);
|
||||
default:
|
||||
return $this->noMatchReply();
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleSubscribeEvent($message)
|
||||
{
|
||||
$openId = $message['FromUserName'] ?? '';
|
||||
$eventKey = $message['EventKey'] ?? '';
|
||||
|
||||
/**
|
||||
* 带场景值的关注事件
|
||||
*/
|
||||
$userId = str_replace('qrscene_', '', $eventKey);
|
||||
|
||||
if ($userId && $openId) {
|
||||
$this->saveWechatSubscribe($userId, $openId);
|
||||
}
|
||||
|
||||
return new TextMessage('开心呀,我们又多了一个小伙伴!');
|
||||
}
|
||||
|
||||
protected function handleUnsubscribeEvent($message)
|
||||
{
|
||||
$openId = $message['FromUserName'] ?? '';
|
||||
|
||||
$subscribeRepo = new WeChatSubscribeRepo();
|
||||
|
||||
$subscribe = $subscribeRepo->findByOpenId($openId);
|
||||
|
||||
if ($subscribe) {
|
||||
$subscribe->deleted = 1;
|
||||
$subscribe->update();
|
||||
}
|
||||
|
||||
return new TextMessage('伤心呀,我们又少了一个小伙伴!');
|
||||
}
|
||||
|
||||
protected function handleScanEvent($message)
|
||||
{
|
||||
$openId = $message['FromUserName'] ?? '';
|
||||
$eventKey = $message['EventKey'] ?? '';
|
||||
|
||||
$userId = str_replace('qrscene_', '', $eventKey);
|
||||
|
||||
if ($userId && $openId) {
|
||||
$userInfo = $this->getUserInfo($openId);
|
||||
$unionId = $userInfo['unionid'] ?: '';
|
||||
$this->saveWechatSubscribe($userId, $openId, $unionId);
|
||||
}
|
||||
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleClickEvent($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleViewEvent($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleLocationEvent($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleTextReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleImageReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleVoiceReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleVideoReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleShortVideoReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleLocationReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleLinkReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function emptyReply()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function noMatchReply()
|
||||
{
|
||||
return new TextMessage('没有匹配的服务哦!');
|
||||
}
|
||||
|
||||
protected function saveWechatSubscribe($userId, $openId, $unionId = '')
|
||||
{
|
||||
if (!$userId || !$openId) return;
|
||||
$connect = $connectRepo->findByOpenId($openId, ConnectModel::PROVIDER_WECHAT_OA);
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$user = $userRepo->findById($userId);
|
||||
$user = $userRepo->findById($connect->user_id);
|
||||
|
||||
if (!$user) return;
|
||||
$validator = new AccountValidator();
|
||||
|
||||
$subscribeRepo = new WeChatSubscribeRepo();
|
||||
$validator->checkIfAllowLogin($user);
|
||||
|
||||
$subscribe = $subscribeRepo->findByOpenId($openId);
|
||||
$this->handleLoginNotice($user);
|
||||
|
||||
if ($subscribe) {
|
||||
if ($subscribe->user_id != $userId) {
|
||||
$subscribe->user_id = $userId;
|
||||
}
|
||||
if (empty($subscribe->union_id) && !empty($unionId)) {
|
||||
$subscribe->union_id = $unionId;
|
||||
}
|
||||
if ($subscribe->deleted == 1) {
|
||||
$subscribe->deleted = 0;
|
||||
}
|
||||
$subscribe->update();
|
||||
} else {
|
||||
$subscribe = new WeChatSubscribeModel();
|
||||
$subscribe->user_id = $userId;
|
||||
$subscribe->open_id = $openId;
|
||||
$subscribe->union_id = $unionId;
|
||||
$subscribe->create();
|
||||
}
|
||||
$auth = $this->getAppAuth();
|
||||
|
||||
$auth->saveAuthInfo($user);
|
||||
}
|
||||
|
||||
protected function getUserInfo($openId)
|
||||
public function bindLogin()
|
||||
{
|
||||
$app = $this->getOfficialAccount();
|
||||
$post = $this->request->getPost();
|
||||
|
||||
return $app->user->get($openId);
|
||||
$validator = new AccountValidator();
|
||||
|
||||
$user = $validator->checkUserLogin($post['account'], $post['password']);
|
||||
|
||||
$validator = new WeChatOAValidator();
|
||||
|
||||
$openId = $validator->checkLoginOpenId($post['ticket']);
|
||||
|
||||
$connect = new ConnectModel();
|
||||
|
||||
$connect->user_id = $user->id;
|
||||
$connect->open_id = $openId;
|
||||
$connect->provider = ConnectModel::PROVIDER_WECHAT_OA;
|
||||
|
||||
$connect->create();
|
||||
|
||||
$this->handleLoginNotice($user);
|
||||
|
||||
$auth = $this->getAppAuth();
|
||||
|
||||
$auth->saveAuthInfo($user);
|
||||
}
|
||||
|
||||
protected function getWechatLogger()
|
||||
public function bindRegister()
|
||||
{
|
||||
$service = new WeChatService();
|
||||
$post = $this->request->getPost();
|
||||
|
||||
return $service->logger;
|
||||
$validator = new WeChatOAValidator();
|
||||
|
||||
$openId = $validator->checkLoginOpenId($post['ticket']);
|
||||
|
||||
$registerService = new RegisterService();
|
||||
|
||||
$account = $registerService->handle();
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$user = $userRepo->findById($account->id);
|
||||
|
||||
$connect = new ConnectModel();
|
||||
|
||||
$connect->user_id = $user->id;
|
||||
$connect->open_id = $openId;
|
||||
$connect->provider = ConnectModel::PROVIDER_WECHAT_OA;
|
||||
|
||||
$connect->create();
|
||||
|
||||
$this->handleLoginNotice($user);
|
||||
|
||||
$auth = $this->getAppAuth();
|
||||
|
||||
$auth->saveAuthInfo($user);
|
||||
}
|
||||
|
||||
protected function getAppAuth()
|
||||
{
|
||||
/**
|
||||
* @var $auth AuthService
|
||||
*/
|
||||
$auth = $this->getDI()->get('auth');
|
||||
|
||||
return $auth;
|
||||
}
|
||||
|
||||
protected function handleLoginNotice(UserModel $user)
|
||||
{
|
||||
$notice = new AccountLoginNotice();
|
||||
|
||||
$notice->createTask($user);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,7 +40,6 @@
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('home/js/content.editor.js') }}
|
||||
{{ js_include('home/js/answer.edit.js') }}
|
||||
|
||||
|
@ -39,7 +39,6 @@
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('home/js/content.editor.js') }}
|
||||
{{ js_include('home/js/answer.edit.js') }}
|
||||
|
||||
|
@ -88,7 +88,6 @@
|
||||
|
||||
{{ js_include('lib/xm-select.js') }}
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('home/js/content.editor.js') }}
|
||||
{{ js_include('home/js/article.edit.js') }}
|
||||
|
||||
|
@ -55,7 +55,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="content ke-content">{{ article.content }}</div>
|
||||
<div class="content ke-content kg-zoom">{{ article.content }}</div>
|
||||
{% if article.tags %}
|
||||
<div class="tags">
|
||||
{% for item in article.tags %}
|
||||
|
@ -23,7 +23,7 @@
|
||||
<div class="layout-content">
|
||||
<div class="article-info wrap">
|
||||
<div class="title">{{ chapter.title }}</div>
|
||||
<div class="content ke-content">
|
||||
<div class="content ke-content kg-zoom">
|
||||
{{ chapter.content }}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,18 +5,10 @@
|
||||
{% set update_url = url({'for':'home.consult.reply','id':consult.id}) %}
|
||||
|
||||
<form class="layui-form consult-form" method="post" action="{{ update_url }}">
|
||||
{% if consult.course.id is defined %}
|
||||
<div class="layui-form-item mb0">
|
||||
<label class="layui-form-label">课程</label>
|
||||
<div class="layui-form-mid">{{ consult.course.title }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if consult.chapter.id is defined %}
|
||||
<div class="layui-form-item mb0">
|
||||
<label class="layui-form-label">章节</label>
|
||||
<div class="layui-form-mid">{{ consult.chapter.title }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="layui-form-item mb0">
|
||||
<label class="layui-form-label">课程</label>
|
||||
<div class="layui-form-mid">{{ consult.course.title }}</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">问题</label>
|
||||
<div class="layui-form-mid">{{ consult.question }}</div>
|
||||
|
@ -52,7 +52,7 @@
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div class="course-details ke-content">{{ course.details }}</div>
|
||||
<div class="course-details ke-content kg-zoom">{{ course.details }}</div>
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
{{ partial('course/show_catalog') }}
|
||||
|
@ -9,20 +9,3 @@
|
||||
<button class="layui-btn layui-btn-fluid layui-btn-danger btn-buy" data-url="{{ order_url }}">立即购买</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if course.me.allow_reward == 1 %}
|
||||
<div class="sidebar">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">赞赏支持</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="sidebar-order">
|
||||
{% for reward in rewards %}
|
||||
{% set item_id = [course.id,reward.id]|join('-') %}
|
||||
{% set order_url = url({'for':'home.order.confirm'},{'item_id':item_id,'item_type':3}) %}
|
||||
<button class="layui-btn layui-btn-xs btn-reward" data-url="{{ order_url }}">{{ reward.title }}</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
@ -15,7 +15,7 @@
|
||||
<div class="layout-main">
|
||||
<div class="layout-content">
|
||||
<div class="page-info wrap">
|
||||
<div class="content ke-content">{{ help.content }}</div>
|
||||
<div class="content ke-content kg-zoom">{{ help.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout-sidebar">
|
||||
|
@ -30,7 +30,7 @@
|
||||
<a href="{{ owner_url }}" target="_blank">{{ item.owner.name }}</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="content ke-content">{{ item.content }}</div>
|
||||
<div class="content ke-content kg-zoom">{{ item.content }}</div>
|
||||
<div class="footer">
|
||||
<div class="left">
|
||||
<div class="column">
|
||||
|
@ -34,13 +34,6 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% elseif order.item_type == 3 %}
|
||||
{% set course = order.item_info.course %}
|
||||
{% set reward = order.item_info.reward %}
|
||||
<div class="order-item">
|
||||
<p>课程名称:{{ course.title }}</p>
|
||||
<p>赞赏金额:<em class="price">{{ '¥%0.2f'|format(reward.price) }}</em></p>
|
||||
</div>
|
||||
{% elseif order.item_type == 4 %}
|
||||
{% set vip = order.item_info.vip %}
|
||||
<div class="order-item">
|
||||
|
@ -42,32 +42,6 @@
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro cart_reward_card(item_info) %}
|
||||
{% set course = item_info.course %}
|
||||
{% set reward = item_info.reward %}
|
||||
{% set course_url = url({'for':'home.course.show','id':course.id}) %}
|
||||
<div class="cart-item-card">
|
||||
<div class="cover">
|
||||
<img src="{{ course.cover }}!cover_270" alt="{{ course.title }}">
|
||||
</div>
|
||||
<div class="info">
|
||||
<p><a href="{{ course_url }}" target="_blank">{{ course.title }}</a></p>
|
||||
<p>
|
||||
<span class="key">赞赏金额</span>
|
||||
<span class="price">{{ '¥%0.2f'|format(reward.price) }}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="key">难度</span>
|
||||
<span class="value">{{ level_type(course.level) }}</span>
|
||||
<span class="key">课时</span>
|
||||
<span class="value">{{ course.lesson_count }}</span>
|
||||
<span class="key">学员</span>
|
||||
<span class="value">{{ course.user_count }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro cart_vip_card(item_info) %}
|
||||
{% set vip = item_info.vip %}
|
||||
<div class="cart-item-card">
|
||||
@ -102,8 +76,6 @@
|
||||
{% for course in package.courses %}
|
||||
{{ cart_course_card(course) }}
|
||||
{% endfor %}
|
||||
{% elseif confirm.item_type == 3 %}
|
||||
{{ cart_reward_card(confirm.item_info) }}
|
||||
{% elseif confirm.item_type == 4 %}
|
||||
{{ cart_vip_card(confirm.item_info) }}
|
||||
{% endif %}
|
||||
|
@ -14,7 +14,7 @@
|
||||
<div class="layout-main">
|
||||
<div class="layout-content">
|
||||
<div class="page-info wrap">
|
||||
<div class="content ke-content">{{ page.content }}</div>
|
||||
<div class="content ke-content kg-zoom">{{ page.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout-sidebar">
|
||||
|
@ -55,7 +55,7 @@
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">物品详情</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="gift-details ke-content">{{ gift.details }}</div>
|
||||
<div class="gift-details ke-content kg-zoom">{{ gift.details }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -68,7 +68,6 @@
|
||||
|
||||
{{ js_include('lib/xm-select.js') }}
|
||||
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
|
||||
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
|
||||
{{ js_include('home/js/content.editor.js') }}
|
||||
{{ js_include('home/js/question.edit.js') }}
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="content ke-content">{{ question.content }}</div>
|
||||
<div class="content ke-content kg-zoom">{{ question.content }}</div>
|
||||
{% if question.tags %}
|
||||
<div class="tags">
|
||||
{% for item in question.tags %}
|
||||
|
@ -14,8 +14,7 @@
|
||||
{% else %}
|
||||
{{ icon_link('favicon.ico') }}
|
||||
{% endif %}
|
||||
<link rel="preload" href="//at.alicdn.com/t/font_2760791_mj6x0o9n15s.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="//at.alicdn.com/t/font_2760791_mj6x0o9n15s.css">
|
||||
{{ css_link('lib/iconfont/iconfont.css') }}
|
||||
{{ css_link('lib/layui/css/layui.css') }}
|
||||
{{ css_link('home/css/common.css') }}
|
||||
{% block link_css %}{% endblock %}
|
||||
|
@ -16,7 +16,7 @@ class AppInfo
|
||||
|
||||
protected $link = 'https://www.koogua.com';
|
||||
|
||||
protected $version = '1.7.0';
|
||||
protected $version = '1.7.1';
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
|
@ -39,82 +39,113 @@ class FileInfo
|
||||
|
||||
public static function isSecure($mime)
|
||||
{
|
||||
return in_array($mime, self::getMimeTypes());
|
||||
foreach (self::getMimeTypes() as $mimeTypes) {
|
||||
if (in_array($mime, $mimeTypes)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getMimeType($file)
|
||||
{
|
||||
$info = new \finfo(FILEINFO_MIME_TYPE);
|
||||
|
||||
return $info->file($file);
|
||||
return mime_content_type($file);
|
||||
}
|
||||
|
||||
public static function getMimeTypeByExt($ext)
|
||||
{
|
||||
$mimeTypes = self::getMimeTypes();
|
||||
|
||||
return $mimeTypes[$ext] ?? null;
|
||||
return $mimeTypes[$ext] ? $mimeTypes[$ext][0] : '';
|
||||
}
|
||||
|
||||
public static function getMimeTypes()
|
||||
{
|
||||
return [
|
||||
'aac' => 'audio/aac',
|
||||
'ogg' => 'audio/ogg',
|
||||
'wav' => 'audio/wav',
|
||||
'mp3' => 'audio/mpeg',
|
||||
'weba' => 'audio/webm',
|
||||
'm4a' => 'audio/x-m4a',
|
||||
'wma' => 'audio/x-ms-wma',
|
||||
'aac' => ['audio/aac'],
|
||||
'ogg' => ['audio/ogg'],
|
||||
'wav' => ['audio/wav'],
|
||||
'mp3' => ['audio/mpeg'],
|
||||
'weba' => ['audio/webm'],
|
||||
'm4a' => ['audio/x-m4a'],
|
||||
'wma' => ['audio/x-ms-wma'],
|
||||
|
||||
'mp4' => 'video/mp4',
|
||||
'3gp' => 'video/3gpp',
|
||||
'mpeg' => 'video/mpeg',
|
||||
'webm' => 'video/webm',
|
||||
'flv' => 'video/x-flv',
|
||||
'avi' => 'video/x-msvideo',
|
||||
'mkv' => 'video/x-matroska',
|
||||
'wmv' => 'video/x-ms-wmv',
|
||||
'mp4' => ['video/mp4'],
|
||||
'3gp' => ['video/3gpp'],
|
||||
'mpeg' => ['video/mpeg'],
|
||||
'webm' => ['video/webm'],
|
||||
'flv' => ['video/x-flv'],
|
||||
'avi' => ['video/x-msvideo'],
|
||||
'mkv' => ['video/x-matroska'],
|
||||
'wmv' => ['video/x-ms-wmv'],
|
||||
|
||||
'gif' => 'image/gif',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'png' => 'image/png',
|
||||
'webp' => 'image/webp',
|
||||
'bmp' => 'image/bmp',
|
||||
'ico' => 'image/x-icon',
|
||||
'tif' => 'image/tiff',
|
||||
'tiff' => 'image/tiff',
|
||||
'svg' => 'image/svg+xml',
|
||||
'psd' => 'image/vnd.adobe.photoshop',
|
||||
'gif' => ['image/gif'],
|
||||
'jpeg' => ['image/jpeg'],
|
||||
'jpg' => ['image/jpeg'],
|
||||
'png' => ['image/png'],
|
||||
'webp' => ['image/webp'],
|
||||
'bmp' => ['image/bmp'],
|
||||
'ico' => ['image/x-icon'],
|
||||
'tif' => ['image/tiff'],
|
||||
'tiff' => ['image/tiff'],
|
||||
'svg' => ['image/svg+xml'],
|
||||
'psd' => ['image/vnd.adobe.photoshop'],
|
||||
|
||||
'rar' => 'application/vnd.rar',
|
||||
'tar' => 'application/x-tar',
|
||||
'7z' => 'application/x-7z-compressed',
|
||||
'bz' => 'application/x-bzip',
|
||||
'bz2' => 'application/x-bzip2',
|
||||
'gz' => 'application/gzip',
|
||||
'zip' => 'application/zip',
|
||||
'rar' => ['application/x-rar', 'application/x-rar-compressed', 'application/vnd.rar'],
|
||||
'zip' => ['application/zip', 'application/x-zip-compressed', 'multipart/x-zip'],
|
||||
'tar' => ['application/x-tar'],
|
||||
'7z' => ['application/x-7z-compressed'],
|
||||
'bz' => ['application/x-bzip'],
|
||||
'bz2' => ['application/x-bzip2'],
|
||||
'gz' => ['application/gzip'],
|
||||
|
||||
'txt' => 'text/plain',
|
||||
'csv' => 'text/csv',
|
||||
'json' => 'application/json',
|
||||
'xml' => 'application/xml',
|
||||
'txt' => ['text/plain'],
|
||||
'csv' => ['text/csv'],
|
||||
'pdf' => ['application/pdf'],
|
||||
'json' => ['application/json'],
|
||||
'xml' => ['application/xml'],
|
||||
|
||||
'pdf' => 'application/pdf',
|
||||
'doc' => 'application/msword',
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'vsd' => 'application/vnd.visio',
|
||||
'rtf' => 'application/rtf',
|
||||
'doc' => ['application/msword', 'application/CDFV2'],
|
||||
'docm' => ['application/vnd.ms-word.document.macroenabled.12'],
|
||||
'docx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
|
||||
'dot' => ['application/msword'],
|
||||
'dotm' => ['application/vnd.ms-word.template.macroenabled.12'],
|
||||
'dotx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.template'],
|
||||
|
||||
'ttf' => 'font/ttf',
|
||||
'woff' => 'font/woff',
|
||||
'woff2' => 'font/woff2',
|
||||
'ppt' => ['application/vnd.ms-powerpoint'],
|
||||
'pptm' => ['application/vnd.ms-powerpoint.presentation.macroenabled.12'],
|
||||
'pptx' => ['application/vnd.openxmlformats-officedocument.presentationml.presentation'],
|
||||
'pot' => ['application/vnd.ms-powerpoint'],
|
||||
'potm' => ['application/vnd.ms-powerpoint.template.macroenabled.12'],
|
||||
'potx' => ['application/vnd.openxmlformats-officedocument.presentationml.template'],
|
||||
'pps' => ['application/vnd.ms-powerpoint'],
|
||||
'ppsm' => ['application/vnd.ms-powerpoint.slideshow.macroenabled.12'],
|
||||
'ppsx' => ['application/vnd.openxmlformats-officedocument.presentationml.slideshow'],
|
||||
|
||||
'xls' => ['application/vnd.ms-excel'],
|
||||
'xlsb' => ['application/vnd.ms-excel.sheet.binary.macroenabled.12'],
|
||||
'xlsm' => ['application/vnd.ms-excel.sheet.macroenabled.12'],
|
||||
'xlsx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
|
||||
'xlt' => ['application/vnd.ms-excel'],
|
||||
'xltm' => ['application/vnd.ms-excel.template.macroenabled.12'],
|
||||
'xltx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.template'],
|
||||
|
||||
'wps' => ['application/msword'],
|
||||
'wpt' => ['application/msword'],
|
||||
'dpt' => ['application/vnd.ms-powerpoint'],
|
||||
'dps' => ['application/vnd.ms-powerpoint'],
|
||||
'et' => ['application/vnd.ms-excel'],
|
||||
'ett' => ['application/vnd.ms-excel'],
|
||||
|
||||
'ofd' => ['application/octet-stream'],
|
||||
'swf' => ['application/x-shockwave-flash'],
|
||||
'vsd' => ['application/vnd.visio'],
|
||||
'rtf' => ['application/rtf'],
|
||||
|
||||
'ttf' => ['font/ttf'],
|
||||
'woff' => ['font/woff'],
|
||||
'woff2' => ['font/woff2'],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ class Chapter extends Model
|
||||
* 图文扩展属性
|
||||
*/
|
||||
protected $_read_attrs = [
|
||||
'format' => 'html',
|
||||
'duration' => 0,
|
||||
'word_count' => 0,
|
||||
];
|
||||
|
@ -15,7 +15,9 @@ class Connect extends Model
|
||||
const PROVIDER_QQ = 1; // QQ
|
||||
const PROVIDER_WEIXIN = 2; // 微信扫码
|
||||
const PROVIDER_WEIBO = 3; // 新浪微博
|
||||
const PROVIDER_WECHAT = 4; // 公众号网页
|
||||
const PROVIDER_WECHAT_OA = 4; // 微信公众号
|
||||
const PROVIDER_WECHAT_MINI = 5; // 微信小程序
|
||||
|
||||
|
||||
/**
|
||||
* 主键编号
|
||||
|
@ -40,13 +40,6 @@ class Consult extends Model
|
||||
*/
|
||||
public $course_id = 0;
|
||||
|
||||
/**
|
||||
* 章节编号
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $chapter_id = 0;
|
||||
|
||||
/**
|
||||
* 提主编号
|
||||
*
|
||||
|
@ -17,7 +17,7 @@ class Order extends Model
|
||||
*/
|
||||
const ITEM_COURSE = 1; // 课程
|
||||
const ITEM_PACKAGE = 2; // 套餐
|
||||
const ITEM_REWARD = 3; // 赞赏
|
||||
const ITEM_REWARD = 3; // 赞赏(已弃用)
|
||||
const ITEM_VIP = 4; // 会员
|
||||
const ITEM_TEST = 99; // 测试
|
||||
|
||||
@ -190,7 +190,6 @@ class Order extends Model
|
||||
return [
|
||||
self::ITEM_COURSE => '课程',
|
||||
self::ITEM_PACKAGE => '套餐',
|
||||
self::ITEM_REWARD => '赞赏',
|
||||
self::ITEM_VIP => '会员',
|
||||
self::ITEM_TEST => '测试',
|
||||
];
|
||||
|
@ -1,89 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Phalcon\Mvc\Model\Behavior\SoftDelete;
|
||||
|
||||
class Reward extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* 主键编号
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $id = 0;
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $title = '';
|
||||
|
||||
/**
|
||||
* 价格
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $price = 0.00;
|
||||
|
||||
/**
|
||||
* 删除标识
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $deleted = 0;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $create_time = 0;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $update_time = 0;
|
||||
|
||||
public function getSource(): string
|
||||
{
|
||||
return 'kg_reward';
|
||||
}
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$this->addBehavior(
|
||||
new SoftDelete([
|
||||
'field' => 'deleted',
|
||||
'value' => 1,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterFetch()
|
||||
{
|
||||
$this->price = (float)$this->price;
|
||||
}
|
||||
|
||||
}
|
@ -67,4 +67,17 @@ class Connect extends Repository
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param int $provider
|
||||
* @return ConnectModel|Model|bool
|
||||
*/
|
||||
public function findByUserId($userId, $provider)
|
||||
{
|
||||
return ConnectModel::findFirst([
|
||||
'conditions' => 'user_id = ?1 AND provider = ?2 AND deleted = 0',
|
||||
'bind' => [1 => $userId, 2 => $provider],
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Repos;
|
||||
|
||||
use App\Models\Reward as RewardModel;
|
||||
use Phalcon\Mvc\Model;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class Reward extends Repository
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $where
|
||||
* @return ResultsetInterface|Resultset|RewardModel[]
|
||||
*/
|
||||
public function findAll($where = [])
|
||||
{
|
||||
$query = RewardModel::query();
|
||||
|
||||
$query->where('1 = 1');
|
||||
|
||||
if (isset($where['deleted'])) {
|
||||
$query->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]);
|
||||
}
|
||||
|
||||
return $query->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return RewardModel|Model|bool
|
||||
*/
|
||||
public function findById($id)
|
||||
{
|
||||
return RewardModel::findFirst([
|
||||
'conditions' => 'id = :id:',
|
||||
'bind' => ['id' => $id],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $ids
|
||||
* @param array|string $columns
|
||||
* @return ResultsetInterface|Resultset|RewardModel[]
|
||||
*/
|
||||
public function findByIds($ids, $columns = '*')
|
||||
{
|
||||
return RewardModel::query()
|
||||
->columns($columns)
|
||||
->inWhere('id', $ids)
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
@ -45,8 +45,8 @@ class CourseInfo extends LogicService
|
||||
{
|
||||
$me = [
|
||||
'plan_id' => 0,
|
||||
'allow_study' => 0,
|
||||
'allow_order' => 0,
|
||||
'allow_reward' => 0,
|
||||
'progress' => 0,
|
||||
'logged' => 0,
|
||||
'joined' => 0,
|
||||
@ -66,14 +66,6 @@ class CourseInfo extends LogicService
|
||||
$caseModel = $course->attrs['end_date'] < date('Y-m-d');
|
||||
}
|
||||
|
||||
if ($caseOwned && $casePrice && $caseModel) {
|
||||
$me['allow_order'] = 1;
|
||||
}
|
||||
|
||||
if ($course->market_price == 0) {
|
||||
$me['allow_reward'] = 1;
|
||||
}
|
||||
|
||||
if ($user->id > 0) {
|
||||
|
||||
$me['logged'] = 1;
|
||||
@ -82,8 +74,8 @@ class CourseInfo extends LogicService
|
||||
$me['allow_order'] = 1;
|
||||
}
|
||||
|
||||
if ($course->market_price == 0) {
|
||||
$me['allow_reward'] = 1;
|
||||
if ($this->ownedCourse && $course->model != CourseModel::MODEL_OFFLINE) {
|
||||
$me['allow_study'] = 1;
|
||||
}
|
||||
|
||||
if ($this->joinedCourse) {
|
||||
|
@ -40,10 +40,10 @@ class AccountLogin extends WeChatNotice
|
||||
$params = [
|
||||
'first' => $first,
|
||||
'remark' => $remark,
|
||||
'keyword1' => $loginUser,
|
||||
'keyword2' => $loginTime,
|
||||
'keyword3' => $loginRegion,
|
||||
'keyword4' => $loginIp,
|
||||
'thing3' => $loginUser,
|
||||
'time2' => $loginTime,
|
||||
'thing7' => $loginRegion,
|
||||
'character_string8' => $loginIp,
|
||||
];
|
||||
|
||||
$templateId = $this->getTemplateId($this->templateCode);
|
||||
|
@ -30,9 +30,9 @@ class GoodsDeliver extends WeChatNotice
|
||||
$params = [
|
||||
'first' => $first,
|
||||
'remark' => $remark,
|
||||
'keyword1' => $params['order_sn'],
|
||||
'keyword2' => $params['goods_name'],
|
||||
'keyword3' => date('Y-m-d H:i', $params['deliver_time']),
|
||||
'character_string12' => $params['order_sn'],
|
||||
'thing14' => $params['goods_name'],
|
||||
'time3' => date('Y-m-d H:i', $params['deliver_time']),
|
||||
];
|
||||
|
||||
$templateId = $this->getTemplateId($this->templateCode);
|
||||
|
@ -30,9 +30,9 @@ class OrderFinish extends WeChatNotice
|
||||
$params = [
|
||||
'first' => $first,
|
||||
'remark' => $remark,
|
||||
'keyword1' => sprintf('%s元', $params['order']['amount']),
|
||||
'keyword2' => $params['order']['subject'],
|
||||
'keyword3' => date('Y-m-d H:i', $params['order']['update_time']),
|
||||
'amount3' => sprintf('%s元', $params['order']['amount']),
|
||||
'thing1' => $params['order']['subject'],
|
||||
'time4' => date('Y-m-d H:i', $params['order']['update_time']),
|
||||
];
|
||||
|
||||
$templateId = $this->getTemplateId($this->templateCode);
|
||||
|
@ -30,10 +30,10 @@ class RefundFinish extends WeChatNotice
|
||||
$params = [
|
||||
'first' => $first,
|
||||
'remark' => $remark,
|
||||
'keyword1' => $params['refund']['sn'],
|
||||
'keyword2' => $params['refund']['subject'],
|
||||
'keyword3' => sprintf('%s元', $params['refund']['amount']),
|
||||
'keyword4' => date('Y-m-d H:i', $params['refund']['update_time']),
|
||||
'character_string5' => $params['refund']['sn'],
|
||||
'thing1' => $params['refund']['subject'],
|
||||
'amount2' => sprintf('%s元', $params['refund']['amount']),
|
||||
'time4' => date('Y-m-d H:i', $params['refund']['update_time']),
|
||||
];
|
||||
|
||||
$templateId = $this->getTemplateId($this->templateCode);
|
||||
|
@ -10,7 +10,6 @@ namespace App\Services\Logic\Order;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\Order as OrderModel;
|
||||
use App\Models\Package as PackageModel;
|
||||
use App\Models\Reward as RewardModel;
|
||||
use App\Models\Vip as VipModel;
|
||||
use App\Repos\Package as PackageRepo;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
@ -66,20 +65,6 @@ class OrderConfirm extends LogicService
|
||||
$result['total_amount'] = $vip->price;
|
||||
$result['pay_amount'] = $vip->price;
|
||||
$result['discount_amount'] = 0;
|
||||
|
||||
} elseif ($itemType == OrderModel::ITEM_REWARD) {
|
||||
|
||||
list($courseId, $rewardId) = explode('-', $itemId);
|
||||
|
||||
$course = $validator->checkCourse($courseId);
|
||||
$reward = $validator->checkReward($rewardId);
|
||||
|
||||
$result['item_info']['course'] = $this->handleCourseInfo($course);
|
||||
$result['item_info']['reward'] = $this->handleRewardInfo($reward);
|
||||
|
||||
$result['total_amount'] = $reward->price;
|
||||
$result['pay_amount'] = $reward->price;
|
||||
$result['discount_amount'] = 0;
|
||||
}
|
||||
|
||||
$validator->checkAmount($result['pay_amount']);
|
||||
@ -123,15 +108,6 @@ class OrderConfirm extends LogicService
|
||||
];
|
||||
}
|
||||
|
||||
protected function handleRewardInfo(RewardModel $reward)
|
||||
{
|
||||
return [
|
||||
'id' => $reward->id,
|
||||
'title' => $reward->title,
|
||||
'price' => $reward->price,
|
||||
];
|
||||
}
|
||||
|
||||
protected function formatCourseInfo(CourseModel $course)
|
||||
{
|
||||
return [
|
||||
|
@ -10,7 +10,6 @@ namespace App\Services\Logic\Order;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\Order as OrderModel;
|
||||
use App\Models\Package as PackageModel;
|
||||
use App\Models\Reward as RewardModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Models\Vip as VipModel;
|
||||
use App\Repos\Package as PackageRepo;
|
||||
@ -69,19 +68,6 @@ class OrderCreate extends LogicService
|
||||
|
||||
$order = $this->createPackageOrder($package, $user);
|
||||
|
||||
} elseif ($post['item_type'] == OrderModel::ITEM_REWARD) {
|
||||
|
||||
list($courseId, $rewardId) = explode('-', $post['item_id']);
|
||||
|
||||
$course = $orderValidator->checkCourse($courseId);
|
||||
$reward = $orderValidator->checkReward($rewardId);
|
||||
|
||||
$this->amount = $reward->price;
|
||||
|
||||
$orderValidator->checkAmount($this->amount);
|
||||
|
||||
$order = $this->createRewardOrder($course, $reward, $user);
|
||||
|
||||
} elseif ($post['item_type'] == OrderModel::ITEM_VIP) {
|
||||
|
||||
$vip = $orderValidator->checkVip($post['item_id']);
|
||||
@ -186,33 +172,6 @@ class OrderCreate extends LogicService
|
||||
return $order;
|
||||
}
|
||||
|
||||
protected function createRewardOrder(CourseModel $course, RewardModel $reward, UserModel $user)
|
||||
{
|
||||
$itemInfo = [
|
||||
'course' => $this->handleCourseInfo($course),
|
||||
'reward' => [
|
||||
'id' => $reward->id,
|
||||
'title' => $reward->title,
|
||||
'price' => $reward->price,
|
||||
]
|
||||
];
|
||||
|
||||
$order = new OrderModel();
|
||||
|
||||
$order->owner_id = $user->id;
|
||||
$order->item_id = $course->id;
|
||||
$order->item_type = OrderModel::ITEM_REWARD;
|
||||
$order->item_info = $itemInfo;
|
||||
$order->client_type = $this->getClientType();
|
||||
$order->client_ip = $this->getClientIp();
|
||||
$order->subject = "赞赏 - {$course->title}";
|
||||
$order->amount = $this->amount;
|
||||
|
||||
$order->create();
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
protected function handleCourseInfo(CourseModel $course)
|
||||
{
|
||||
$studyExpiryTime = strtotime("+{$course->study_expiry} months");
|
||||
|
@ -140,9 +140,6 @@ class OrderInfo extends LogicService
|
||||
case OrderModel::ITEM_VIP:
|
||||
$result = $this->handleVipInfo($itemInfo);
|
||||
break;
|
||||
case OrderModel::ITEM_REWARD:
|
||||
$result = $this->handleRewardInfo($itemInfo);
|
||||
break;
|
||||
case OrderModel::ITEM_TEST:
|
||||
$result = $this->handleTestInfo($itemInfo);
|
||||
break;
|
||||
@ -174,11 +171,6 @@ class OrderInfo extends LogicService
|
||||
return $itemInfo;
|
||||
}
|
||||
|
||||
protected function handleRewardInfo($itemInfo)
|
||||
{
|
||||
return $itemInfo;
|
||||
}
|
||||
|
||||
protected function handleTestInfo($itemInfo)
|
||||
{
|
||||
return $itemInfo;
|
||||
|
@ -1,39 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Services\Logic\Reward;
|
||||
|
||||
use App\Repos\Reward as RewardRepo;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
|
||||
class OptionList extends LogicService
|
||||
{
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$rewardRepo = new RewardRepo();
|
||||
|
||||
$rewards = $rewardRepo->findAll(['deleted' => 0]);
|
||||
|
||||
if ($rewards->count() == 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($rewards as $reward) {
|
||||
$result[] = [
|
||||
'id' => $reward->id,
|
||||
'title' => $reward->title,
|
||||
'price' => $reward->price,
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
@ -116,11 +116,6 @@ class FullH5Url extends AppService
|
||||
return $this->getFullUrl('/question/info', ['id' => $id]);
|
||||
}
|
||||
|
||||
public function getAnswerInfoUrl($id)
|
||||
{
|
||||
return $this->getFullUrl('/answer/info', ['id' => $id]);
|
||||
}
|
||||
|
||||
public function getTopicInfoUrl($id)
|
||||
{
|
||||
return $this->getFullUrl('/topic/info', ['id' => $id]);
|
||||
|
@ -48,6 +48,8 @@ class ShareUrl extends AppService
|
||||
$result = $this->getArticleUrl($id);
|
||||
} elseif ($type == 'page') {
|
||||
$result = $this->getPageUrl($id);
|
||||
} elseif ($type == 'help') {
|
||||
$result = $this->getHelpUrl($id);
|
||||
} elseif ($type == 'question') {
|
||||
$result = $this->getQuestionUrl($id);
|
||||
} elseif ($type == 'course') {
|
||||
|
@ -48,14 +48,12 @@ class ConsultList extends LogicService
|
||||
$consults = $pager->items->toArray();
|
||||
|
||||
$courses = $builder->getCourses($consults);
|
||||
$chapters = $builder->getChapters($consults);
|
||||
|
||||
$items = [];
|
||||
|
||||
foreach ($consults as $consult) {
|
||||
|
||||
$course = $courses[$consult['course_id']] ?? new \stdClass();
|
||||
$chapter = $chapters[$consult['chapter_id']] ?? new \stdClass();
|
||||
|
||||
$items[] = [
|
||||
'id' => $consult['id'],
|
||||
@ -66,7 +64,6 @@ class ConsultList extends LogicService
|
||||
'reply_time' => $consult['reply_time'],
|
||||
'create_time' => $consult['create_time'],
|
||||
'course' => $course,
|
||||
'chapter' => $chapter,
|
||||
];
|
||||
}
|
||||
|
||||
|
317
app/Services/Logic/WeChat/OfficialAccount.php
Normal file
317
app/Services/Logic/WeChat/OfficialAccount.php
Normal file
@ -0,0 +1,317 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Services\Logic\WeChat;
|
||||
|
||||
use App\Models\Connect as ConnectModel;
|
||||
use App\Repos\Connect as ConnectRepo;
|
||||
use App\Services\Service as AppService;
|
||||
use App\Services\WeChat as WeChatService;
|
||||
use EasyWeChat\Kernel\Messages\Text as TextMessage;
|
||||
use Phalcon\Text;
|
||||
|
||||
class OfficialAccount extends AppService
|
||||
{
|
||||
|
||||
/**
|
||||
* 二维码场景类型
|
||||
*/
|
||||
const QR_SCENE_LOGIN = 'login';
|
||||
const QR_SCENE_SUBSCRIBE = 'subscribe';
|
||||
|
||||
public function getOfficialAccount()
|
||||
{
|
||||
$service = new WeChatService();
|
||||
|
||||
return $service->getOfficialAccount();
|
||||
}
|
||||
|
||||
public function createSubscribeQrCode()
|
||||
{
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$app = $this->getOfficialAccount();
|
||||
|
||||
$sceneValue = sprintf('%s%s', self::QR_SCENE_SUBSCRIBE, $user->id);
|
||||
|
||||
$result = $app->qrcode->temporary($sceneValue);
|
||||
|
||||
$url = $app->qrcode->url($result['ticket']);
|
||||
|
||||
return ['url' => $url];
|
||||
}
|
||||
|
||||
public function createLoginQrCode()
|
||||
{
|
||||
$app = $this->getOfficialAccount();
|
||||
|
||||
$ticket = Text::random(0, 16);
|
||||
|
||||
$sceneValue = sprintf('%s%s', self::QR_SCENE_LOGIN, $ticket);
|
||||
|
||||
$result = $app->qrcode->temporary($sceneValue);
|
||||
|
||||
$keyName = $this->getLoginCacheKey($ticket);
|
||||
|
||||
$content = [
|
||||
'action' => '',
|
||||
'open_id' => '',
|
||||
];
|
||||
|
||||
$this->getCache()->save($keyName, $content, 30 * 60);
|
||||
|
||||
$url = $app->qrcode->url($result['ticket']);
|
||||
|
||||
return [
|
||||
'ticket' => $ticket,
|
||||
'url' => $url,
|
||||
];
|
||||
}
|
||||
|
||||
public function getLoginStatus($ticket)
|
||||
{
|
||||
$keyName = $this->getLoginCacheKey($ticket);
|
||||
|
||||
return $this->getCache()->get($keyName);
|
||||
}
|
||||
|
||||
public function getSubscribeStatus()
|
||||
{
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$connectRepo = new ConnectRepo();
|
||||
|
||||
$connect = $connectRepo->findByUserId($user->id, ConnectModel::PROVIDER_WECHAT_OA);
|
||||
|
||||
return $connect ? 1 : 0;
|
||||
}
|
||||
|
||||
public function getLoginOpenId($ticket)
|
||||
{
|
||||
$keyName = $this->getLoginCacheKey($ticket);
|
||||
|
||||
$content = $this->getCache()->get($keyName);
|
||||
|
||||
return $content['open_id'] ?? null;
|
||||
}
|
||||
|
||||
public function getLoginCacheKey($key)
|
||||
{
|
||||
return "wechat_oa_login:{$key}";
|
||||
}
|
||||
|
||||
public function handleNotify($message)
|
||||
{
|
||||
$logger = $this->getWeChatLogger();
|
||||
|
||||
$logger->debug('Received Message: ' . json_encode($message));
|
||||
|
||||
switch ($message['MsgType']) {
|
||||
case 'event':
|
||||
switch ($message['Event']) {
|
||||
case 'subscribe':
|
||||
return $this->handleSubscribeEvent($message);
|
||||
case 'unsubscribe':
|
||||
return $this->handleUnsubscribeEvent($message);
|
||||
case 'SCAN':
|
||||
return $this->handleScanEvent($message);
|
||||
case 'CLICK':
|
||||
return $this->handleClickEvent($message);
|
||||
case 'VIEW':
|
||||
return $this->handleViewEvent($message);
|
||||
case 'LOCATION':
|
||||
return $this->handleLocationEvent($message);
|
||||
default:
|
||||
return $this->noMatchReply();
|
||||
}
|
||||
case 'text':
|
||||
return $this->handleTextReply($message);
|
||||
case 'image':
|
||||
return $this->handleImageReply($message);
|
||||
case 'voice':
|
||||
return $this->handleVoiceReply($message);
|
||||
case 'video':
|
||||
return $this->handleVideoReply($message);
|
||||
case 'shortvideo':
|
||||
return $this->handleShortVideoReply($message);
|
||||
case 'location':
|
||||
return $this->handleLocationReply($message);
|
||||
case 'link':
|
||||
return $this->handleLinkReply($message);
|
||||
default:
|
||||
return $this->noMatchReply();
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleSubscribeEvent($message)
|
||||
{
|
||||
$openId = $message['FromUserName'] ?? '';
|
||||
|
||||
if (empty($openId)) return null;
|
||||
|
||||
return new TextMessage('开心呀,我们又多了一个小伙伴!');
|
||||
}
|
||||
|
||||
protected function handleUnsubscribeEvent($message)
|
||||
{
|
||||
$openId = $message['FromUserName'] ?? '';
|
||||
|
||||
if (empty($openId)) return null;
|
||||
|
||||
$connectRepo = new ConnectRepo();
|
||||
|
||||
$connect = $connectRepo->findByOpenId($openId, ConnectModel::PROVIDER_WECHAT_OA);
|
||||
|
||||
if ($connect) {
|
||||
$connect->deleted = 1;
|
||||
$connect->update();
|
||||
}
|
||||
|
||||
return new TextMessage('伤心呀,我们又少了一个小伙伴!');
|
||||
}
|
||||
|
||||
protected function handleScanEvent($message)
|
||||
{
|
||||
$openId = $message['FromUserName'] ?? '';
|
||||
$eventKey = $message['EventKey'] ?? '';
|
||||
|
||||
if (Text::startsWith($eventKey, self::QR_SCENE_LOGIN)) {
|
||||
return $this->handleLoginScanEvent($eventKey, $openId);
|
||||
} elseif (Text::startsWith($eventKey, self::QR_SCENE_SUBSCRIBE)) {
|
||||
return $this->handleSubscribeScanEvent($eventKey, $openId);
|
||||
}
|
||||
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleLoginScanEvent($eventKey, $openId)
|
||||
{
|
||||
$ticket = str_replace(self::QR_SCENE_LOGIN, '', $eventKey);
|
||||
|
||||
if (empty($ticket) || empty($openId)) return null;
|
||||
|
||||
$connectRepo = new ConnectRepo();
|
||||
|
||||
$connect = $connectRepo->findByOpenId($openId, ConnectModel::PROVIDER_WECHAT_OA);
|
||||
|
||||
$keyName = $this->getLoginCacheKey($ticket);
|
||||
|
||||
$cache = $this->getCache();
|
||||
|
||||
$content = [
|
||||
'action' => $connect ? 'login' : 'bind',
|
||||
'open_id' => $openId,
|
||||
];
|
||||
|
||||
$cache->save($keyName, $content, 30 * 60);
|
||||
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleSubscribeScanEvent($eventKey, $openId)
|
||||
{
|
||||
$userId = str_replace(self::QR_SCENE_SUBSCRIBE, '', $eventKey);
|
||||
|
||||
if (empty($userId) || empty($openId)) return null;
|
||||
|
||||
$userInfo = $this->getUserInfo($openId);
|
||||
|
||||
$unionId = $userInfo['unionid'] ?: '';
|
||||
|
||||
$connectRepo = new ConnectRepo();
|
||||
|
||||
$connect = $connectRepo->findByOpenId($openId, ConnectModel::PROVIDER_WECHAT_OA);
|
||||
|
||||
if ($connect) return null;
|
||||
|
||||
$connect = new ConnectModel();
|
||||
|
||||
$connect->user_id = $userId;
|
||||
$connect->open_id = $openId;
|
||||
$connect->union_id = $unionId;
|
||||
$connect->provider = ConnectModel::PROVIDER_WECHAT_OA;
|
||||
|
||||
$connect->create();
|
||||
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleClickEvent($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleViewEvent($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleLocationEvent($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleTextReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleImageReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleVoiceReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleVideoReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleShortVideoReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleLocationReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleLinkReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function emptyReply()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function noMatchReply()
|
||||
{
|
||||
return new TextMessage('没有匹配的服务哦!');
|
||||
}
|
||||
|
||||
protected function getUserInfo($openId)
|
||||
{
|
||||
$app = $this->getOfficialAccount();
|
||||
|
||||
return $app->user->get($openId);
|
||||
}
|
||||
|
||||
protected function getWeChatLogger()
|
||||
{
|
||||
$service = new WeChatService();
|
||||
|
||||
return $service->logger;
|
||||
}
|
||||
|
||||
}
|
@ -91,7 +91,7 @@ class WeChat extends OAuth
|
||||
$userInfo['name'] = $data['nickname'];
|
||||
$userInfo['avatar'] = $data['headimgurl'];
|
||||
$userInfo['unionid'] = $data['unionid'] ?? '';
|
||||
$userInfo['provider'] = ConnectModel::PROVIDER_WECHAT;
|
||||
$userInfo['provider'] = ConnectModel::PROVIDER_WECHAT_OA;
|
||||
|
||||
return $userInfo;
|
||||
}
|
||||
|
@ -33,9 +33,6 @@ class Refund extends Service
|
||||
case OrderModel::ITEM_PACKAGE:
|
||||
$result = $this->previewPackageRefund($order);
|
||||
break;
|
||||
case OrderModel::ITEM_REWARD:
|
||||
$result = $this->previewRewardRefund($order);
|
||||
break;
|
||||
case OrderModel::ITEM_VIP:
|
||||
$result = $this->previewVipRefund($order);
|
||||
break;
|
||||
@ -121,11 +118,6 @@ class Refund extends Service
|
||||
];
|
||||
}
|
||||
|
||||
protected function previewRewardRefund(OrderModel $order)
|
||||
{
|
||||
return $this->previewOtherRefund($order);
|
||||
}
|
||||
|
||||
protected function previewVipRefund(OrderModel $order)
|
||||
{
|
||||
return $this->previewOtherRefund($order);
|
||||
|
@ -258,4 +258,25 @@ class Course extends Validator
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function checkPublishAbility(CourseModel $course)
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$lessons = $courseRepo->findLessons($course->id);
|
||||
|
||||
$ability = false;
|
||||
|
||||
if ($lessons->count() > 0) {
|
||||
foreach ($lessons as $lesson) {
|
||||
if ($lesson->published == 1) {
|
||||
$ability = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$ability) {
|
||||
throw new BadRequestException('course.content_not_ready');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ use App\Models\Trade as TradeModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\Order as OrderRepo;
|
||||
use App\Repos\Package as PackageRepo;
|
||||
use App\Repos\Reward as RewardRepo;
|
||||
use App\Repos\Vip as VipRepo;
|
||||
|
||||
class Order extends Validator
|
||||
@ -101,24 +100,11 @@ class Order extends Validator
|
||||
return $vip;
|
||||
}
|
||||
|
||||
public function checkReward($itemId)
|
||||
{
|
||||
$rewardRepo = new RewardRepo();
|
||||
|
||||
$reward = $rewardRepo->findById($itemId);
|
||||
|
||||
if (!$reward) {
|
||||
throw new BadRequestException('order.item_not_found');
|
||||
}
|
||||
|
||||
return $reward;
|
||||
}
|
||||
|
||||
public function checkAmount($amount)
|
||||
{
|
||||
$value = $this->filter->sanitize($amount, ['trim', 'float']);
|
||||
|
||||
if ($value < 0.01 || $value > 10000) {
|
||||
if ($value < 0.01 || $value > 100000) {
|
||||
throw new BadRequestException('order.invalid_pay_amount');
|
||||
}
|
||||
|
||||
|
@ -1,57 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Validators;
|
||||
|
||||
use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Repos\Reward as RewardRepo;
|
||||
|
||||
class Reward extends Validator
|
||||
{
|
||||
|
||||
public function checkReward($id)
|
||||
{
|
||||
$rewardRepo = new RewardRepo();
|
||||
|
||||
$reward = $rewardRepo->findById($id);
|
||||
|
||||
if (!$reward) {
|
||||
throw new BadRequestException('reward.not_found');
|
||||
}
|
||||
|
||||
return $reward;
|
||||
}
|
||||
|
||||
public function checkTitle($title)
|
||||
{
|
||||
$value = $this->filter->sanitize($title, ['trim', 'string']);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length < 2) {
|
||||
throw new BadRequestException('reward.title_too_short');
|
||||
}
|
||||
|
||||
if ($length > 30) {
|
||||
throw new BadRequestException('reward.title_too_long');
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function checkPrice($price)
|
||||
{
|
||||
$value = $this->filter->sanitize($price, ['trim', 'float']);
|
||||
|
||||
if ($value < 0.01 || $value > 10000) {
|
||||
throw new BadRequestException('reward.invalid_price');
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
29
app/Validators/WeChatOfficialAccount.php
Normal file
29
app/Validators/WeChatOfficialAccount.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Validators;
|
||||
|
||||
use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Services\Logic\WeChat\OfficialAccount as WeChatOfficeAccount;
|
||||
|
||||
class WeChatOfficialAccount extends Validator
|
||||
{
|
||||
|
||||
public function checkLoginOpenId($ticket)
|
||||
{
|
||||
$service = new WeChatOfficeAccount();
|
||||
|
||||
$openId = $service->getLoginOpenId($ticket);
|
||||
|
||||
if (!$openId) {
|
||||
throw new BadRequestException('wechat_oa.invalid_login_ticket');
|
||||
}
|
||||
|
||||
return $openId;
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user