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

修复更新递减数值溢出,完善用户中心

This commit is contained in:
xiaochong0302 2020-07-24 20:27:14 +08:00
parent 199845cfd0
commit b7bd710cd9
53 changed files with 695 additions and 26495 deletions

View File

@ -2,6 +2,7 @@
namespace App\Builders;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
@ -47,6 +48,23 @@ class ConsultList extends Builder
return $result;
}
public function getChapters(array $consults)
{
$ids = kg_array_column($consults, 'chapter_id');
$chapterRepo = new ChapterRepo();
$chapters = $chapterRepo->findByIds($ids, ['id', 'title']);
$result = [];
foreach ($chapters->toArray() as $chapter) {
$result[$chapter['id']] = $chapter;
}
return $result;
}
public function getUsers(array $consults)
{
$ids = kg_array_column($consults, 'user_id');

View File

@ -112,6 +112,7 @@ class Course extends Service
$logger = $this->getLogger();
$logger->error('Create Course Error ' . kg_json_encode([
'line' => $e->getLine(),
'code' => $e->getCode(),
'message' => $e->getMessage(),
]));

View File

@ -7,6 +7,7 @@ use App\Services\Frontend\Consult\ConsultDelete as ConsultDeleteService;
use App\Services\Frontend\Consult\ConsultInfo as ConsultInfoService;
use App\Services\Frontend\Consult\ConsultLike as ConsultLikeService;
use App\Services\Frontend\Consult\ConsultUpdate as ConsultUpdateService;
use Phalcon\Mvc\View;
/**
* @RoutePrefix("/consult")
@ -19,21 +20,33 @@ class ConsultController extends Controller
*/
public function addAction()
{
$chapterId = $this->request->getQuery('chapter_id');
$this->view->setVar('chapter_id', $chapterId);
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
}
/**
* @Get("/{id:[0-9]+}/info", name="web.consult.info")
* @Get("/{id:[0-9]+}/edit", name="web.consult.edit")
*/
public function infoAction($id)
public function editAction($id)
{
$service = new ConsultInfoService();
$consult = $service->handle($id);
return $this->jsonSuccess(['consult' => $consult]);
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVar('consult', $consult);
}
/**
* @Get("/{id:[0-9]+}/show", name="web.consult.show")
*/
public function showAction($id)
{
$service = new ConsultInfoService();
$consult = $service->handle($id);
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVar('consult', $consult);
}
/**
@ -51,7 +64,7 @@ class ConsultController extends Controller
$content = [
'consult' => $consult,
'msg' => '提交课程咨询成功',
'msg' => '提交咨询成功',
];
return $this->jsonSuccess($content);
@ -68,7 +81,7 @@ class ConsultController extends Controller
$content = [
'consult' => $consult,
'msg' => '更新课程咨询成功',
'msg' => '更新咨询成功',
];
return $this->jsonSuccess($content);
@ -83,7 +96,7 @@ class ConsultController extends Controller
$service->handle($id);
$content = ['msg' => '删除课程咨询成功'];
$content = ['msg' => '删除咨询成功'];
return $this->jsonSuccess($content);
}

View File

@ -4,6 +4,9 @@ namespace App\Http\Web\Controllers;
use App\Services\Frontend\My\AccountInfo as AccountInfoService;
use App\Services\Frontend\My\ConsultList as MyConsultListService;
use App\Services\Frontend\My\CourseList as MyCourseListService;
use App\Services\Frontend\My\ImFriendDelete as MyFriendDeleteService;
use App\Services\Frontend\My\ImGroupDelete as MyGroupDeleteService;
use App\Services\Frontend\My\OrderList as MyOrderListService;
use App\Services\Frontend\My\RefundList as MyRefundListService;
use App\Services\Frontend\My\ReviewList as MyReviewListService;
@ -67,10 +70,12 @@ class MyController extends Controller
*/
public function coursesAction()
{
$service = new MyConsultListService();
$service = new MyCourseListService();
$pager = $service->handle();
$pager->items = kg_array_object($pager->items);
$this->view->setVar('pager', $pager);
}
@ -95,6 +100,8 @@ class MyController extends Controller
$pager = $service->handle();
$pager->items = kg_array_object($pager->items);
$this->view->setVar('pager', $pager);
}
@ -107,6 +114,8 @@ class MyController extends Controller
$pager = $service->handle();
$pager->items = kg_array_object($pager->items);
$this->view->setVar('pager', $pager);
}
@ -181,19 +190,31 @@ class MyController extends Controller
}
/**
* @Post("/friend/delete", name="web.my.delete_friend")
* @Post("/friend/{id:[0-9]+}/delete", name="web.my.delete_friend")
*/
public function deleteFriendAction()
public function deleteFriendAction($id)
{
$service = new MyFriendDeleteService();
$service->handle($id);
$content = ['msg' => '删除好友成功'];
return $this->jsonSuccess($content);
}
/**
* @Post("/group/delete", name="web.my.delete_group")
* @Post("/group/{id:[0-9]+}/delete", name="web.my.delete_group")
*/
public function deleteGroupAction()
public function deleteGroupAction($id)
{
$service = new MyGroupDeleteService();
$service->handle($id);
$content = ['msg' => '退出群组成功'];
return $this->jsonSuccess($content);
}
}

