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

去掉第三方登录

增强关闭交易健壮性
去除.phalcon目录
This commit is contained in:
xiaochong0302 2020-04-18 19:51:43 +08:00
parent 3c906cb6c7
commit 93b0071c87
32 changed files with 200 additions and 549 deletions

View File

View File

@ -23,17 +23,19 @@ class CourseList extends Builder
$result[] = [
'id' => $course['id'],
'model' => $course['model'],
'title' => $course['title'],
'summary' => $course['summary'],
'cover' => $course['cover'],
'summary' => $course['summary'],
'categories' => $course['categories'],
'market_price' => (float)$course['market_price'],
'vip_price' => (float)$course['vip_price'],
'expiry' => $course['expiry'],
'study_expiry' => $course->study_expiry,
'refund_expiry' => $course->refund_expiry,
'rating' => (float)$course['rating'],
'score' => (float)$course['score'],
'model' => $course['model'],
'level' => $course['level'],
'score' => $course['score'],
'attrs' => $course['attrs'],
'categories' => $course['categories'],
'user_count' => $course['user_count'],
'lesson_count' => $course['lesson_count'],
'comment_count' => $course['comment_count'],

View File

@ -25,11 +25,7 @@ class Category extends Cache
$category = $categoryRepo->findById($id);
if (!$category) {
return new \stdClass();
}
return $category;
return $category ?: null;
}
}

View File

@ -6,7 +6,7 @@ use App\Builders\ChapterTreeList as ChapterTreeListBuilder;
use App\Repos\Course as CourseRepo;
use Phalcon\Mvc\Model\Resultset;
class ChapterTreeList extends Cache
class CourseChapterList extends Cache
{
protected $lifetime = 7 * 86400;
@ -18,16 +18,13 @@ class ChapterTreeList extends Cache
public function getKey($id = null)
{
return "chapter_tree_list:{$id}";
return "course_chapter_list:{$id}";
}
public function getContent($id = null)
{
$courseRepo = new CourseRepo();
/**
* @var Resultset $chapters
*/
$chapters = $courseRepo->findChapters($id);
if ($chapters->count() == 0) {

View File

@ -81,6 +81,10 @@ class CoursePackageList extends Cache
'vip_price' => $course->vip_price,
'model' => $course->model,
'level' => $course->level,
'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count,
'review_count' => $course->review_count,
'favorite_count' => $course->favorite_count,
];
}

View File

@ -54,8 +54,14 @@ class CourseRelatedList extends Cache
'summary' => $course->summary,
'market_price' => (float)$course->market_price,
'vip_price' => (float)$course->vip_price,
'rating' => (float)$course['rating'],
'score' => (float)$course['score'],
'model' => $course->model,
'level' => $course->level,
'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count,
'review_count' => $course->review_count,
'favorite_count' => $course->favorite_count,
];
}

View File

