mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-07-15 12:52:21 +08:00
Merge branch 'koogua/v1.4.5'
This commit is contained in:
commit
b29ae1ef2f
16
CHANGELOG.md
16
CHANGELOG.md
@ -1,3 +1,19 @@
|
||||
### [v1.4.5](https://gitee.com/koogua/course-tencent-cloud/releases/v1.4.5)(2021-09-27)
|
||||
|
||||
- 修正点击内容分享到微信会额外出现公众号二维码的问题
|
||||
- 修正后台首页提问和回答的数量统计
|
||||
- 调整登录限制(邮箱|手机)为注册限制
|
||||
- 调整订单发货为每一分钟执行一次
|
||||
- 增强课时安全性,无权限时不返回播放地址或内容
|
||||
- 抽离出文章关闭,仅我可见操作
|
||||
- 增加退出群组和解除好友接口
|
||||
- 增加删除文章和提问接口
|
||||
- 增加首页推荐教师接口
|
||||
- 增加微信公众号支付处理
|
||||
- 增加取消订单功能
|
||||
- 优化订单API结构
|
||||
- 优化计划任务
|
||||
|
||||
### [v1.4.4](https://gitee.com/koogua/course-tencent-cloud/releases/v1.4.4)(2021-09-17)
|
||||
|
||||
- 后台增加邮件手机登录选择配置
|
||||
|
@ -58,7 +58,7 @@ class AnswerList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -71,7 +71,7 @@ class ArticleList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -69,6 +69,7 @@ class CategoryTreeList extends Builder
|
||||
|
||||
$query->where('parent_id = 0');
|
||||
$query->andWhere('published = 1');
|
||||
$query->andWhere('deleted = 0');
|
||||
$query->andWhere('type = :type:', ['type' => $type]);
|
||||
$query->orderBy('priority ASC');
|
||||
|
||||
@ -84,6 +85,7 @@ class CategoryTreeList extends Builder
|
||||
$query = CategoryModel::query();
|
||||
|
||||
$query->where('published = 1');
|
||||
$query->where('deleted = 0');
|
||||
$query->andWhere('parent_id = :parent_id:', ['parent_id' => $parentId]);
|
||||
$query->orderBy('priority ASC');
|
||||
|
||||
|
@ -32,7 +32,7 @@ class CommentList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -79,7 +79,7 @@ class ConsultList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -62,7 +62,7 @@ class CourseList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -87,7 +87,7 @@ class DanmuList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -29,7 +29,7 @@ class ImMessageList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -48,7 +48,7 @@ class LiveList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($teacherIds, ['id', 'name', 'title', 'avatar', 'about']);
|
||||
$users = $userRepo->findShallowUserByIds($teacherIds);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -68,6 +68,7 @@ class NavTreeList extends Builder
|
||||
return NavModel::query()
|
||||
->where('parent_id = :parent_id:', ['parent_id' => $navId])
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('priority ASC')
|
||||
->execute();
|
||||
}
|
||||
@ -80,7 +81,9 @@ class NavTreeList extends Builder
|
||||
{
|
||||
return NavModel::query()
|
||||
->where('position = :position:', ['position' => $position])
|
||||
->andWhere('level = 1 AND published = 1')
|
||||
->andWhere('level = 1')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('priority ASC')
|
||||
->execute();
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class NotificationList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\Order as OrderModel;
|
||||
use App\Repos\User as UserRepo;
|
||||
|
||||
@ -42,7 +43,7 @@ class OrderList extends Builder
|
||||
public function handleItems(array $orders)
|
||||
{
|
||||
foreach ($orders as $key => $order) {
|
||||
$itemInfo = $this->handleItem($order);
|
||||
$itemInfo = $this->handleItemInfo($order);
|
||||
$orders[$key]['item_info'] = $itemInfo;
|
||||
}
|
||||
|
||||
@ -53,7 +54,7 @@ class OrderList extends Builder
|
||||
* @param array $order
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function handleItem(array $order)
|
||||
public function handleItemInfo(array $order)
|
||||
{
|
||||
$itemInfo = [];
|
||||
|
||||
@ -72,6 +73,52 @@ class OrderList extends Builder
|
||||
return $itemInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $order
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function handleMeInfo(array $order)
|
||||
{
|
||||
$me = [
|
||||
'allow_pay' => 0,
|
||||
'allow_cancel' => 0,
|
||||
'allow_refund' => 0,
|
||||
];
|
||||
|
||||
$payStatusOk = $order['status'] == OrderModel::STATUS_PENDING ? 1 : 0;
|
||||
$cancelStatusOk = $order['status'] == OrderModel::STATUS_PENDING ? 1 : 0;
|
||||
$refundStatusOk = $order['status'] == OrderModel::STATUS_FINISHED ? 1 : 0;
|
||||
|
||||
if ($order['item_type'] == OrderModel::ITEM_COURSE) {
|
||||
|
||||
$course = $order['item_info']['course'];
|
||||
|
||||
$courseModelOk = $course['model'] != CourseModel::MODEL_OFFLINE;
|
||||
$refundTimeOk = $course['refund_expiry_time'] > time();
|
||||
|
||||
$me['allow_refund'] = $courseModelOk && $refundStatusOk && $refundTimeOk ? 1 : 0;
|
||||
|
||||
} elseif ($order['item_type'] == OrderModel::ITEM_PACKAGE) {
|
||||
|
||||
$courses = $order['item_info']['courses'];
|
||||
|
||||
$refundTimeOk = false;
|
||||
|
||||
foreach ($courses as $course) {
|
||||
if ($course['refund_expiry_time'] > time()) {
|
||||
$refundTimeOk = true;
|
||||
}
|
||||
}
|
||||
|
||||
$me['allow_refund'] = $refundStatusOk && $refundTimeOk ? 1 : 0;
|
||||
}
|
||||
|
||||
$me['allow_pay'] = $payStatusOk;
|
||||
$me['allow_cancel'] = $cancelStatusOk;
|
||||
|
||||
return $me;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $itemInfo
|
||||
* @return mixed
|
||||
@ -139,7 +186,7 @@ class OrderList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$result = [];
|
||||
|
||||
|
@ -72,7 +72,7 @@ class QuestionFavoriteList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -74,7 +74,7 @@ class QuestionList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
use App\Models\Refund as RefundModel;
|
||||
use App\Repos\Order as OrderRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
|
||||
@ -35,6 +36,24 @@ class RefundList extends Builder
|
||||
return $refunds;
|
||||
}
|
||||
|
||||
public function handleMeInfo(array $refund)
|
||||
{
|
||||
$me = [
|
||||
'allow_cancel' => 0,
|
||||
];
|
||||
|
||||
$statusTypes = [
|
||||
RefundModel::STATUS_PENDING,
|
||||
RefundModel::STATUS_APPROVED,
|
||||
];
|
||||
|
||||
if (in_array($refund['status'], $statusTypes)) {
|
||||
$me['allow_cancel'] = 1;
|
||||
}
|
||||
|
||||
return $me;
|
||||
}
|
||||
|
||||
public function getOrders(array $trades)
|
||||
{
|
||||
$ids = kg_array_column($trades, 'order_id');
|
||||
@ -58,11 +77,14 @@ class RefundList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($users->toArray() as $user) {
|
||||
$user['avatar'] = $baseUrl . $user['avatar'];
|
||||
$result[$user['id']] = $user;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ class ReportList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -58,7 +58,7 @@ class ReviewList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
|
@ -58,11 +58,14 @@ class TradeList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name']);
|
||||
$users = $userRepo->findShallowUserByIds($ids);
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($users->toArray() as $user) {
|
||||
$user['avatar'] = $baseUrl . $user['avatar'];
|
||||
$result[$user['id']] = $user;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ class CategoryList extends Cache
|
||||
->columns(['id', 'parent_id', 'name', 'priority', 'level', 'path'])
|
||||
->where('type = :type:', ['type' => $type])
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->execute();
|
||||
|
||||
if ($categories->count() == 0) {
|
||||
|
@ -70,7 +70,9 @@ class CourseRecommendedList extends Cache
|
||||
public function findCourses($limit = 5)
|
||||
{
|
||||
return CourseModel::query()
|
||||
->where('published = 1 AND market_price > 0')
|
||||
->where('market_price > 0')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('RAND()')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
@ -51,6 +51,7 @@ class CourseTeacherList extends Cache
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
'avatar' => $user->avatar,
|
||||
'vip' => $user->vip,
|
||||
'title' => $user->title,
|
||||
'about' => $user->about,
|
||||
];
|
||||
|
@ -73,7 +73,9 @@ class HelpList extends Cache
|
||||
{
|
||||
return CategoryModel::query()
|
||||
->where('type = :type:', ['type' => CategoryModel::TYPE_HELP])
|
||||
->andWhere('level = 1 AND published = 1')
|
||||
->andWhere('level = 1')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('priority ASC')
|
||||
->execute();
|
||||
}
|
||||
@ -87,6 +89,7 @@ class HelpList extends Cache
|
||||
return HelpModel::query()
|
||||
->where('category_id = :category_id:', ['category_id' => $categoryId])
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('priority ASC')
|
||||
->execute();
|
||||
}
|
||||
|
@ -111,7 +111,8 @@ class HotQuestionList extends Cache
|
||||
{
|
||||
return QuestionModel::query()
|
||||
->where('create_time > :create_time:', ['create_time' => $createTime])
|
||||
->andWhere('published = 1 AND deleted = 0')
|
||||
->andWhere('published = :published:', ['published' => QuestionModel::PUBLISH_APPROVED])
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('score DESC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
@ -72,6 +72,8 @@ class ImActiveGroupList extends Cache
|
||||
->orderBy('total_count DESC')
|
||||
->where('receiver_type = :type:', ['type' => ImMessageModel::TYPE_GROUP])
|
||||
->betweenWhere('create_time', $startTime, $endTime)
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
||||
|
@ -70,6 +70,7 @@ class ImNewGroupList extends Cache
|
||||
{
|
||||
return ImGroupModel::query()
|
||||
->where('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('id DESC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
@ -14,7 +14,7 @@ use App\Services\Logic\Article\ArticleList as ArticleListService;
|
||||
class IndexArticleList extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 1 * 86400;
|
||||
protected $lifetime = 15 * 60;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
@ -30,7 +30,10 @@ class IndexArticleList extends Cache
|
||||
{
|
||||
$articleRepo = new ArticleRepo();
|
||||
|
||||
$where = ['published' => ArticleModel::PUBLISH_APPROVED];
|
||||
$where = [
|
||||
'published' => ArticleModel::PUBLISH_APPROVED,
|
||||
'deleted' => 0,
|
||||
];
|
||||
|
||||
$pager = $articleRepo->paginate($where, 'latest', 1, 10);
|
||||
|
||||
|
@ -94,7 +94,9 @@ class IndexFeaturedCourseList extends Cache
|
||||
{
|
||||
return CategoryModel::query()
|
||||
->where('type = :type:', ['type' => CategoryModel::TYPE_COURSE])
|
||||
->andWhere('level = 1 AND published = 1')
|
||||
->andWhere('level = 1')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('priority ASC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
@ -113,8 +115,9 @@ class IndexFeaturedCourseList extends Cache
|
||||
|
||||
return CourseModel::query()
|
||||
->inWhere('category_id', $categoryIds)
|
||||
->andWhere('published = 1')
|
||||
->andWhere('featured = 1')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('id DESC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
36
app/Caches/IndexFlashSaleList.php
Normal file
36
app/Caches/IndexFlashSaleList.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Services\Logic\FlashSale\SaleList;
|
||||
|
||||
class IndexFlashSaleList extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 1 * 86400;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
return strtotime('tomorrow') - time();
|
||||
}
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return 'index_flash_sale_list';
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$service = new SaleList();
|
||||
|
||||
$sales = $service->handle();
|
||||
|
||||
return $sales[0]['items'] ?? [];
|
||||
}
|
||||
|
||||
}
|
@ -94,7 +94,9 @@ class IndexFreeCourseList extends Cache
|
||||
{
|
||||
return CategoryModel::query()
|
||||
->where('type = :type:', ['type' => CategoryModel::TYPE_COURSE])
|
||||
->andWhere('level = 1 AND published = 1')
|
||||
->andWhere('level = 1')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('priority ASC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
@ -113,8 +115,9 @@ class IndexFreeCourseList extends Cache
|
||||
|
||||
return CourseModel::query()
|
||||
->inWhere('category_id', $categoryIds)
|
||||
->andWhere('published = 1')
|
||||
->andWhere('market_price = 0')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('score DESC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
@ -132,6 +132,8 @@ class IndexLiveList extends Cache
|
||||
->addFrom(ChapterLiveModel::class, 'cl')
|
||||
->join(ChapterModel::class, 'cl.chapter_id = c.id', 'c')
|
||||
->betweenWhere('start_time', $startTime, $endTime)
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('start_time ASC')
|
||||
->getQuery()
|
||||
->execute();
|
||||
|
@ -94,7 +94,9 @@ class IndexNewCourseList extends Cache
|
||||
{
|
||||
return CategoryModel::query()
|
||||
->where('type = :type:', ['type' => CategoryModel::TYPE_COURSE])
|
||||
->andWhere('level = 1 AND published = 1')
|
||||
->andWhere('level = 1')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('priority ASC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
@ -114,6 +116,7 @@ class IndexNewCourseList extends Cache
|
||||
return CourseModel::query()
|
||||
->inWhere('category_id', $categoryIds)
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('id DESC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
@ -14,7 +14,7 @@ use App\Services\Logic\Question\QuestionList as QuestionListService;
|
||||
class IndexQuestionList extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 1 * 86400;
|
||||
protected $lifetime = 15 * 60;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
@ -30,7 +30,10 @@ class IndexQuestionList extends Cache
|
||||
{
|
||||
$questionRepo = new QuestionRepo();
|
||||
|
||||
$where = ['published' => QuestionModel::PUBLISH_APPROVED];
|
||||
$where = [
|
||||
'published' => QuestionModel::PUBLISH_APPROVED,
|
||||
'deleted' => 0,
|
||||
];
|
||||
|
||||
$pager = $questionRepo->paginate($where, 'latest', 1, 10);
|
||||
|
||||
|
@ -65,8 +65,9 @@ class IndexSimpleFeaturedCourseList extends Cache
|
||||
protected function findCourses($limit = 8)
|
||||
{
|
||||
return CourseModel::query()
|
||||
->where('published = 1')
|
||||
->andWhere('featured = 1')
|
||||
->where('featured = 1')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('id DESC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
@ -65,8 +65,9 @@ class IndexSimpleFreeCourseList extends Cache
|
||||
protected function findCourses($limit = 8)
|
||||
{
|
||||
return CourseModel::query()
|
||||
->where('published = 1')
|
||||
->andWhere('market_price = 0')
|
||||
->where('market_price = 0')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('score DESC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
@ -66,6 +66,7 @@ class IndexSimpleNewCourseList extends Cache
|
||||
{
|
||||
return CourseModel::query()
|
||||
->where('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('id DESC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
@ -65,9 +65,10 @@ class IndexSimpleVipCourseList extends Cache
|
||||
protected function findCourses($limit = 8)
|
||||
{
|
||||
return CourseModel::query()
|
||||
->where('published = 1')
|
||||
->andWhere('market_price > vip_price')
|
||||
->where('market_price > vip_price')
|
||||
->andWhere('vip_price >= 0')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('score DESC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
@ -68,6 +68,7 @@ class IndexSlideList extends Cache
|
||||
{
|
||||
return SlideModel::query()
|
||||
->where('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('priority ASC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
69
app/Caches/IndexTeacherList.php
Normal file
69
app/Caches/IndexTeacherList.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Models\User as UserModel;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class IndexTeacherList extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 1 * 3600;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
return $this->lifetime;
|
||||
}
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return 'index_teacher_list';
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$teachers = $this->findTeachers();
|
||||
|
||||
if ($teachers->count() == 0) return [];
|
||||
|
||||
$result = [];
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
foreach ($teachers->toArray() as $teacher) {
|
||||
|
||||
$teacher['avatar'] = $baseUrl . $teacher['avatar'];
|
||||
|
||||
$result[] = [
|
||||
'id' => $teacher['id'],
|
||||
'name' => $teacher['name'],
|
||||
'title' => $teacher['title'],
|
||||
'avatar' => $teacher['avatar'],
|
||||
'about' => $teacher['about'],
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @return ResultsetInterface|Resultset|UserModel[]
|
||||
*/
|
||||
protected function findTeachers($limit = 8)
|
||||
{
|
||||
return UserModel::query()
|
||||
->where('edu_role = :edu_role:', ['edu_role' => UserModel::EDU_ROLE_TEACHER])
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('RAND()')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
@ -94,7 +94,9 @@ class IndexVipCourseList extends Cache
|
||||
{
|
||||
return CategoryModel::query()
|
||||
->where('type = :type:', ['type' => CategoryModel::TYPE_COURSE])
|
||||
->andWhere('level = 1 AND published = 1')
|
||||
->andWhere('level = 1')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('priority ASC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
@ -113,9 +115,10 @@ class IndexVipCourseList extends Cache
|
||||
|
||||
return CourseModel::query()
|
||||
->inWhere('category_id', $categoryIds)
|
||||
->andWhere('published = 1')
|
||||
->andWhere('market_price > vip_price')
|
||||
->andWhere('vip_price >= 0')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('score DESC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
@ -76,6 +76,7 @@ class PointHotGiftList extends Cache
|
||||
{
|
||||
return PointGiftModel::query()
|
||||
->where('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('redeem_count DESC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Models\Order as OrderModel;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class SaleTrend extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 2 * 3600;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
return $this->lifetime;
|
||||
}
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return 'sale_trend';
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderModel[] $sales
|
||||
* @param int $days
|
||||
* @return array
|
||||
*/
|
||||
protected function handleSales($sales, $days = 7)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach (array_reverse(range(1, $days)) as $num) {
|
||||
$date = date('Y-m-d', strtotime("-{$num} days"));
|
||||
$result[$date] = 0;
|
||||
}
|
||||
|
||||
foreach ($sales as $sale) {
|
||||
$date = date('Y-m-d', $sale->create_time);
|
||||
$result[$date] += $sale->amount;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $days
|
||||
* @return ResultsetInterface|Resultset|OrderModel[]
|
||||
*/
|
||||
protected function findSales($days = 7)
|
||||
{
|
||||
$time = strtotime("-{$days} days");
|
||||
|
||||
return OrderModel::query()
|
||||
->where('status = :status:', ['status' => OrderModel::STATUS_FINISHED])
|
||||
->andWhere('create_time > :time:', ['time' => $time])
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
@ -7,12 +7,14 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Repos\Answer as AnswerRepo;
|
||||
use App\Repos\Article as ArticleRepo;
|
||||
use App\Repos\Comment as CommentRepo;
|
||||
use App\Repos\Consult as ConsultRepo;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\ImGroup as GroupRepo;
|
||||
use App\Repos\Package as PackageRepo;
|
||||
use App\Repos\Question as QuestionRepo;
|
||||
use App\Repos\Review as ReviewRepo;
|
||||
use App\Repos\Topic as TopicRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
@ -36,6 +38,8 @@ class SiteGlobalStat extends Cache
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
$articleRepo = new ArticleRepo();
|
||||
$questionRepo = new QuestionRepo();
|
||||
$answerRepo = new AnswerRepo();
|
||||
$commentRepo = new CommentRepo();
|
||||
$consultRepo = new ConsultRepo();
|
||||
$groupRepo = new GroupRepo();
|
||||
@ -47,6 +51,8 @@ class SiteGlobalStat extends Cache
|
||||
return [
|
||||
'course_count' => $courseRepo->countCourses(),
|
||||
'article_count' => $articleRepo->countArticles(),
|
||||
'question_count' => $questionRepo->countQuestions(),
|
||||
'answer_count' => $answerRepo->countAnswers(),
|
||||
'comment_count' => $commentRepo->countComments(),
|
||||
'consult_count' => $consultRepo->countConsults(),
|
||||
'group_count' => $groupRepo->countGroups(),
|
||||
|
@ -34,6 +34,7 @@ class TaggedArticleList extends Cache
|
||||
$where = [
|
||||
'tag_id' => $id,
|
||||
'published' => ArticleModel::PUBLISH_APPROVED,
|
||||
'deleted' => 0,
|
||||
];
|
||||
|
||||
$pager = $articleRepo->paginate($where);
|
||||
|
@ -35,6 +35,7 @@ class TaggedQuestionList extends Cache
|
||||
$where = [
|
||||
'tag_id' => $id,
|
||||
'published' => QuestionModel::PUBLISH_APPROVED,
|
||||
'deleted' => 0,
|
||||
];
|
||||
|
||||
$pager = $questionRepo->paginate($where);
|
||||
|
@ -124,6 +124,7 @@ class ArticleIndexTask extends Task
|
||||
{
|
||||
return ArticleModel::query()
|
||||
->where('published = :published:', ['published' => ArticleModel::PUBLISH_APPROVED])
|
||||
->andWhere('deleted = 0')
|
||||
->execute();
|
||||
}
|
||||
|
||||
|
@ -124,6 +124,7 @@ class CourseIndexTask extends Task
|
||||
{
|
||||
return CourseModel::query()
|
||||
->where('published = 1')
|
||||
->where('deleted = 0')
|
||||
->execute();
|
||||
}
|
||||
|
||||
|
@ -293,11 +293,11 @@ class DeliverTask extends Task
|
||||
* @param int $limit
|
||||
* @return ResultsetInterface|Resultset|TaskModel[]
|
||||
*/
|
||||
protected function findTasks($limit = 30)
|
||||
protected function findTasks($limit = 100)
|
||||
{
|
||||
$itemType = TaskModel::TYPE_DELIVER;
|
||||
$status = TaskModel::STATUS_PENDING;
|
||||
$createTime = strtotime('-3 days');
|
||||
$createTime = strtotime('-1 days');
|
||||
|
||||
return TaskModel::query()
|
||||
->where('item_type = :item_type:', ['item_type' => $itemType])
|
||||
|
@ -124,6 +124,7 @@ class GroupIndexTask extends Task
|
||||
{
|
||||
return GroupModel::query()
|
||||
->where('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->execute();
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ class NoticeTask extends Task
|
||||
|
||||
$task->update();
|
||||
|
||||
$logger->info('Notice Process Exception ' . kg_json_encode([
|
||||
$logger->error('Notice Process Exception ' . kg_json_encode([
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'message' => $e->getMessage(),
|
||||
|
@ -124,6 +124,7 @@ class QuestionIndexTask extends Task
|
||||
{
|
||||
return QuestionModel::query()
|
||||
->where('published = :published:', ['published' => QuestionModel::PUBLISH_APPROVED])
|
||||
->andWhere('deleted = 0')
|
||||
->execute();
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,7 @@ class UserIndexTask extends Task
|
||||
protected function findUsers($limit, $offset)
|
||||
{
|
||||
return UserModel::query()
|
||||
->where('deleted = 0')
|
||||
->limit($limit, $offset)
|
||||
->execute();
|
||||
}
|
||||
|
@ -1205,7 +1205,7 @@ class AuthNode extends Service
|
||||
],
|
||||
[
|
||||
'id' => '5-1-12',
|
||||
'title' => '登录设置',
|
||||
'title' => '注册登录',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.setting.oauth',
|
||||
],
|
||||
|
@ -59,13 +59,13 @@
|
||||
<div class="layui-col-md2">
|
||||
<div class="kg-stat-card">
|
||||
<div class="name">提问数</div>
|
||||
<div class="count">0</div>
|
||||
<div class="count">{{ global_stat.question_count }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md2">
|
||||
<div class="kg-stat-card">
|
||||
<div class="name">回答数</div>
|
||||
<div class="count">0</div>
|
||||
<div class="count">{{ global_stat.answer_count }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md2">
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<div class="layui-tab layui-tab-brief">
|
||||
<ul class="layui-tab-title kg-tab-title">
|
||||
<li class="layui-this">本地登录</li>
|
||||
<li class="layui-this">注册设置</li>
|
||||
<li>QQ登录</li>
|
||||
<li>微信登录</li>
|
||||
<li>微博登录</li>
|
||||
|
@ -1,16 +1,16 @@
|
||||
<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>
|
||||
<label class="layui-form-label">开启手机注册</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="login_with_phone" value="1" title="是" {% if local_auth.login_with_phone == "1" %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="login_with_phone" value="0" title="否" {% if local_auth.login_with_phone == "0" %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="register_with_phone" value="1" title="是" {% if local_auth.register_with_phone == "1" %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="register_with_phone" value="0" title="否" {% if local_auth.register_with_phone == "0" %}checked="checked"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">开启邮箱登录</label>
|
||||
<label class="layui-form-label">开启邮箱注册</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="login_with_email" value="1" title="是" {% if local_auth.login_with_email == "1" %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="login_with_email" value="0" title="否" {% if local_auth.login_with_email == "0" %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="register_with_email" value="1" title="是" {% if local_auth.register_with_email == "1" %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="register_with_email" value="0" title="否" {% if local_auth.register_with_email == "0" %}checked="checked"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
namespace App\Http\Api\Controllers;
|
||||
|
||||
use App\Models\Answer as AnswerModel;
|
||||
use App\Services\Logic\Answer\AnswerAccept as AnswerAcceptService;
|
||||
use App\Services\Logic\Answer\AnswerCreate as AnswerCreateService;
|
||||
use App\Services\Logic\Answer\AnswerDelete as AnswerDeleteService;
|
||||
@ -30,6 +31,17 @@ class AnswerController extends Controller
|
||||
|
||||
$answer = $service->handle($id);
|
||||
|
||||
if ($answer['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$approved = $answer['published'] != AnswerModel::PUBLISH_APPROVED;
|
||||
$owned = $answer['me']['owned'] == 1;
|
||||
|
||||
if (!$approved && !$owned) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['answer' => $answer]);
|
||||
}
|
||||
|
||||
@ -82,7 +94,7 @@ class AnswerController extends Controller
|
||||
|
||||
$service->handle($id);
|
||||
|
||||
return $this->jsonSuccess(['msg' => '删除回答成功']);
|
||||
return $this->jsonSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,10 +7,14 @@
|
||||
|
||||
namespace App\Http\Api\Controllers;
|
||||
|
||||
use App\Models\Article as ArticleModel;
|
||||
use App\Services\Logic\Article\ArticleClose as ArticleCloseService;
|
||||
use App\Services\Logic\Article\ArticleDelete as ArticleDeleteService;
|
||||
use App\Services\Logic\Article\ArticleFavorite as ArticleFavoriteService;
|
||||
use App\Services\Logic\Article\ArticleInfo as ArticleInfoService;
|
||||
use App\Services\Logic\Article\ArticleLike as ArticleLikeService;
|
||||
use App\Services\Logic\Article\ArticleList as ArticleListService;
|
||||
use App\Services\Logic\Article\ArticlePrivate as ArticlePrivateService;
|
||||
use App\Services\Logic\Article\CategoryList as CategoryListService;
|
||||
use App\Services\Logic\Article\CommentList as CommentListService;
|
||||
|
||||
@ -53,6 +57,22 @@ class ArticleController extends Controller
|
||||
|
||||
$article = $service->handle($id);
|
||||
|
||||
if ($article['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$approved = $article['published'] == ArticleModel::PUBLISH_APPROVED;
|
||||
$owned = $article['me']['owned'] == 1;
|
||||
$private = $article['private'] == 1;
|
||||
|
||||
if (!$approved && !$owned) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($private && !$owned) {
|
||||
$this->forbidden();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['article' => $article]);
|
||||
}
|
||||
|
||||
@ -68,6 +88,46 @@ class ArticleController extends Controller
|
||||
return $this->jsonPaginate($pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/delete", name="api.article.delete")
|
||||
*/
|
||||
public function deleteAction($id)
|
||||
{
|
||||
$service = new ArticleDeleteService();
|
||||
|
||||
$service->handle($id);
|
||||
|
||||
return $this->jsonSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/close", name="home.article.close")
|
||||
*/
|
||||
public function closeAction($id)
|
||||
{
|
||||
$service = new ArticleCloseService();
|
||||
|
||||
$article = $service->handle($id);
|
||||
|
||||
$msg = $article->closed == 1 ? '关闭评论成功' : '开启评论成功';
|
||||
|
||||
return $this->jsonSuccess(['msg' => $msg]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/private", name="home.article.private")
|
||||
*/
|
||||
public function privateAction($id)
|
||||
{
|
||||
$service = new ArticlePrivateService();
|
||||
|
||||
$article = $service->handle($id);
|
||||
|
||||
$msg = $article->private == 1 ? '开启仅我可见成功' : '关闭仅我可见成功';
|
||||
|
||||
return $this->jsonSuccess(['msg' => $msg]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/favorite", name="api.article.favorite")
|
||||
*/
|
||||
|
@ -65,8 +65,16 @@ class ChapterController extends Controller
|
||||
|
||||
$chapter = $service->handle($id);
|
||||
|
||||
if ($chapter['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($chapter['published'] == 0) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($chapter['me']['owned'] == 0) {
|
||||
return $this->jsonError(['msg' => '没有访问章节权限']);
|
||||
$this->forbidden();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['chapter' => $chapter]);
|
||||
|
@ -85,7 +85,7 @@ class CommentController extends Controller
|
||||
|
||||
$service->handle($id);
|
||||
|
||||
return $this->jsonSuccess(['msg' => '删除评论成功']);
|
||||
return $this->jsonSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
|
74
app/Http/Api/Controllers/ConnectController.php
Normal file
74
app/Http/Api/Controllers/ConnectController.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Http\Api\Controllers;
|
||||
|
||||
use App\Http\Api\Services\Connect as ConnectService;
|
||||
use App\Models\Connect as ConnectModel;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/api/oauth")
|
||||
*/
|
||||
class ConnectController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @Get("/wechat", name="api.oauth.wechat")
|
||||
*/
|
||||
public function wechatAction()
|
||||
{
|
||||
$redirect = $this->request->getQuery('redirect', 'trim');
|
||||
|
||||
$service = new ConnectService();
|
||||
|
||||
if ($redirect) {
|
||||
$service->setWechatRedirectCache($redirect);
|
||||
}
|
||||
|
||||
$url = $service->getAuthorizeUrl(ConnectModel::PROVIDER_WECHAT);
|
||||
|
||||
return $this->response->redirect($url, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/wechat/callback", name="api.oauth.wechat_callback")
|
||||
*/
|
||||
public function wechatCallbackAction()
|
||||
{
|
||||
$service = new ConnectService();
|
||||
|
||||
$data = $service->handleCallback(ConnectModel::PROVIDER_WECHAT);
|
||||
|
||||
$redirect = $service->getWechatRedirectCache();
|
||||
|
||||
if ($redirect) {
|
||||
$service->removeWechatRedirectCache();
|
||||
if (strpos($redirect, '?')) {
|
||||
$location = $redirect . '&' . http_build_query($data);
|
||||
} else {
|
||||
$location = $redirect . '?' . http_build_query($data);
|
||||
}
|
||||
} else {
|
||||
$location = kg_h5_index_url() . '?' . http_build_query($data);
|
||||
}
|
||||
|
||||
return $this->response->redirect($location, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/wechat/info", name="api.oauth.wechat_info")
|
||||
*/
|
||||
public function wechatInfoAction()
|
||||
{
|
||||
$service = new ConnectService();
|
||||
|
||||
$wechat = $service->getWechatInfo();
|
||||
|
||||
return $this->jsonSuccess(['wechat' => $wechat]);
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
|
||||
namespace App\Http\Api\Controllers;
|
||||
|
||||
use App\Models\Consult as ConsultModel;
|
||||
use App\Services\Logic\Consult\ConsultCreate as ConsultCreateService;
|
||||
use App\Services\Logic\Consult\ConsultDelete as ConsultDeleteService;
|
||||
use App\Services\Logic\Consult\ConsultInfo as ConsultInfoService;
|
||||
@ -28,6 +29,17 @@ class ConsultController extends Controller
|
||||
|
||||
$consult = $service->handle($id);
|
||||
|
||||
if ($consult['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$approved = $consult['published'] == ConsultModel::PUBLISH_APPROVED;
|
||||
$owned = $consult['me']['owned'] == 1;
|
||||
|
||||
if (!$approved && !$owned) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['consult' => $consult]);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ use App\Models\User as UserModel;
|
||||
use App\Services\Auth\Api as ApiAuth;
|
||||
use App\Traits\Response as ResponseTrait;
|
||||
use App\Traits\Security as SecurityTrait;
|
||||
use App\Validators\Validator as AppValidator;
|
||||
use Phalcon\Mvc\Dispatcher;
|
||||
|
||||
class Controller extends \Phalcon\Mvc\Controller
|
||||
@ -30,6 +31,10 @@ class Controller extends \Phalcon\Mvc\Controller
|
||||
$this->setCors();
|
||||
}
|
||||
|
||||
$validator = new AppValidator();
|
||||
|
||||
$validator->checkSiteStatus();
|
||||
|
||||
$this->checkRateLimit();
|
||||
|
||||
return true;
|
||||
|
@ -55,6 +55,14 @@ class CourseController extends Controller
|
||||
|
||||
$course = $service->handle($id);
|
||||
|
||||
if ($course['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($course['published'] == 0) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['course' => $course]);
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,14 @@ class HelpController extends Controller
|
||||
|
||||
$help = $service->handle($id);
|
||||
|
||||
if ($help['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($help['published'] == 0) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['help' => $help]);
|
||||
}
|
||||
|
||||
|
30
app/Http/Api/Controllers/ImFriendController.php
Normal file
30
app/Http/Api/Controllers/ImFriendController.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Http\Api\Controllers;
|
||||
|
||||
use App\Services\Logic\Im\FriendQuit as FriendQuitService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/api/im/friend")
|
||||
*/
|
||||
class ImFriendController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/quit", name="api.im_friend.quit")
|
||||
*/
|
||||
public function quitAction($id)
|
||||
{
|
||||
$service = new FriendQuitService();
|
||||
|
||||
$service->handle($id);
|
||||
|
||||
return $this->jsonSuccess();
|
||||
}
|
||||
|
||||
}
|
@ -9,6 +9,7 @@ namespace App\Http\Api\Controllers;
|
||||
|
||||
use App\Services\Logic\Im\GroupInfo as GroupInfoService;
|
||||
use App\Services\Logic\Im\GroupList as GroupListService;
|
||||
use App\Services\Logic\Im\GroupQuit as GroupQuitService;
|
||||
use App\Services\Logic\Im\GroupUserList as GroupUserListService;
|
||||
|
||||
/**
|
||||
@ -38,6 +39,14 @@ class ImGroupController extends Controller
|
||||
|
||||
$group = $service->handle($id);
|
||||
|
||||
if ($group['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($group['published'] == 0) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['group' => $group]);
|
||||
}
|
||||
|
||||
@ -53,4 +62,16 @@ class ImGroupController extends Controller
|
||||
return $this->jsonPaginate($pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/quit", name="api.im_group.quit")
|
||||
*/
|
||||
public function quitAction($id)
|
||||
{
|
||||
$service = new GroupQuitService();
|
||||
|
||||
$service->handle($id);
|
||||
|
||||
return $this->jsonSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
namespace App\Http\Api\Controllers;
|
||||
|
||||
use App\Caches\IndexArticleList;
|
||||
use App\Caches\IndexFlashSaleList;
|
||||
use App\Caches\IndexLiveList;
|
||||
use App\Caches\IndexQuestionList;
|
||||
use App\Caches\IndexSimpleFeaturedCourseList;
|
||||
@ -15,6 +16,7 @@ use App\Caches\IndexSimpleFreeCourseList;
|
||||
use App\Caches\IndexSimpleNewCourseList;
|
||||
use App\Caches\IndexSimpleVipCourseList;
|
||||
use App\Caches\IndexSlideList;
|
||||
use App\Caches\IndexTeacherList;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/api/index")
|
||||
@ -70,6 +72,30 @@ class IndexController extends Controller
|
||||
return $this->jsonSuccess(['lives' => $lives]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/teachers", name="api.index.teachers")
|
||||
*/
|
||||
public function teachersAction()
|
||||
{
|
||||
$cache = new IndexTeacherList();
|
||||
|
||||
$teachers = $cache->get();
|
||||
|
||||
return $this->jsonSuccess(['teachers' => $teachers]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/flash/sales", name="api.index.flash_sales")
|
||||
*/
|
||||
public function flashSalesAction()
|
||||
{
|
||||
$cache = new IndexFlashSaleList();
|
||||
|
||||
$sales = $cache->get();
|
||||
|
||||
return $this->jsonSuccess(['sales' => $sales]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/courses/featured", name="api.index.featured_courses")
|
||||
*/
|
||||
|
@ -29,6 +29,10 @@ class OrderController extends Controller
|
||||
|
||||
$order = $service->handle($sn);
|
||||
|
||||
if ($order['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['order' => $order]);
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,14 @@ class PageController extends Controller
|
||||
|
||||
$page = $service->handle($id);
|
||||
|
||||
if ($page['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($page['published'] == 0) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['page' => $page]);
|
||||
}
|
||||
|
||||
|
@ -49,8 +49,12 @@ class PublicController extends Controller
|
||||
|
||||
$content = [];
|
||||
|
||||
/**
|
||||
* ssl通过nginx转发实现
|
||||
*/
|
||||
if ($this->request->isSecure()) {
|
||||
$content['connect_url'] = sprintf('wss://%s/wss', $this->request->getHttpHost());
|
||||
list($domain) = explode(':', $websocket->connect_address);
|
||||
$content['connect_url'] = sprintf('wss://%s/wss', $domain);
|
||||
} else {
|
||||
$content['connect_url'] = sprintf('ws://%s', $websocket->connect_address);
|
||||
}
|
||||
|
@ -7,9 +7,11 @@
|
||||
|
||||
namespace App\Http\Api\Controllers;
|
||||
|
||||
use App\Models\Question as QuestionModel;
|
||||
use App\Services\Logic\Question\AnswerList as AnswerListService;
|
||||
use App\Services\Logic\Question\CategoryList as CategoryListService;
|
||||
use App\Services\Logic\Question\CommentList as CommentListService;
|
||||
use App\Services\Logic\Question\QuestionDelete as QuestionDeleteService;
|
||||
use App\Services\Logic\Question\QuestionFavorite as QuestionFavoriteService;
|
||||
use App\Services\Logic\Question\QuestionInfo as QuestionInfoService;
|
||||
use App\Services\Logic\Question\QuestionLike as QuestionLikeService;
|
||||
@ -54,6 +56,17 @@ class QuestionController extends Controller
|
||||
|
||||
$question = $service->handle($id);
|
||||
|
||||
if ($question['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$approved = $question['published'] == QuestionModel::PUBLISH_APPROVED;
|
||||
$owned = $question['me']['owned'] == 1;
|
||||
|
||||
if (!$approved && !$owned) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['question' => $question]);
|
||||
}
|
||||
|
||||
@ -81,6 +94,18 @@ class QuestionController extends Controller
|
||||
return $this->jsonPaginate($pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/delete", name="api.question.delete")
|
||||
*/
|
||||
public function deleteAction($id)
|
||||
{
|
||||
$service = new QuestionDeleteService();
|
||||
|
||||
$service->handle($id);
|
||||
|
||||
return $this->jsonSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/favorite", name="api.question.favorite")
|
||||
*/
|
||||
|
@ -43,6 +43,14 @@ class RefundController extends Controller
|
||||
|
||||
$refund = $service->handle($sn);
|
||||
|
||||
if ($refund['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($refund['me']['owned'] == 0) {
|
||||
$this->forbidden();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['refund' => $refund]);
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
namespace App\Http\Api\Controllers;
|
||||
|
||||
use App\Models\Review as ReviewModel;
|
||||
use App\Services\Logic\Review\ReviewCreate as ReviewCreateService;
|
||||
use App\Services\Logic\Review\ReviewDelete as ReviewDeleteService;
|
||||
use App\Services\Logic\Review\ReviewInfo as ReviewInfoService;
|
||||
@ -28,6 +29,17 @@ class ReviewController extends Controller
|
||||
|
||||
$review = $service->handle($id);
|
||||
|
||||
if ($review['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$approved = $review['published'] == ReviewModel::PUBLISH_APPROVED;
|
||||
$owned = $review['me']['owned'] == 1;
|
||||
|
||||
if (!$approved && !$owned) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['review' => $review]);
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,14 @@ class TradeController extends Controller
|
||||
|
||||
$trade = $service->handle($sn);
|
||||
|
||||
if ($trade['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($trade['me']['owned'] == 0) {
|
||||
$this->forbidden();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['trade' => $trade]);
|
||||
}
|
||||
|
||||
@ -54,6 +62,18 @@ class TradeController extends Controller
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/mini/create", name="api.trade.mini_create")
|
||||
*/
|
||||
public function createMiniTradeAction()
|
||||
{
|
||||
$service = new TradeService();
|
||||
|
||||
$content = $service->createMiniTrade();
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/app/create", name="api.trade.app_create")
|
||||
*/
|
||||
@ -61,7 +81,7 @@ class TradeController extends Controller
|
||||
{
|
||||
$service = new TradeService();
|
||||
|
||||
$content = $service->createMpTrade();
|
||||
$content = $service->createAppTrade();
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
@ -30,6 +30,10 @@ class UserController extends Controller
|
||||
|
||||
$user = $service->handle($id);
|
||||
|
||||
if ($user['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['user' => $user]);
|
||||
}
|
||||
|
||||
|
210
app/Http/Api/Services/Connect.php
Normal file
210
app/Http/Api/Services/Connect.php
Normal file
@ -0,0 +1,210 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Http\Api\Services;
|
||||
|
||||
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\Services\Auth\Api as ApiAuthService;
|
||||
use App\Services\Logic\Notice\AccountLogin as AccountLoginNoticeService;
|
||||
use App\Services\OAuth\QQ as QQAuth;
|
||||
use App\Services\OAuth\WeChat as WeChatAuth;
|
||||
use App\Services\OAuth\WeiBo as WeiBoAuth;
|
||||
use Exception;
|
||||
|
||||
class Connect extends Service
|
||||
{
|
||||
|
||||
public function getWechatInfo()
|
||||
{
|
||||
return [
|
||||
'auth_url' => kg_full_url(['for' => 'api.oauth.wechat']),
|
||||
'auto_login' => 1,
|
||||
];
|
||||
}
|
||||
|
||||
public function getWechatRedirectCache()
|
||||
{
|
||||
return $this->session->get('wechat_redirect');
|
||||
}
|
||||
|
||||
public function setWechatRedirectCache($redirect)
|
||||
{
|
||||
$this->session->set('wechat_redirect', $redirect);
|
||||
}
|
||||
|
||||
public function removeWechatRedirectCache()
|
||||
{
|
||||
$this->session->remove('wechat_redirect');
|
||||
}
|
||||
|
||||
public function handleCallback($provider)
|
||||
{
|
||||
$code = $this->request->getQuery('code');
|
||||
$state = $this->request->getQuery('state');
|
||||
|
||||
$openUser = $this->getOpenUserInfo($code, $state, $provider);
|
||||
$relation = $this->getConnectRelation($openUser['id'], $provider);
|
||||
|
||||
$token = null;
|
||||
|
||||
if ($relation) {
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$user = $userRepo->findById($relation->user_id);
|
||||
|
||||
$auth = new ApiAuthService();
|
||||
|
||||
$token = $auth->saveAuthInfo($user);
|
||||
|
||||
$this->handleLoginNotice($user);
|
||||
}
|
||||
|
||||
return [
|
||||
'openid' => $openUser['id'],
|
||||
'token' => $token,
|
||||
];
|
||||
}
|
||||
|
||||
public function getAuthorizeUrl($provider)
|
||||
{
|
||||
$auth = $this->getConnectAuth($provider);
|
||||
|
||||
return $auth->getAuthorizeUrl();
|
||||
}
|
||||
|
||||
public function getOpenUserInfo($code, $state, $provider)
|
||||
{
|
||||
$auth = $this->getConnectAuth($provider);
|
||||
|
||||
$auth->checkState($state);
|
||||
|
||||
$token = $auth->getAccessToken($code);
|
||||
|
||||
$openId = $auth->getOpenId($token);
|
||||
|
||||
return $auth->getUserInfo($token, $openId);
|
||||
}
|
||||
|
||||
public function getConnectRelation($openId, $provider)
|
||||
{
|
||||
$connectRepo = new ConnectRepo();
|
||||
|
||||
return $connectRepo->findByOpenId($openId, $provider);
|
||||
}
|
||||
|
||||
public function getConnectAuth($provider)
|
||||
{
|
||||
$auth = null;
|
||||
|
||||
switch ($provider) {
|
||||
case ConnectModel::PROVIDER_QQ:
|
||||
$auth = $this->getQQAuth();
|
||||
break;
|
||||
case ConnectModel::PROVIDER_WEIBO:
|
||||
$auth = $this->getWeiBoAuth();
|
||||
break;
|
||||
case ConnectModel::PROVIDER_WECHAT:
|
||||
$auth = $this->getWeChatAuth();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$auth) {
|
||||
throw new Exception('Invalid OAuth Provider');
|
||||
}
|
||||
|
||||
return $auth;
|
||||
}
|
||||
|
||||
protected function getQQAuth()
|
||||
{
|
||||
$settings = $this->getSettings('oauth.qq');
|
||||
|
||||
$settings['redirect_uri'] = kg_full_url(['for' => 'api.oauth.qq_callback']);
|
||||
|
||||
return new QQAuth(
|
||||
$settings['client_id'],
|
||||
$settings['client_secret'],
|
||||
$settings['redirect_uri']
|
||||
);
|
||||
}
|
||||
|
||||
protected function getWeChatAuth()
|
||||
{
|
||||
/**
|
||||
* 使用的是微信公众号网页授权登录功能
|
||||
*/
|
||||
$settings = $this->getSettings('wechat.oa');
|
||||
|
||||
$settings['redirect_uri'] = kg_full_url(['for' => 'api.oauth.wechat_callback']);
|
||||
|
||||
return new WeChatAuth(
|
||||
$settings['app_id'],
|
||||
$settings['app_secret'],
|
||||
$settings['redirect_uri']
|
||||
);
|
||||
}
|
||||
|
||||
protected function getWeiBoAuth()
|
||||
{
|
||||
$settings = $this->getSettings('oauth.weibo');
|
||||
|
||||
$settings['redirect_uri'] = kg_full_url(['for' => 'api.oauth.weibo_callback']);
|
||||
|
||||
return new WeiBoAuth(
|
||||
$settings['client_id'],
|
||||
$settings['client_secret'],
|
||||
$settings['redirect_uri']
|
||||
);
|
||||
}
|
||||
|
||||
protected function handleConnectRelation(UserModel $user, array $openUser)
|
||||
{
|
||||
$connectRepo = new ConnectRepo();
|
||||
|
||||
$connect = $connectRepo->findByOpenId($openUser['id'], $openUser['provider']);
|
||||
|
||||
if ($connect) {
|
||||
|
||||
$connect->open_name = $openUser['name'];
|
||||
$connect->open_avatar = $openUser['avatar'];
|
||||
|
||||
if ($connect->user_id != $user->id) {
|
||||
$connect->user_id = $user->id;
|
||||
}
|
||||
|
||||
if ($connect->deleted == 1) {
|
||||
$connect->deleted = 0;
|
||||
}
|
||||
|
||||
$connect->update();
|
||||
|
||||
} else {
|
||||
|
||||
$connect = new ConnectModel();
|
||||
|
||||
$connect->user_id = $user->id;
|
||||
$connect->open_id = $openUser['id'];
|
||||
$connect->open_name = $openUser['name'];
|
||||
$connect->open_avatar = $openUser['avatar'];
|
||||
$connect->provider = $openUser['provider'];
|
||||
|
||||
$connect->create();
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleLoginNotice(UserModel $user)
|
||||
{
|
||||
$service = new AccountLoginNoticeService();
|
||||
|
||||
$service->createTask($user);
|
||||
}
|
||||
|
||||
}
|
@ -75,6 +75,45 @@ class Trade extends Service
|
||||
{
|
||||
$post = $this->request->getPost();
|
||||
|
||||
$order = $this->checkOrderBySn($post['order_sn']);
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$channel = TradeModel::CHANNEL_WXPAY;
|
||||
|
||||
$trade = new TradeModel();
|
||||
|
||||
$trade->subject = $order->subject;
|
||||
$trade->amount = $order->amount;
|
||||
$trade->channel = $channel;
|
||||
$trade->order_id = $order->id;
|
||||
$trade->owner_id = $user->id;
|
||||
|
||||
$trade->create();
|
||||
|
||||
$wxpay = new Wxpay();
|
||||
|
||||
$response = $wxpay->mp($trade, $post['open_id']);
|
||||
|
||||
$payment = [
|
||||
'appId' => $response->appId,
|
||||
'timeStamp' => $response->timeStamp,
|
||||
'nonceStr' => $response->nonceStr,
|
||||
'package' => $response->package,
|
||||
'signType' => $response->signType,
|
||||
'paySign' => $response->paySign,
|
||||
];
|
||||
|
||||
return [
|
||||
'trade' => $this->handleTradeInfo($trade->sn),
|
||||
'payment' => $payment,
|
||||
];
|
||||
}
|
||||
|
||||
public function createMiniTrade()
|
||||
{
|
||||
$post = $this->request->getPost();
|
||||
|
||||
$validator = new ClientValidator();
|
||||
|
||||
$platform = $this->getPlatform();
|
||||
@ -120,7 +159,7 @@ class Trade extends Service
|
||||
|
||||
public function createAppTrade()
|
||||
{
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function getPlatform()
|
||||
|
@ -28,6 +28,10 @@ class AccountController extends Controller
|
||||
|
||||
$returnUrl = $this->request->getHTTPReferer();
|
||||
|
||||
$service = new OAuthProviderService();
|
||||
|
||||
$oauthProvider = $service->handle();
|
||||
|
||||
$service = new AccountService();
|
||||
|
||||
$captcha = $service->getSettings('captcha');
|
||||
@ -35,6 +39,7 @@ class AccountController extends Controller
|
||||
$this->seo->prependTitle('注册');
|
||||
|
||||
$this->view->setVar('return_url', $returnUrl);
|
||||
$this->view->setVar('local_oauth', $oauthProvider['local']);
|
||||
$this->view->setVar('captcha', $captcha);
|
||||
}
|
||||
|
||||
|
@ -57,8 +57,15 @@ class AnswerController extends Controller
|
||||
|
||||
$answer = $service->handle($id);
|
||||
|
||||
if ($answer['published'] != AnswerModel::PUBLISH_APPROVED) {
|
||||
return $this->notFound();
|
||||
if ($answer['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$approved = $answer['published'] != AnswerModel::PUBLISH_APPROVED;
|
||||
$owned = $answer['me']['owned'] == 1;
|
||||
|
||||
if (!$approved && !$owned) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$questionId = $answer['question']['id'];
|
||||
|
@ -10,12 +10,14 @@ namespace App\Http\Home\Controllers;
|
||||
use App\Http\Home\Services\Article as ArticleService;
|
||||
use App\Http\Home\Services\ArticleQuery as ArticleQueryService;
|
||||
use App\Models\Article as ArticleModel;
|
||||
use App\Services\Logic\Article\ArticleClose as ArticleCloseService;
|
||||
use App\Services\Logic\Article\ArticleCreate as ArticleCreateService;
|
||||
use App\Services\Logic\Article\ArticleDelete as ArticleDeleteService;
|
||||
use App\Services\Logic\Article\ArticleFavorite as ArticleFavoriteService;
|
||||
use App\Services\Logic\Article\ArticleInfo as ArticleInfoService;
|
||||
use App\Services\Logic\Article\ArticleLike as ArticleLikeService;
|
||||
use App\Services\Logic\Article\ArticleList as ArticleListService;
|
||||
use App\Services\Logic\Article\ArticlePrivate as ArticlePrivateService;
|
||||
use App\Services\Logic\Article\ArticleUpdate as ArticleUpdateService;
|
||||
use App\Services\Logic\Article\RelatedArticleList as RelatedArticleListService;
|
||||
use Phalcon\Mvc\View;
|
||||
@ -103,8 +105,20 @@ class ArticleController extends Controller
|
||||
|
||||
$article = $service->handle($id);
|
||||
|
||||
if ($article['published'] != ArticleModel::PUBLISH_APPROVED) {
|
||||
return $this->notFound();
|
||||
if ($article['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$approved = $article['published'] == ArticleModel::PUBLISH_APPROVED;
|
||||
$owned = $article['me']['owned'] == 1;
|
||||
$private = $article['private'] == 1;
|
||||
|
||||
if (!$approved && !$owned) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($private && !$owned) {
|
||||
$this->forbidden();
|
||||
}
|
||||
|
||||
$this->seo->prependTitle(['专栏', $article['title']]);
|
||||
@ -195,6 +209,34 @@ class ArticleController extends Controller
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/close", name="home.article.close")
|
||||
*/
|
||||
public function closeAction($id)
|
||||
{
|
||||
$service = new ArticleCloseService();
|
||||
|
||||
$article = $service->handle($id);
|
||||
|
||||
$msg = $article->closed == 1 ? '关闭评论成功' : '开启评论成功';
|
||||
|
||||
return $this->jsonSuccess(['msg' => $msg]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/private", name="home.article.private")
|
||||
*/
|
||||
public function privateAction($id)
|
||||
{
|
||||
$service = new ArticlePrivateService();
|
||||
|
||||
$article = $service->handle($id);
|
||||
|
||||
$msg = $article->private == 1 ? '开启仅我可见成功' : '关闭仅我可见成功';
|
||||
|
||||
return $this->jsonSuccess(['msg' => $msg]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/favorite", name="home.article.favorite")
|
||||
*/
|
||||
|
@ -39,20 +39,24 @@ class ChapterController extends Controller
|
||||
*/
|
||||
public function showAction($id)
|
||||
{
|
||||
$service = new ChapterInfoService();
|
||||
|
||||
$chapter = $service->handle($id);
|
||||
|
||||
if ($chapter['published'] == 0) {
|
||||
return $this->notFound();
|
||||
}
|
||||
|
||||
if ($this->authUser->id == 0) {
|
||||
return $this->response->redirect(['for' => 'home.account.login']);
|
||||
}
|
||||
|
||||
$service = new ChapterInfoService();
|
||||
|
||||
$chapter = $service->handle($id);
|
||||
|
||||
if ($chapter['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($chapter['published'] == 0) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($chapter['me']['owned'] == 0) {
|
||||
return $this->forbidden();
|
||||
$this->forbidden();
|
||||
}
|
||||
|
||||
$service = new CourseInfoService();
|
||||
|
@ -119,6 +119,19 @@ class ConnectController extends Controller
|
||||
|
||||
$service = new ConnectService();
|
||||
|
||||
$openUser = $service->getOpenUserInfo($code, $state, $provider);
|
||||
|
||||
/**
|
||||
* 微信扫码登录检查是否关注过公众号,关注过直接登录
|
||||
*/
|
||||
if ($provider == ConnectModel::PROVIDER_WEIXIN && !empty($openUser['unionid'])) {
|
||||
$subscribe = $service->getWeChatSubscribe($openUser['unionid']);
|
||||
if ($subscribe && $subscribe->deleted == 0) {
|
||||
$service->authSubscribeLogin($subscribe);
|
||||
return $this->response->redirect(['for' => 'home.index']);
|
||||
}
|
||||
}
|
||||
|
||||
$openUser = $service->getOpenUserInfo($code, $state, $provider);
|
||||
$connect = $service->getConnectRelation($openUser['id'], $openUser['provider']);
|
||||
|
||||
@ -129,7 +142,7 @@ class ConnectController extends Controller
|
||||
}
|
||||
} else {
|
||||
if ($connect) {
|
||||
$service->authLogin($connect);
|
||||
$service->authConnectLogin($connect);
|
||||
return $this->response->redirect(['for' => 'home.index']);
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Models\Consult as ConsultModel;
|
||||
use App\Services\Logic\Consult\ConsultCreate as ConsultCreateService;
|
||||
use App\Services\Logic\Consult\ConsultDelete as ConsultDeleteService;
|
||||
use App\Services\Logic\Consult\ConsultInfo as ConsultInfoService;
|
||||
@ -37,6 +38,17 @@ class ConsultController extends Controller
|
||||
|
||||
$consult = $service->handle($id);
|
||||
|
||||
if ($consult['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$approved = $consult['published'] == ConsultModel::PUBLISH_APPROVED;
|
||||
$owned = $consult['me']['owned'] == 1;
|
||||
|
||||
if (!$approved && !$owned) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$this->view->setVar('consult', $consult);
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,8 @@ class Controller extends \Phalcon\Mvc\Controller
|
||||
* ssl通过nginx转发实现
|
||||
*/
|
||||
if ($this->request->isSecure()) {
|
||||
$websocket->connect_url = sprintf('wss://%s/wss', $this->request->getHttpHost());
|
||||
list($domain) = explode(':', $websocket->connect_address);
|
||||
$websocket->connect_url = sprintf('wss://%s/wss', $domain);
|
||||
} else {
|
||||
$websocket->connect_url = sprintf('ws://%s', $websocket->connect_address);
|
||||
}
|
||||
|
@ -77,8 +77,12 @@ class CourseController extends Controller
|
||||
|
||||
$course = $service->handle($id);
|
||||
|
||||
if ($course['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($course['published'] == 0) {
|
||||
return $this->notFound();
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$service = new CourseChapterListService();
|
||||
|
@ -40,8 +40,12 @@ class HelpController extends Controller
|
||||
|
||||
$help = $service->handle($id);
|
||||
|
||||
if ($help['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($help['published'] == 0) {
|
||||
return $this->notFound();
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$featuredCourses = $this->getFeaturedCourses();
|
||||
|
@ -145,7 +145,7 @@ class ImController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/notice/read", name="home.im.read_notice")
|
||||
* @Get("/notice/read", name="home.im.read_notice")
|
||||
*/
|
||||
public function readNoticeAction()
|
||||
{
|
||||
|
@ -51,8 +51,12 @@ class ImGroupController extends Controller
|
||||
|
||||
$group = $service->getGroup($id);
|
||||
|
||||
if ($group['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($group['published'] == 0) {
|
||||
return $this->notFound();
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$this->seo->prependTitle(['群组', $group['name']]);
|
||||
|
@ -45,6 +45,14 @@ class OrderController extends Controller
|
||||
|
||||
$order = $service->handle($sn);
|
||||
|
||||
if ($order['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($order['me']['owned'] == 0) {
|
||||
$this->forbidden();
|
||||
}
|
||||
|
||||
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
|
||||
$this->view->setVar('order', $order);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class PackageController extends Controller
|
||||
$package = $service->handle($id);
|
||||
|
||||
if ($package['published'] == 0) {
|
||||
return $this->notFound();
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$this->seo->prependTitle(['套餐', $package['title']]);
|
||||
|
@ -25,8 +25,12 @@ class PageController extends Controller
|
||||
|
||||
$page = $service->handle($id);
|
||||
|
||||
if ($page['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($page['published'] == 0) {
|
||||
return $this->notFound();
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$featuredCourses = $this->getFeaturedCourses();
|
||||
|
@ -68,8 +68,12 @@ class PointGiftController extends Controller
|
||||
|
||||
$gift = $service->handle($id);
|
||||
|
||||
if ($gift['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($gift['published'] == 0) {
|
||||
return $this->notFound();
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$hotGifts = $this->getHotGifts();
|
||||
|
@ -102,8 +102,15 @@ class QuestionController extends Controller
|
||||
|
||||
$question = $service->handle($id);
|
||||
|
||||
if ($question['published'] != QuestionModel::PUBLISH_APPROVED) {
|
||||
return $this->notFound();
|
||||
if ($question['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$approved = $question['published'] == QuestionModel::PUBLISH_APPROVED;
|
||||
$owned = $question['me']['owned'] == 1;
|
||||
|
||||
if (!$approved && !$owned) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$this->seo->prependTitle(['问答', $question['title']]);
|
||||
|
@ -63,6 +63,14 @@ class RefundController extends Controller
|
||||
|
||||
$refund = $service->handle($sn);
|
||||
|
||||
if ($refund['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
if ($refund['me']['owned'] == 0) {
|
||||
$this->forbidden();
|
||||
}
|
||||
|
||||
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
|
||||
$this->view->setVar('refund', $refund);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Models\Review as ReviewModel;
|
||||
use App\Services\Logic\Review\ReviewCreate as ReviewCreateService;
|
||||
use App\Services\Logic\Review\ReviewDelete as ReviewDeleteService;
|
||||
use App\Services\Logic\Review\ReviewInfo as ReviewInfoService;
|
||||
@ -50,6 +51,17 @@ class ReviewController extends Controller
|
||||
|
||||
$review = $service->handle($id);
|
||||
|
||||
if ($review['deleted'] == 1) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$approved = $review['published'] == ReviewModel::PUBLISH_APPROVED;
|
||||
$owned = $review['me']['owned'] == 1;
|
||||
|
||||
if (!$approved && !$owned) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
return $this->jsonSuccess(['review' => $review]);
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ class TopicController extends Controller
|
||||
$topic = $service->handle($id);
|
||||
|
||||
if ($topic['published'] == 0) {
|
||||
return $this->notFound();
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$this->seo->prependTitle(['专题', $topic['title']]);
|
||||
|
@ -32,7 +32,7 @@ class UserController extends Controller
|
||||
$user = $service->handle($id);
|
||||
|
||||
if ($user['deleted'] == 1) {
|
||||
return $this->notFound();
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$this->seo->prependTitle(['空间', $user['name']]);
|
||||
|
@ -9,11 +9,14 @@ namespace App\Http\Home\Services;
|
||||
|
||||
use App\Models\Connect as ConnectModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Models\WeChatSubscribe as WeChatSubscribeModel;
|
||||
use App\Repos\Connect as ConnectRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
use App\Repos\WeChatSubscribe as WeChatSubscribeRepo;
|
||||
use App\Services\Auth\Home as AuthService;
|
||||
use App\Services\Auth\Home as HomeAuthService;
|
||||
use App\Services\Logic\Account\Register as RegisterService;
|
||||
use App\Services\Logic\Notice\AccountLogin as AccountLoginNoticeService;
|
||||
use App\Services\Logic\Notice\AccountLogin as AccountLoginNotice;
|
||||
use App\Services\OAuth\QQ as QQAuth;
|
||||
use App\Services\OAuth\WeiBo as WeiBoAuth;
|
||||
use App\Services\OAuth\WeiXin as WeiXinAuth;
|
||||
@ -79,7 +82,20 @@ class Connect extends Service
|
||||
$this->handleConnectRelation($user, $openUser);
|
||||
}
|
||||
|
||||
public function authLogin(ConnectModel $connect)
|
||||
public function authSubscribeLogin(WeChatSubscribeModel $subscribe)
|
||||
{
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$user = $userRepo->findById($subscribe->user_id);
|
||||
|
||||
$this->handleLoginNotice($user);
|
||||
|
||||
$auth = new HomeAuthService();
|
||||
|
||||
$auth->saveAuthInfo($user);
|
||||
}
|
||||
|
||||
public function authConnectLogin(ConnectModel $connect)
|
||||
{
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
@ -112,6 +128,13 @@ class Connect extends Service
|
||||
return $auth->getUserInfo($token, $openId);
|
||||
}
|
||||
|
||||
public function getWeChatSubscribe($unionId)
|
||||
{
|
||||
$subscribeRepo = new WeChatSubscribeRepo();
|
||||
|
||||
return $subscribeRepo->findByUnionId($unionId);
|
||||
}
|
||||
|
||||
public function getConnectRelation($openId, $provider)
|
||||
{
|
||||
$connectRepo = new ConnectRepo();
|
||||
@ -200,6 +223,14 @@ class Connect extends Service
|
||||
$connect->user_id = $user->id;
|
||||
}
|
||||
|
||||
if (empty($connect->union_id) && !empty($openUser['unionid'])) {
|
||||
$connect->union_id = $openUser['unionid'];
|
||||
}
|
||||
|
||||
if ($connect->deleted == 1) {
|
||||
$connect->deleted = 0;
|
||||
}
|
||||
|
||||
$connect->update();
|
||||
|
||||
} else {
|
||||
@ -207,6 +238,7 @@ class Connect extends Service
|
||||
$connect = new ConnectModel();
|
||||
|
||||
$connect->user_id = $user->id;
|
||||
$connect->union_id = $openUser['unionid'];
|
||||
$connect->open_id = $openUser['id'];
|
||||
$connect->open_name = $openUser['name'];
|
||||
$connect->open_avatar = $openUser['avatar'];
|
||||
@ -218,9 +250,9 @@ class Connect extends Service
|
||||
|
||||
protected function handleLoginNotice(UserModel $user)
|
||||
{
|
||||
$service = new AccountLoginNoticeService();
|
||||
$notice = new AccountLoginNotice();
|
||||
|
||||
$service->createTask($user);
|
||||
$notice->createTask($user);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -114,7 +114,8 @@ class WeChatOfficialAccount extends Service
|
||||
$subscribe = $subscribeRepo->findByOpenId($openId);
|
||||
|
||||
if ($subscribe) {
|
||||
$subscribe->delete();
|
||||
$subscribe->deleted = 1;
|
||||
$subscribe->update();
|
||||
}
|
||||
|
||||
return new TextMessage('伤心呀,我们又少了一个小伙伴!');
|
||||
@ -128,7 +129,9 @@ class WeChatOfficialAccount extends Service
|
||||
$userId = str_replace('qrscene_', '', $eventKey);
|
||||
|
||||
if ($userId && $openId) {
|
||||
$this->saveWechatSubscribe($userId, $openId);
|
||||
$userInfo = $this->getUserInfo($openId);
|
||||
$unionId = $userInfo['unionid'] ?: '';
|
||||
$this->saveWechatSubscribe($userId, $openId, $unionId);
|
||||
}
|
||||
|
||||
return $this->emptyReply();
|
||||
@ -194,7 +197,7 @@ class WeChatOfficialAccount extends Service
|
||||
return new TextMessage('没有匹配的服务哦!');
|
||||
}
|
||||
|
||||
protected function saveWechatSubscribe($userId, $openId)
|
||||
protected function saveWechatSubscribe($userId, $openId, $unionId = '')
|
||||
{
|
||||
if (!$userId || !$openId) return;
|
||||
|
||||
@ -211,14 +214,35 @@ class WeChatOfficialAccount extends Service
|
||||
if ($subscribe) {
|
||||
if ($subscribe->user_id != $userId) {
|
||||
$subscribe->user_id = $userId;
|
||||
$subscribe->update();
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
protected function getUserInfo($openId)
|
||||
{
|
||||
$app = $this->getOfficialAccount();
|
||||
|
||||
return $app->user->get($openId);
|
||||
}
|
||||
|
||||
protected function getWechatLogger()
|
||||
{
|
||||
$service = new WeChatService();
|
||||
|
||||
return $service->logger;
|
||||
}
|
||||
|
||||
}
|
||||
|
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