View File

@ -7,6 +7,7 @@ use App\Services\Frontend\Review\ReviewDelete as ReviewDeleteService;
use App\Services\Frontend\Review\ReviewInfo as ReviewInfoService;
use App\Services\Frontend\Review\ReviewLike as ReviewLikeService;
use App\Services\Frontend\Review\ReviewUpdate as ReviewUpdateService;
use Phalcon\Mvc\View;
/**
* @RoutePrefix("/review")
@ -19,9 +20,20 @@ class ReviewController extends Controller
*/
public function addAction()
{
$courseId = $this->request->getQuery('course_id');
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
}
$this->view->setVar('course_id', $courseId);
/**
* @Get("/{id:[0-9]+}/edit", name="web.review.edit")
*/
public function editAction($id)
{
$service = new ReviewInfoService();
$review = $service->handle($id);
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVar('review', $review);
}
/**
@ -51,7 +63,7 @@ class ReviewController extends Controller
$content = [
'review' => $review,
'msg' => '发布课程评价成功',
'msg' => '发布评价成功',
];
return $this->jsonSuccess($content);
@ -64,11 +76,15 @@ class ReviewController extends Controller
{
$service = new ReviewUpdateService();
$service->handle($id);
$service = new ReviewInfoService();
$review = $service->handle($id);
$content = [
'review' => $review,
'msg' => '更新课程评价成功',
'msg' => '更新评价成功',
];
return $this->jsonSuccess($content);
@ -83,7 +99,7 @@ class ReviewController extends Controller
$service->handle($id);
$content = ['msg' => '删除课程评价成功'];
$content = ['msg' => '删除评价成功'];
return $this->jsonSuccess($content);
}

View File

@ -29,7 +29,7 @@ Trait ImFriendTrait
$group = $validator->checkGroup($post['group_id']);
$remark = $validator->checkRemark($post['remark']);
$validator->checkIfSelfApply($user->id, $friend->id);
$validator->checkIfSelf($user->id, $friend->id);
$validator->checkIfJoined($user->id, $friend->id);
$validator->checkIfBlocked($user->id, $friend->id);

View File

@ -9,7 +9,7 @@
</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="private" value="1" title="是">
<input type="radio" name="private" value="0" title="否" checked="checked">
@ -20,7 +20,7 @@
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<input type="hidden" name="chapter_id" value="{{ chapter_id }}">
<input type="hidden" name="chapter_id" value="{{ request.get('chapter_id') }}">
</div>
</div>
</form>

View File

@ -0,0 +1,37 @@
{% extends 'templates/layer.volt' %}
{% block content %}
{% set update_url = url({'for':'web.consult.update','id':consult.id}) %}
<form class="layui-form" method="post" action="{{ update_url }}">
<div class="layui-form-item mb0">
<label class="layui-form-label">课程</label>
<div class="layui-form-mid">{{ consult.course.title }}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">章节</label>
<div class="layui-form-mid">{{ consult.chapter.title }}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">咨询内容</label>
<div class="layui-input-block">
<textarea name="question" class="layui-textarea" lay-verify="required">{{ consult.question }}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">私密</label>
<div class="layui-input-block">
<input type="radio" name="private" value="1" title="是" {% if consult.private == 1 %}checked="checked"{% endif %}>
<input type="radio" name="private" value="0" title="否" {% if consult.private == 0 %}checked="checked"{% endif %}>
</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="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,27 @@
{% extends 'templates/layer.volt' %}
{% block content %}
<form class="layui-form" method="post" action="{{ url({'for':'web.consult.create'}) }}">
<div class="layui-form-item">
<label class="layui-form-label">咨询内容</label>
<div class="layui-input-block">
<textarea name="question" class="layui-textarea" placeholder="请详细描述问题,我们会尽快回复您" lay-verify="required"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">私密问题</label>
<div class="layui-input-block">
<input type="radio" name="private" value="1" title="是">
<input type="radio" name="private" value="0" title="否" checked="checked">
</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="reset" class="layui-btn layui-btn-primary">重置</button>
<input type="hidden" name="chapter_id" value="{{ request.get('chapter_id') }}">
</div>
</div>
</form>
{% endblock %}

View File

@ -1,9 +1,4 @@
{%- macro star_info(rating) %}
{% set stars = [1,2,3,4,5] %}
{% for val in stars if val <= rating %}
<i class="layui-icon layui-icon-star-fill"></i>
{% endfor %}
{%- endmacro %}
{{ partial('partials/macro_course') }}
{% if pager.total_pages > 0 %}
<div class="review-list">

View File

@ -0,0 +1,59 @@
{% extends 'templates/full.volt' %}
{% block content %}
{{ partial('partials/macro_course') }}
<div class="layout-main">
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="wrap">
<div class="my-nav-title">我的咨询</div>
{% if pager.total_pages > 0 %}
<table class="layui-table review-table">
<colgroup>
<col>
<col>
<col width="20%">
</colgroup>
<thead>
<tr>
<th>内容</th>
<th>时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in pager.items %}
{% set item.answer = item.answer ? item.answer : '请耐心等待我们的回复吧' %}
{% set show_url = url({'for':'web.consult.show','id':item.id}) %}
{% set edit_url = url({'for':'web.consult.edit','id':item.id}) %}
{% set delete_url = url({'for':'web.consult.delete','id':item.id}) %}
<tr>
<td>
<p class="content layui-elip" title="{{ item.question|e }}">提问:{{ item.question }}</p>
<p class="content layui-elip" title="{{ item.answer|e }}">回复:{{ item.answer }}</p>
</td>
<td>{{ date('Y-m-d',item.create_time) }}</td>
<td>
<button class="layui-btn layui-btn-xs layui-bg-green btn-show-consult" data-url="{{ show_url }}">详情</button>
<button class="layui-btn layui-btn-xs layui-bg-blue btn-edit-consult" data-url="{{ edit_url }}">修改</button>
<button class="layui-btn layui-btn-xs layui-bg-red kg-delete" data-url="{{ delete_url }}">删除</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ partial('partials/pager') }}
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% block include_js %}
{{ js_include('web/js/my.js') }}
{% endblock %}

View File

@ -0,0 +1,56 @@
{% extends 'templates/full.volt' %}
{% block content %}
<div class="layout-main">
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="wrap">
<div class="my-nav-title">我的课程</div>
{% if pager.total_pages > 0 %}
<table class="layui-table" lay-size="lg">
<colgroup>
<col>
<col>
<col>
<col width="15%">
</colgroup>
<thead>
<tr>
<th>课程</th>
<th>进度</th>
<th>过期时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in pager.items %}
{% set course_url = url({'for':'web.course.show','id':item.course.id}) %}
{% set review_url = url({'for':'web.review.add'},{'id':item.course.id}) %}
<tr>
<td><a href="{{ course_url }}">{{ item.course.title }}</a></td>
<td>
<p>用时:{{ item.duration|duration }}</p>
<p>进度:{{ item.progress }}%</p>
</td>
<td>{{ date('Y-m-d', item.expiry_time) }}</td>
<td>
<button class="layui-btn layui-btn-sm btn-add-review" data-url="{{ review_url }}">评价</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ partial('partials/pager') }}
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% block include_js %}
{{ js_include('web/js/my.js') }}
{% endblock %}

View File

@ -38,13 +38,15 @@
<tbody>
{% for item in pager.items %}
{% set user_url = url({'for':'web.user.show','id':item.id}) %}
{% set delete_friend_url = url({'for':'web.my.delete_friend'}) %}
{% set delete_url = url({'for':'web.my.delete_friend','id':item.id}) %}
<tr>
<td><a href="{{ user_url }}" title="{{ item.about|e }}">{{ item.name }}</a></td>
<td>{{ gender_info(item.gender) }}</td>
<td>{{ item.location }}</td>
<td>{{ item.active_time|time_ago }}</td>
<td><a class="layui-btn layui-btn-sm btn-delete-friend" href="javascript:" data-friendId="{{ item.id }}" data-url="#">删除好友</a></td>
<td>
<button class="layui-btn layui-btn-sm kg-delete" data-url="{{ delete_url }}">删除</button>
</td>
</tr>
{% endfor %}
</tbody>

View File

@ -31,11 +31,13 @@
</thead>
<tbody>
{% for item in pager.items %}
{% set delete_group_url = url({'for':'web.my.delete_group'}) %}
{% set delete_url = url({'for':'web.my.delete_group','id':item.id}) %}
<tr>
<td><span title="{{ item.about|e }}">{{ item.name }}</span> {{ type_info(item.type) }}</td>
<td><span class="layui-badge-rim">{{ item.user_count }}</span></td>
<td><a class="layui-btn layui-btn-sm btn-delete-group" href="javascript:" data-groupId="{{ item.id }}" data-url="{{ delete_group_url }}">退出群组</a></td>
<td>
<button class="layui-btn layui-btn-sm kg-delete" data-tips="确定要退出吗?" data-url="{{ delete_url }}">退出</button>
</td>
</tr>
{% endfor %}
</tbody>

View File

@ -0,0 +1,61 @@
{% extends 'templates/full.volt' %}
{% block content %}
{{ partial('partials/macro_course') }}
<div class="layout-main">
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="wrap">
<div class="my-nav-title">我的评价</div>
{% if pager.total_pages > 0 %}
<table class="layui-table review-table">
<colgroup>
<col>
<col>
<col width="15%">
</colgroup>
<thead>
<tr>
<th>内容</th>
<th>评分</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in pager.items %}
{% set course_url = url({'for':'web.course.show','id':item.course.id}) %}
{% set edit_url = url({'for':'web.review.edit','id':item.id}) %}
{% set delete_url = url({'for':'web.review.delete','id':item.id}) %}
<tr>
<td>
<p class="title layui-elip">课程:<a href="{{ course_url }}">{{ item.course.title }}</a></p>
<p class="content layui-elip" title="{{ item.content|e }}">评价:{{ item.content }}</p>
</td>
<td>
<p class="rating">内容实用:{{ star_info(item.rating1) }}</p>
<p class="rating">通俗易懂:{{ star_info(item.rating2) }}</p>
<p class="rating">逻辑清晰:{{ star_info(item.rating3) }}</p>
</td>
<td>
<button class="layui-btn layui-btn-xs btn-edit-review" data-url="{{ edit_url }}">修改</button>
<button class="layui-btn layui-btn-xs layui-bg-red kg-delete" data-url="{{ delete_url }}">删除</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ partial('partials/pager') }}
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% block include_js %}
{{ js_include('web/js/my.js') }}
{% endblock %}

View File

@ -1,7 +1,10 @@
{% extends 'templates/layer.volt' %}
{% block content %}
<form class="layui-form rating-form" method="post" action="{{ url({'for':'web.review.create'}) }}">
{% set create_url = url({'for':'web.review.create'}) %}
<form class="layui-form review-form" method="post" action="{{ create_url }}">
<div class="layui-form-item mb0">
<label class="layui-form-label">内容实用</label>
<div class="layui-input-block">
@ -30,8 +33,8 @@
<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="layui-btn layui-btn-primary btn-cancel">取消</button>
<input type="hidden" name="course_id" value="{{ course.id }}">
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<input type="hidden" name="course_id" value="{{ request.get('course.id') }}">
<input type="hidden" name="rating1" value="5">
<input type="hidden" name="rating2" value="5">
<input type="hidden" name="rating3" value="5">
@ -42,6 +45,6 @@
{% block include_js %}
{{ js_include('web/js/course.rating.js') }}
{{ js_include('web/js/my.review.js') }}
{% endblock %}

View File

@ -0,0 +1,49 @@
{% extends 'templates/layer.volt' %}
{% block content %}
{% set update_url = url({'for':'web.review.update','id':review.id}) %}
<form class="layui-form review-form" method="post" action="{{ update_url }}">
<div class="layui-form-item mb0">
<label class="layui-form-label">内容实用</label>
<div class="layui-input-block">
<div id="rating1"></div>
</div>
</div>
<div class="layui-form-item mb0">
<label class="layui-form-label">通俗易懂</label>
<div class="layui-input-block">
<div id="rating2"></div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">逻辑清晰</label>
<div class="layui-input-block">
<div id="rating3"></div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评价内容</label>
<div class="layui-input-block">
<textarea name="content" class="layui-textarea">{{ review.content }}</textarea>
</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="reset" class="layui-btn layui-btn-primary">重置</button>
<input type="hidden" name="rating1" value="{{ review.rating1 }}">
<input type="hidden" name="rating2" value="{{ review.rating2 }}">
<input type="hidden" name="rating3" value="{{ review.rating3 }}">
</div>
</div>
</form>
{% endblock %}
{% block include_js %}
{{ js_include('web/js/my.review.js') }}
{% endblock %}

View File

@ -65,6 +65,7 @@ class Pay extends Listener
$this->db->rollback();
$this->logger->error('After Pay Event Error ' . kg_json_encode([
'line' => $e->getLine(),
'code' => $e->getCode(),
'message' => $e->getMessage(),
]));

48
app/Models/Area.php Normal file
View File

@ -0,0 +1,48 @@
<?php
namespace App\Models;
class Area extends Model
{
/**
* 区域类型
*/
const TYPE_PROVINCE = 'province';
const TYPE_CITY = 'city';
const TYPE_COUNTY = 'county';
/**
* 主键
*
* @var int
*/
public $id;
/**
* 类型
*
* @var string
*/
public $type;
/**
* 编码
*
* @var string
*/
public $code;
/**
* 名称
*
* @var string
*/
public $name;
public function getSource(): string
{
return 'kg_area';
}
}