@ -22,45 +22,73 @@ class CloseTradeTask extends Task
foreach ($trades as $trade) {
if ($trade->channel == TradeModel::CHANNEL_ALIPAY) {
$this->closeAlipayTrade($trade);
$this->handleAlipayTrade($trade);
} elseif ($trade->channel == TradeModel::CHANNEL_WXPAY) {
$this->closeWxpayTrade($trade);
$this->handleWxpayTrade($trade);
}
}
}
/**
* 关闭支付宝交易
* 处理支付宝交易
*
* @param TradeModel $trade
*/
protected function closeAlipayTrade($trade)
protected function handleAlipayTrade($trade)
{
$allowClosed = true;
$alipay = new AlipayService();
$success = $alipay->close($trade->sn);
$alipayTrade = $alipay->find($trade->sn);
if ($success) {
$trade->status = TradeModel::STATUS_CLOSED;
$trade->update();
if ($alipayTrade) {
/**
* 异步通知接收异常,补救漏网
*/
if ($alipayTrade->trade_status == 'TRADE_SUCCESS') {
$this->eventsManager->fire('pay:afterPay', $this, $trade);
$allowClosed = false;
} elseif ($alipayTrade->trade_status == 'WAIT_BUYER_PAY') {
$alipay->close($trade->sn);
}
}
if (!$allowClosed) return;
$trade->status = TradeModel::STATUS_CLOSED;
$trade->update();
}
/**
* 关闭微信交易
* 处理微信交易
*
* @param TradeModel $trade
*/
protected function closeWxpayTrade($trade)
protected function handleWxpayTrade($trade)
{
$allowClosed = true;
$wxpay = new WxpayService();
$success = $wxpay->close($trade->sn);
$wxpayTrade = $wxpay->find($trade->sn);
if ($success) {
$trade->status = TradeModel::STATUS_CLOSED;
$trade->update();
if ($wxpayTrade) {
/**
* 异步通知接收异常,补救漏网
*/
if ($wxpayTrade->trade_state == 'SUCCESS') {
$this->eventsManager->fire('pay:afterPay', $this, $trade);
$allowClosed = false;
} elseif ($wxpayTrade->trade_state == 'NOTPAY') {
$wxpay->close($trade->sn);
}
}
if (!$allowClosed) return;
$trade->status = TradeModel::STATUS_CLOSED;
$trade->update();
}
/**

View File

@ -4,6 +4,7 @@ namespace App\Http\Admin\Controllers;
use App\Http\Admin\Services\Session as SessionService;
use App\Http\Admin\Services\Setting as SettingService;
use App\Traits\Auth as AuthTrait;
use App\Traits\Response as ResponseTrait;
use App\Traits\Security as SecurityTrait;
@ -13,13 +14,19 @@ use App\Traits\Security as SecurityTrait;
class SessionController extends \Phalcon\Mvc\Controller
{
use ResponseTrait, SecurityTrait;
use AuthTrait, ResponseTrait, SecurityTrait;
/**
* @Route("/login", name="admin.login")
*/
public function loginAction()
{
$currentUser = $this->getCurrentUser();
if ($currentUser->id > 0) {
$this->response->redirect(['for' => 'admin.index']);
}
if ($this->request->isPost()) {
$this->checkHttpReferer();

View File

@ -165,35 +165,6 @@ class SettingController extends Controller
}
}
/**
* @Route("/oauth", name="admin.setting.oauth")
*/
public function oauthAction()
{
$settingService = new SettingService();
if ($this->request->isPost()) {
$section = $this->request->getPost('section');
$data = $this->request->getPost();
$settingService->updateSectionSettings($section, $data);
return $this->jsonSuccess(['msg' => '更新配置成功']);
} else {
$qq = $settingService->getSectionSettings('oauth.qq');
$weibo = $settingService->getSectionSettings('oauth.weibo');
$weixin = $settingService->getSectionSettings('oauth.weixin');
$this->view->setVar('qq', $qq);
$this->view->setVar('weibo', $weibo);
$this->view->setVar('weixin', $weixin);
}
}
/**
* @Route("/smser", name="admin.setting.smser")
*/

View File

@ -683,12 +683,6 @@ class AuthNode extends Service
],
[
'id' => '5-1-10',
'label' => '登录设置',
'type' => 'menu',
'route' => 'admin.setting.oauth',
],
[
'id' => '5-1-11',
'label' => '会员设置',
'type' => 'menu',
'route' => 'admin.setting.vip',

View File

@ -1,18 +0,0 @@
<div class="layui-tab layui-tab-brief">
<ul class="layui-tab-title kg-tab-title">
<li class="layui-this">QQ登录</li>
<li>微博登录</li>
<li>微信登录</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
{{ partial('setting/oauth_qq') }}
</div>
<div class="layui-tab-item">
{{ partial('setting/oauth_weibo') }}
</div>
<div class="layui-tab-item">
{{ partial('setting/oauth_weixin') }}
</div>
</div>
</div>

View File

@ -1,67 +0,0 @@
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.setting.oauth'}) }}">
<div class="layui-form-item">
<label class="layui-form-label">开启登录</label>
<div class="layui-input-block">
<input type="radio" name="enabled" value="1" title="是" {% if qq.enabled == "1" %}checked{% endif %}>
<input type="radio" name="enabled" value="0" title="否" {% if qq.enabled == "0" %}checked{% endif %}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">App ID</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="app_id" value="{{ qq.app_id }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">App Key</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="app_secret" value="{{ qq.app_secret }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">Redirect Uri</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="redirect_uri" value="{{ qq.redirect_uri }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
<input type="hidden" name="section" value="oauth.qq">
</div>
</div>
</form>
<form class="layui-form kg-form">
<fieldset class="layui-elem-field layui-field-title">
<legend>登录测试</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<span id="qq-login-btn" class="layui-btn layui-btn-primary layui-btn-fluid">QQ登录</span>
</div>
</div>
</form>
<script>
layui.use(['jquery', 'layer'], function () {
var $ = layui.jquery;
var layer = layui.layer;
});
</script>

View File

@ -1,67 +0,0 @@
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.setting.oauth'}) }}">
<div class="layui-form-item">
<label class="layui-form-label">开启登录</label>
<div class="layui-input-block">
<input type="radio" name="enabled" value="1" title="是" {% if weibo.enabled == "1" %}checked{% endif %}>
<input type="radio" name="enabled" value="0" title="否" {% if weibo.enabled == "0" %}checked{% endif %}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">App ID</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="app_id" value="{{ weibo.app_id }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">App Key</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="app_secret" value="{{ weibo.app_secret }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">Redirect Uri</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="redirect_uri" value="{{ weibo.redirect_uri }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
<input type="hidden" name="section" value="oauth.weibo">
</div>
</div>
</form>
<form class="layui-form kg-form">
<fieldset class="layui-elem-field layui-field-title">
<legend>登录测试</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<span id="qq-login-btn" class="layui-btn layui-btn-primary layui-btn-fluid">微博登录</span>
</div>
</div>
</form>
<script>
layui.use(['jquery', 'layer'], function () {
var $ = layui.jquery;
var layer = layui.layer;
});
</script>

View File

@ -1,67 +0,0 @@
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.setting.oauth'}) }}">
<div class="layui-form-item">
<label class="layui-form-label">开启登录</label>
<div class="layui-input-block">
<input type="radio" name="enabled" value="1" title="是" {% if weixin.enabled == "1" %}checked{% endif %}>
<input type="radio" name="enabled" value="0" title="否" {% if weixin.enabled == "0" %}checked{% endif %}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">App ID</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="app_id" value="{{ weixin.app_id }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">App Secret</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="app_secret" value="{{ weixin.app_secret }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">Redirect Uri</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="redirect_uri" value="{{ weixin.redirect_uri }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
<input type="hidden" name="section" value="oauth.weixin">
</div>
</div>
</form>
<form class="layui-form kg-form">
<fieldset class="layui-elem-field layui-field-title">
<legend>登录测试</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<span id="qq-login-btn" class="layui-btn layui-btn-primary layui-btn-fluid">微信登录</span>
</div>
</div>
</form>
<script>
layui.use(['jquery', 'layer'], function () {
var $ = layui.jquery;
var layer = layui.layer;
});
</script>

View File

@ -1,63 +0,0 @@
<?php
namespace App\Http\Web\Controllers;
use App\Traits\Response as ResponseTrait;
/**
* @RoutePrefix("/oauth")
*/
class OAuthController extends \Phalcon\Mvc\Controller
{
use ResponseTrait;
/**
* @Get("/qq/connect", name="web.oauth.qq.connect")
*/
public function qqConnectAction()
{
}
/**
* @Get("/qq/callback", name="web.oauth.qq.callback")
*/
public function qqCallbackAction()
{
}
/**
* @Get("/weibo/connect", name="web.oauth.weibo.connect")
*/
public function weiboConnectAction()
{
}
/**
* @Get("/weibo/callback", name="web.oauth.weibo.callback")
*/
public function weiboCallbackAction()
{
}
/**
* @Get("/weixin/connect", name="web.oauth.weixin.connect")
*/
public function weixinConnectAction()
{
}
/**
* @Get("/weixin/callback", name="web.oauth.weixin.callback")
*/
public function weixinCallbackAction()
{
}
}

View File

@ -6,16 +6,13 @@ use App\Services\Pay\Alipay as AlipayService;
use App\Services\Pay\Wxpay as WxpayService;
use App\Traits\Response as ResponseTrait;
/**
* @RoutePrefix("/pay")
*/
class PayController extends \Phalcon\Mvc\Controller
{
use ResponseTrait;
/**
* @Post("/alipay/notify", name="web.pay.alipay.notify")
* @Post("/alipay/notify", name="web.alipay.notify")
*/
public function alipayNotifyAction()
{
@ -31,7 +28,7 @@ class PayController extends \Phalcon\Mvc\Controller
}
/**
* @Post("/wxpay/notify", name="web.pay.wxpay.notify")
* @Post("/wxpay/notify", name="web.wxpay.notify")
*/
public function wxpayNotifyAction()
{
@ -47,7 +44,7 @@ class PayController extends \Phalcon\Mvc\Controller
}
/**
* @Post("/alipay/status", name="web.pay.alipay.status")
* @Post("/alipay/status", name="web.alipay.status")
*/
public function alipayStatusAction()
{
@ -61,7 +58,7 @@ class PayController extends \Phalcon\Mvc\Controller
}
/**
* @Post("/wxpay/status", name="web.pay.wxpay.status")
* @Post("/wxpay/status", name="web.wxpay.status")
*/
public function wxpayStatusAction()
{

View File

@ -1,93 +0,0 @@
<?php
namespace App\Models;
use Phalcon\Mvc\Model\Behavior\SoftDelete;
class AccountBind extends Model
{
/**
* 服务商类型
*/
const PROVIDER_QQ = 'qq';
const PROVIDER_WEIXIN = 'weixin';
const PROVIDER_WEIBO = 'weibo';
/**
* 主键编号
*
* @var int
*/
public $id;
/**
* 服务商
*
* @var string
*/
public $provider;
/**
* 外部用户编号
*
* @var string
*/
public $open_id;
/**
* 内部用户编号
*
* @var int
*/
public $user_id;
/**
* 删除标识
*
* @var int
*/
public $deleted;
/**
* 创建时间
*
* @var int
*/
public $create_time;
/**
* 更新时间
*
* @var int
*/
public $update_time;
public function getSource()
{
return 'kg_account_bind';
}
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();
}
}

View File

@ -86,6 +86,13 @@ class Course extends Model
*/
public $details;
/**
* 主分类编号
*
* @var int
*/
public $category_id;
/**
* 市场价格
*

View File

@ -3,7 +3,6 @@
namespace App\Repos;
use App\Models\Account as AccountModel;
use App\Models\AccountBind as AccountBindModel;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -44,23 +43,6 @@ class Account extends Repository
]);
}
/**
* @param string $provider
* @param string $openId
* @return AccountModel|Model|bool
*/
public function findByOpenId($provider, $openId)
{
$bind = AccountBindModel::findFirst([
'conditions' => 'provider = ?1 AND open_id = ?2',
'bind' => [1 => $provider, 2 => $openId],
]);
if (!$bind) return false;
return AccountModel::findFirst($bind->user_id);
}
/**
* @param array $ids
* @param array|string $columns

View File

@ -15,13 +15,13 @@ class PasswordReset extends Service
$accountValidator = new AccountValidator();
$account = $accountValidator->checkLoginName($post['account']);
$account = $accountValidator->checkLoginName($post['name']);
$accountValidator->checkPassword($post['new_password']);
$securityValidator = new SecurityValidator();
$securityValidator->checkVerifyCode($post['account'], $post['verify_code']);
$securityValidator->checkVerifyCode($post['name'], $post['verify_code']);
$account->password = $post['new_password'];

View File

@ -75,8 +75,8 @@ class CommentList extends Service
$comment['mentions'] = $comment['mentions'] ? json_decode($comment['mentions']) : [];
$me = [
'agreed' => $votes[$comment['id']]['agreed'] ?? false,
'opposed' => $votes[$comment['id']]['opposed'] ?? false,
'agreed' => $votes[$comment['id']]['agreed'] ?? 0,
'opposed' => $votes[$comment['id']]['opposed'] ?? 0,
];
$items[] = [
@ -115,8 +115,8 @@ class CommentList extends Service
foreach ($votes as $vote) {
$result[$vote->comment_id] = [
'agreed' => $vote->type == CommentVoteModel::TYPE_AGREE,
'opposed' => $vote->type == CommentVoteModel::TYPE_OPPOSE,
'agreed' => $vote->type == CommentVoteModel::TYPE_AGREE ? 1 : 0,
'opposed' => $vote->type == CommentVoteModel::TYPE_OPPOSE ? 1 : 0,
];
}

View File

@ -27,11 +27,7 @@ trait ChapterTrait
return $validator->checkChapter($id);
}
/**
* @param ChapterModel $chapter
* @param UserModel $user
*/
public function setChapterUser($chapter, $user)
public function setChapterUser(ChapterModel $chapter, UserModel $user)
{
$chapterUserRepo = new ChapterUserRepo();

View File

@ -40,11 +40,7 @@ class ChapterList extends Service
return $this->handleChapters($chapters);
}
/**
* @param Resultset $chapters
* @return array
*/
protected function handleChapters($chapters)
protected function handleChapters(Resultset $chapters)
{
if ($chapters->count() == 0) {
return [];
@ -60,7 +56,7 @@ class ChapterList extends Service
foreach ($treeList as &$chapter) {
foreach ($chapter['children'] as &$lesson) {
$owned = $this->ownedCourse || $lesson['free'];
$owned = ($this->ownedCourse || $lesson['free']) ? 1 : 0;
$progress = $learningMapping[$lesson['id']]['progress'] ?? 0;
$lesson['me'] = [
'owned' => $owned,
@ -72,12 +68,7 @@ class ChapterList extends Service
return $treeList;
}
/**
* @param CourseModel
* @param UserModel
* @return array
*/
protected function getLearningMapping($course, $user)
protected function getLearningMapping(CourseModel $course, UserModel $user)
{
if ($user->id == 0) {
return [];

View File

@ -2,9 +2,13 @@
namespace App\Services\Frontend\Course;
use App\Caches\CourseChapterList as CourseChapterListCache;
use App\Caches\CourseTeacherList as CourseTeacherListCache;
use App\Models\Course as CourseModel;
use App\Models\User as UserModel;
use App\Repos\Course as CourseRepo;
use App\Repos\CourseFavorite as CourseFavoriteRepo;
use App\Services\Category as CategoryService;
use App\Services\Frontend\CourseTrait;
use App\Services\Frontend\Service;
@ -26,7 +30,27 @@ class CourseInfo extends Service
protected function handleCourse(CourseModel $course, UserModel $user)
{
$result = $this->formatCourse($course);
$result = [
'id' => $course->id,
'title' => $course->title,
'cover' => kg_ci_img_url($course->cover),
'summary' => $course->summary,
'details' => $course->details,
'keywords' => $course->keywords,
'market_price' => (float)$course->market_price,
'vip_price' => (float)$course->vip_price,
'study_expiry' => $course->study_expiry,
'refund_expiry' => $course->refund_expiry,
'rating' => (float)$course->rating,
'score' => (float)$course->score,
'model' => $course->model,
'level' => $course->level,
'attrs' => $course->attrs,
'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count,
'review_count' => $course->review_count,
'favorite_count' => $course->favorite_count,
];
$me = [
'joined' => 0,
@ -55,34 +79,73 @@ class CourseInfo extends Service
$me['owned'] = $this->ownedCourse ? 1 : 0;
}
$result['category_paths'] = $this->getCategoryPaths($course);
$result['teachers'] = $this->getTeachers($course);
$result['chapters'] = $this->getChapters($course, $user);
$result['me'] = $me;
return $result;
}
protected function formatCourse($course)
protected function getCategoryPaths(CourseModel $course)
{
return [
'id' => $course->id,
'title' => $course->title,
'cover' => kg_ci_img_url($course->cover),
'summary' => $course->summary,
'details' => $course->details,
'keywords' => $course->keywords,
'market_price' => (float)$course->market_price,
'vip_price' => (float)$course->vip_price,
'study_expiry' => $course->study_expiry,
'refund_expiry' => $course->refund_expiry,
'rating' => (float)$course->rating,
'score' => (float)$course->score,
'model' => $course->model,
'level' => $course->level,
'attrs' => $course->attrs,
'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count,
'review_count' => $course->review_count,
'favorite_count' => $course->favorite_count,
];
$categoryService = new CategoryService();
return $categoryService->getNodePaths($course->category_id);
}
protected function getTeachers(CourseModel $course)
{
$cache = new CourseTeacherListCache();
return $cache->get($course->id);
}
protected function getChapters(CourseModel $course, UserModel $user)
{
$cache = new CourseChapterListCache();
$chapters = $cache->get($course->id);
$learningMapping = $this->getLearningMapping($course, $user);
foreach ($chapters as &$chapter) {
foreach ($chapter['children'] as &$lesson) {
$owned = ($this->ownedCourse || $lesson['free']) ? 1 : 0;
$progress = $learningMapping[$lesson['id']]['progress'] ?? 0;
$lesson['me'] = [
'owned' => $owned,
'progress' => $progress,
];
}
}
return $chapters;
}
protected function getLearningMapping(CourseModel $course, UserModel $user)
{
if ($user->id == 0) {
return [];
}
$courseRepo = new CourseRepo();
$userLearnings = $courseRepo->findUserLearnings($course->id, $user->id);
if ($userLearnings->count() == 0) {
return [];
}
$mapping = [];
foreach ($userLearnings as $learning) {
$mapping[$learning['chapter_id']] = [
'progress' => $learning['progress'],
];
}
return $mapping;
}
}

View File

@ -62,6 +62,8 @@ class CourseList extends Service
'summary' => $course['summary'],
'market_price' => (float)$course['market_price'],
'vip_price' => (float)$course['vip_price'],
'rating' => (float)$course['rating'],
'score' => (float)$course['score'],
'model' => $course['model'],
'level' => $course['level'],
'user_count' => $course['user_count'],

View File

@ -17,19 +17,7 @@ class CourseRelated extends Service
$listCache = new CourseRelatedListCache();
$courses = $listCache->get($course->id);
if (!$courses) {
return [];
}
$baseUrl = kg_ci_base_url();
foreach ($courses as &$course) {
$course['cover'] = $baseUrl . $course['cover'];
}
return $courses;
return $listCache->get($course->id);
}
}

View File

@ -73,8 +73,14 @@ class PackageList extends Service
'summary' => $course->summary,
'market_price' => (float)$course->market_price,
'vip_price' => (float)$course->vip_price,
'rating' => (float)$course['rating'],
'score' => (float)$course['score'],
'model' => $course->model,
'level' => $course->level,
'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count,
'review_count' => $course->review_count,
'favorite_count' => $course->favorite_count,
];
}

View File

@ -17,17 +17,7 @@ class TeacherList extends Service
$listCache = new CourseTeacherListCache();
$teachers = $listCache->get($course->id);
if (!$teachers) return [];
$baseUrl = kg_ci_base_url();
foreach ($teachers as &$teacher) {
$teacher['avatar'] = $baseUrl . $teacher['avatar'];
}
return $teachers;
return $listCache->get($course->id);
}
}

View File

@ -33,11 +33,7 @@ trait CourseTrait
return $validator->checkCourse($id);
}
/**
* @param CourseModel $course
* @param UserModel $user
*/
public function setCourseUser($course, $user)
public function setCourseUser(CourseModel $course, UserModel $user)
{
$courseUserRepo = new CourseUserRepo();

View File

@ -40,8 +40,9 @@ abstract class Pay extends Service
* 查找交易
*
* @param string $tradeNo
* @param string $type
*/
abstract public function find($tradeNo);
abstract public function find($tradeNo, $type);
/**
* 关闭交易

View File

@ -116,15 +116,16 @@ class Alipay extends AppPay
* 查询交易(扫码生成订单后可执行)
*
* @param string $outTradeNo
* @param string $type
* @return Collection|bool
*/
public function find($outTradeNo)
public function find($outTradeNo, $type = 'wap')
{
try {
$result = $this->gateway->find([
'out_trade_no' => $outTradeNo,
]);
$order = ['out_trade_no' => $outTradeNo];
$result = $this->gateway->find($order, $type);
} catch (\Exception $e) {

View File

@ -115,15 +115,16 @@ class Wxpay extends AppPay
* 查询交易(扫码生成订单后可执行)
*
* @param string $outTradeNo
* @param string $type
* @return Collection|bool
*/
public function find($outTradeNo)
public function find($outTradeNo, $type = 'wap')
{
try {
$result = $this->gateway->find([
'out_trade_no' => $outTradeNo,
]);
$order = ['out_trade_no' => $outTradeNo];
$result = $this->gateway->find($order, $type);
} catch (\Exception $e) {