View File

@ -53,16 +53,18 @@ class Register extends FrontendService
}
$user = new UserModel();
$user->id = $this->id;
$user->name = "user_{$this->id}";
$user->id = $account->id;
$user->name = "user_{$account->id}";
if ($user->create() === false) {
throw new \RuntimeException('Create User Failed');
}
$imUser = new ImUserModel();
$imUser->id = $this->id;
$imUser->name = "user_{$this->id}";
$imUser->id = $user->id;
$imUser->name = $user->name;
if ($imUser->create() === false) {
throw new \RuntimeException('Create ImUser Failed');
@ -79,6 +81,7 @@ class Register extends FrontendService
$logger = $this->getLogger();
$logger->error('Register Error ' . kg_json_encode([
'line' => $e->getLine(),
'code' => $e->getCode(),
'message' => $e->getMessage(),
]));

View File

@ -142,23 +142,21 @@ class ChapterInfo extends FrontendService
$this->incrChapterUserCount($chapter);
}
protected function getLiveStreamName($id)
{
return "chapter_{$id}";
}
protected function incrCourseUserCount(CourseModel $course)
{
$course->user_count += 1;
$course->update();
}
protected function incrChapterUserCount(ChapterModel $chapter)
{
$chapter->user_count += 1;
$chapter->update();
}
protected function getLiveStreamName($id)
{
return "chapter_{$id}";
}
}

View File

@ -64,15 +64,15 @@ class ChapterLike extends FrontendService
protected function incrLikeCount(ChapterModel $chapter)
{
$chapter->like_count += 1;
$chapter->update();
}
protected function decrLikeCount(ChapterModel $chapter)
{
$chapter->like_count -= 1;
$chapter->update();
if ($chapter->like_count > 0) {
$chapter->like_count -= 1;
$chapter->update();
}
}
protected function incrUserDailyChapterLikeCount(UserModel $user)

View File

@ -79,14 +79,12 @@ class ConsultCreate extends FrontendService
protected function incrCourseConsultCount(CourseModel $course)
{
$course->consult_count += 1;
$course->update();
}
protected function incrChapterConsultCount(ChapterModel $chapter)
{
$chapter->consult_count += 1;
$chapter->update();
}

View File

@ -40,16 +40,18 @@ class ConsultDelete extends FrontendService
protected function decrCourseConsultCount(CourseModel $course)
{
$course->consult_count -= 1;
$course->update();
if ($course->consult_count > 0) {
$course->consult_count -= 1;
$course->update();
}
}
protected function decrChapterConsultCount(ChapterModel $chapter)
{
$chapter->consult_count -= 1;
$chapter->update();
if ($chapter->consult_count > 0) {
$chapter->consult_count -= 1;
$chapter->update();
}
}
}

View File

@ -3,6 +3,8 @@
namespace App\Services\Frontend\Consult;
use App\Models\Consult as ConsultModel;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
use App\Services\Frontend\ConsultTrait;
use App\Services\Frontend\Service as FrontendService;
@ -25,19 +27,38 @@ class ConsultInfo extends FrontendService
'id' => $consult->id,
'question' => $consult->question,
'answer' => $consult->answer,
'private' => $consult->private,
'like_count' => $consult->like_count,
'create_time' => $consult->create_time,
'update_time' => $consult->update_time,
];
$courseRepo = new CourseRepo();
$course = $courseRepo->findById($consult->course_id);
$result['course'] = [
'id' => $course->id,
'title' => $course->title,
];
$chapterRepo = new ChapterRepo();
$chapter = $chapterRepo->findById($consult->chapter_id);
$result['chapter'] = [
'id' => $chapter->id,
'title' => $chapter->title,
];
$userRepo = new UserRepo();
$owner = $userRepo->findById($consult->user_id);
$user = $userRepo->findById($consult->user_id);
$result['user'] = [
'id' => $owner->id,
'name' => $owner->name,
'avatar' => $owner->avatar,
'id' => $user->id,
'name' => $user->name,
'avatar' => $user->avatar,
];
return $result;

View File

@ -64,15 +64,15 @@ class ConsultLike extends FrontendService
protected function incrLikeCount(ConsultModel $consult)
{
$consult->like_count += 1;
$consult->update();
}
protected function decrLikeCount(ConsultModel $consult)
{
$consult->like_count -= 1;
$consult->update();
if ($consult->like_count > 0) {
$consult->like_count -= 1;
$consult->update();
}
}
protected function incrUserDailyConsultLikeCount(UserModel $user)

View File

@ -61,12 +61,16 @@ class Favorite extends FrontendService
protected function incrCourseFavoriteCount(CourseModel $course)
{
$this->eventsManager->fire('courseCounter:incrFavoriteCount', $this, $course);
$course->favorite_count += 1;
$course->update();
}
protected function decrCourseFavoriteCount(CourseModel $course)
{
$this->eventsManager->fire('courseCounter:decrFavoriteCount', $this, $course);
if ($course->favorite_count > 0) {
$course->favorite_count -= 1;
$course->update();
}
}
protected function incrUserDailyFavoriteCount(UserModel $user)

View File

@ -6,13 +6,10 @@ use App\Builders\ConsultList as ConsultListBuilder;
use App\Library\Paginator\Query as PagerQuery;
use App\Repos\Consult as ConsultRepo;
use App\Services\Frontend\Service as FrontendService;
use App\Services\Frontend\UserTrait;
class ConsultList extends FrontendService
{
use UserTrait;
public function handle()
{
$user = $this->getLoginUser();
@ -22,7 +19,7 @@ class ConsultList extends FrontendService
$params = $pagerQuery->getParams();
$params['user_id'] = $user->id;
$params['deleted'] = 0;
$params['published'] = 1;
$sort = $pagerQuery->getSort();
$page = $pagerQuery->getPage();
@ -46,12 +43,14 @@ class ConsultList extends FrontendService
$consults = $pager->items->toArray();
$courses = $builder->getCourses($consults);
$chapters = $builder->getChapters($consults);
$items = [];
foreach ($consults as $consult) {
$course = $courses[$consult['course_id']] ?? [];
$course = $courses[$consult['course_id']] ?? new \stdClass();
$chapter = $chapters[$consult['chapter_id']] ?? new \stdClass();
$items[] = [
'id' => $consult['id'],
@ -61,6 +60,7 @@ class ConsultList extends FrontendService
'create_time' => $consult['create_time'],
'update_time' => $consult['update_time'],
'course' => $course,
'chapter' => $chapter,
];
}

View File

@ -2,69 +2,19 @@
namespace App\Services\Frontend\My;
use App\Builders\CourseUserList as CourseUserListBuilder;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\CourseUser as CourseUserModel;
use App\Repos\CourseUser as CourseUserRepo;
use App\Services\Frontend\Service as FrontendService;
use App\Services\Frontend\UserTrait;
use App\Services\Frontend\User\CourseList as UserCourseListService;
class CourseList extends FrontendService
{
use UserTrait;
public function handle()
{
$user = $this->getLoginUser();
$pagerQuery = new PagerQuery();
$service = new UserCourseListService();
$params = $pagerQuery->getParams();
$params['user_id'] = $user->id;
$params['role_type'] = CourseUserModel::ROLE_STUDENT;
$params['deleted'] = 0;
$sort = $pagerQuery->getSort();
$page = $pagerQuery->getPage();
$limit = $pagerQuery->getLimit();
$courseUserRepo = new CourseUserRepo();
$pager = $courseUserRepo->paginate($params, $sort, $page, $limit);
return $this->handleCourses($pager);
}
protected function handleCourses($pager)
{
if ($pager->total_items == 0) {
return $pager;
}
$builder = new CourseUserListBuilder();
$relations = $pager->items->toArray();
$courses = $builder->getCourses($relations);
$items = [];
foreach ($relations as $relation) {
$course = $courses[$relation['course_id']] ?? new \stdClass();
$items = [
'course' => $course,
'progress' => $relation['progress'],
'duration' => $relation['duration'],
];
}
$pager->items = $items;
return $pager;
return $service->handle($user->id);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Services\Frontend\My;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\ImFriendUser as ImFriendUserValidator;
class ImFriendDelete extends FrontendService
{
public function handle($id)
{
$user = $this->getLoginUser();
$validator = new ImFriendUserValidator();
$friend = $validator->checkFriend($id);
$friendUser = $validator->checkFriendUser($user->id, $friend->id);
$friendUser->delete();
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Services\Frontend\My;
use App\Models\ImGroup as ImGroupModel;
use App\Repos\ImGroup as ImGroupRepo;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\ImGroupUser as ImGroupUserValidator;
class ImGroupDelete extends FrontendService
{
public function handle($id)
{
$user = $this->getLoginUser();
$validator = new ImGroupUserValidator();
$group = $validator->checkGroup($id);
$groupUser = $validator->checkGroupUser($group->id, $user->id);
$groupUser->delete();
$this->updateGroupUserCount($group);
}
protected function updateGroupUserCount(ImGroupModel $group)
{
$repo = new ImGroupRepo();
$userCount = $repo->countUsers($group->id);
$group->user_count = $userCount;
$group->update();
}
}

View File

@ -6,13 +6,10 @@ use App\Builders\ReviewList as ReviewListBuilder;
use App\Library\Paginator\Query as PagerQuery;
use App\Repos\Review as ReviewRepo;
use App\Services\Frontend\Service as FrontendService;
use App\Services\Frontend\UserTrait;
class ReviewList extends FrontendService
{
use UserTrait;
public function handle()
{
$user = $this->getLoginUser();
@ -22,7 +19,7 @@ class ReviewList extends FrontendService
$params = $pagerQuery->getParams();
$params['user_id'] = $user->id;
$params['deleted'] = 0;
$params['published'] = 1;
$sort = $pagerQuery->getSort();
$page = $pagerQuery->getPage();
@ -51,12 +48,16 @@ class ReviewList extends FrontendService
foreach ($reviews as $review) {
$course = $courses[$review['course_id']] ?? [];
$course = $courses[$review['course_id']] ?? new \stdClass();
$items[] = [
'id' => $review['id'],
'question' => $review['question'],
'answer' => $review['answer'],
'content' => $review['content'],
'reply' => $review['reply'],
'rating' => $review['rating'],
'rating1' => $review['rating1'],
'rating2' => $review['rating2'],
'rating3' => $review['rating3'],
'like_count' => $review['like_count'],
'create_time' => $review['create_time'],
'update_time' => $review['update_time'],

View File

@ -63,7 +63,6 @@ class ReviewCreate extends FrontendService
protected function incrCourseReviewCount(CourseModel $course)
{
$course->review_count += 1;
$course->update();
}

View File

@ -35,9 +35,10 @@ class ReviewDelete extends FrontendService
protected function decrCourseReviewCount(CourseModel $course)
{
$course->review_count -= 1;
$course->update();
if ($course->review_count > 0) {
$course->review_count -= 1;
$course->update();
}
}
}

View File

@ -26,6 +26,9 @@ class ReviewInfo extends FrontendService
'content' => $review->content,
'reply' => $review->reply,
'rating' => $review->rating,
'rating1' => $review->rating1,
'rating2' => $review->rating2,
'rating3' => $review->rating3,
'like_count' => $review->like_count,
'create_time' => $review->create_time,
'update_time' => $review->update_time,

View File

@ -64,15 +64,15 @@ class ReviewLike extends FrontendService
protected function incrLikeCount(ReviewModel $review)
{
$review->like_count += 1;
$review->update();
}
protected function decrLikeCount(ReviewModel $review)
{
$review->like_count -= 1;
$review->update();
if ($review->like_count > 0) {
$review->like_count -= 1;
$review->update();
}
}
protected function incrUserDailyReviewLikeCount(UserModel $user)

View File

@ -56,9 +56,12 @@ class CourseList extends FrontendService
$course = $courses[$relation['course_id']] ?? new \stdClass();
$items[] = [
'course' => $course,
'progress' => $relation['progress'],
'duration' => $relation['duration'],
'reviewed' => $relation['reviewed'],
'expiry_time' => $relation['expiry_time'],
'create_time' => $relation['create_time'],
'course' => $course,
];
}

View File

@ -61,7 +61,7 @@ class ImFriendUser extends Validator
return $record;
}
public function checkIfSelfApply($userId, $friendId)
public function checkIfSelf($userId, $friendId)
{
if ($userId == $friendId) {
throw new BadRequestException('im_friend_user.self_apply');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,28 +0,0 @@
Copyright (c) 2017 Dailymotion (http://www.dailymotion.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
src/remux/mp4-generator.js and src/demux/exp-golomb.js implementation in this project
are derived from the HLS library for video.js (https://github.com/videojs/videojs-contrib-hls)
That work is also covered by the Apache 2 License, following copyright:
Copyright (c) 2013-2015 Brightcove
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language>
<adCountdown>[$second]</adCountdown><!--广告播放结束倒计时-->
<skipDelay>[$second]</skipDelay>
<buttonOver>
<play>点击播放</play>
<pause>暂停播放</pause>
<mute>静音</mute>
<escMute>恢复音量</escMute>
<full>全屏</full>
<escFull>退出全屏</escFull>
<previousPage>上一集</previousPage>
<nextPage>下一集</nextPage>
<definition>点击选择清晰度</definition>
<subtitle>选择字幕</subtitle>
</buttonOver>
<volumeSliderOver>
音量:[$volume]%
</volumeSliderOver>
<buffer>[$percentage]%</buffer>
<timeSliderOver><!--鼠标经过进度条显示的时间格式-->
[$timeh]:[$timei]:[$times]
</timeSliderOver>
<liveAndVod>
[$timeh]:[$timei]:[$times]
</liveAndVod>
<live>
直播中 [$liveTimeY]-[$liveTimem]-[$liveTimed] [$liveTimeh]:[$liveTimei]:[$liveTimes]
</live>
<m3u8Definition>
<name>流畅</name>
<name>低清</name>
<name>标清</name>
<name>高清</name>
<name>超清</name>
<name>蓝光</name>
<name>未知</name>
</m3u8Definition>
<error>
<cannotFindUrl>视频地址不存在</cannotFindUrl>
<streamNotFound>加载失败</streamNotFound>
<formatError>视频格式错误</formatError>
</error>
<definition>自动</definition>
<subtitle>默认</subtitle>
</language>

File diff suppressed because one or more lines are too long

View File

@ -830,10 +830,6 @@ body {
color: gray;
}
.rating-form .layui-rate {
padding-top: 6px;
}
.read-info {
min-height: 428px;
margin-bottom: 0;
@ -1371,6 +1367,19 @@ body {
width: 95%;
}
.review-table .title, .review-table .content {
width: 350px;
}
.review-table .rating .layui-icon {
color: orange;
font-size: 14px;
}
.review-form .layui-rate {
padding-top: 6px;
}
.security-item {
padding: 15px;
line-height: 50px;
@ -1405,12 +1414,12 @@ body {
margin-right: 30px;
}
.order-table {
margin: 0;
.layui-table p {
line-height: 1.8em;
}
.order-table p {
line-height: 1.8em;
.order-table {
margin: 0;
}
.order-table span {

View File

@ -60,8 +60,13 @@ layui.use(['jquery', 'form', 'element', 'layer', 'helper'], function () {
layer.msg(res.msg, {icon: icon});
}
if (res.location) {
var target = res.target || 'self';
setTimeout(function () {
window.location.href = res.location;
if (target === 'parent') {
parent.location.href = res.location;
} else {
window.location.href = res.location;
}
}, 1500);
} else {
submit.removeAttr('disabled').removeClass('layui-btn-disabled');
@ -78,7 +83,8 @@ layui.use(['jquery', 'form', 'element', 'layer', 'helper'], function () {
$('.kg-delete').on('click', function () {
var url = $(this).data('url');
var tips = '确定要删除吗?';
var tips = $(this).data('tips');
tips = tips || '确定要删除吗?';
layer.confirm(tips, function () {
$.ajax({
type: 'POST',

View File

@ -3,34 +3,4 @@ layui.use(['jquery', 'layer'], function () {
var $ = layui.jquery;
var layer = layui.layer;
$('.btn-delete-friend').on('click', function () {
var url = $(this).data('url');
var friendId = $(this).data('friendId');
layer.confirm('确定要删除好友吗?', function () {
$.ajax({
type: 'POST',
url: url,
data: {friend_id: friendId},
success: function (res) {
}
});
});
});
$('.btn-delete-group').on('click', function () {
var url = $(this).data('url');
var groupId = $(this).data('groupId');
layer.confirm('确定要退出群组吗?', function () {
$.ajax({
type: 'POST',
url: url,
data: {group_id: groupId},
success: function (res) {
}
});
});
});
});

View File

@ -4,6 +4,67 @@ layui.use(['jquery', 'layer', 'helper'], function () {
var layer = layui.layer;
var helper = layui.helper;
/**
* 查看咨询
*/
$('.btn-show-consult').on('click', function () {
var url = $(this).data('url');
layer.open({
type: 2,
title: '咨询详情',
content: [url, 'no'],
area: ['720px', '480px']
});
});
/**
* 编辑咨询
*/
$('.btn-edit-consult').on('click', function () {
var url = $(this).data('url');
layer.open({
type: 2,
title: '编辑咨询',
content: [url, 'no'],
area: ['720px', '400px'],
cancel: function () {
parent.location.reload();
}
});
});
/**
* 发布评价
*/
$('.btn-add-review').on('click', function () {
var url = $(this).data('url');
layer.open({
type: 2,
title: '发布评价',
content: [url, 'no'],
area: ['640px', '400px'],
cancel: function () {
parent.location.reload();
}
});
});
/**
* 修改评价
*/
$('.btn-edit-review').on('click', function () {
var url = $(this).data('url');
layer.open({
type: 2,
title: '修改评价',
content: [url, 'no'],
area: ['640px', '400px'],
cancel: function () {
parent.location.reload();
}
});
});
/**
* 订单详情
*/

View File

@ -3,31 +3,35 @@ layui.use(['jquery', 'rate'], function () {
var $ = layui.jquery;
var rate = layui.rate;
var $rating1 = $('input[name=rating1]');
var $rating2 = $('input[name=rating2]');
var $rating3 = $('input[name=rating3]');
$('.btn-cancel').on('click', function () {
parent.layer.closeAll();
});
rate.render({
elem: '#rating1',
value: 5,
value: $rating1.val(),
choose: function (value) {
$('input[name=rating1]').val(value);
$rating1.val(value);
}
});
rate.render({
elem: '#rating2',
value: 5,
value: $rating2.val(),
choose: function (value) {
$('input[name=rating2]').val(value);
$rating2.val(value);
}
});
rate.render({
elem: '#rating3',
value: 5,
value: $rating3.val(),
choose: function (value) {
$('input[name=rating3]').val(value);
$rating3.val(value);
}
});

View File

@ -34,18 +34,6 @@ $scheduler->php($script, $bin, ['--task' => 'refund', '--action' => 'main'])
$scheduler->php($script, $bin, ['--task' => 'sync_course_index', '--action' => 'main'])
->hourly(11);
$scheduler->php($script, $bin, ['--task' => 'sync_course_counter', '--action' => 'main'])
->hourly(13);
$scheduler->php($script, $bin, ['--task' => 'sync_chapter_counter', '--action' => 'main'])
->hourly(17);
$scheduler->php($script, $bin, ['--task' => 'sync_consult_counter', '--action' => 'main'])
->hourly(23);
$scheduler->php($script, $bin, ['--task' => 'sync_review_counter', '--action' => 'main'])
->hourly(29);
$scheduler->php($script, $bin, ['--task' => 'clean_log', '--action' => 'main'])
->daily(3, 3);