mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-25 04:07:17 +08:00
整理代码
This commit is contained in:
parent
f772c206d0
commit
3014ef2260
@ -2,12 +2,13 @@
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\ChapterUser as ChapterUserModel;
|
||||
use App\Models\CourseUser as CourseUserModel;
|
||||
use App\Models\Learning as LearningModel;
|
||||
use App\Models\Order as OrderModel;
|
||||
use App\Models\Refund as RefundModel;
|
||||
use App\Models\Task as TaskModel;
|
||||
use App\Models\Trade as TradeModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\CourseUser as CourseUserRepo;
|
||||
use App\Repos\Order as OrderRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
@ -87,9 +88,6 @@ class OrderTask extends Task
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
protected function handleCourseOrder(OrderModel $order)
|
||||
{
|
||||
/**
|
||||
@ -114,9 +112,6 @@ class OrderTask extends Task
|
||||
$this->handleCourseHistory($data['course_id'], $data['user_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
protected function handlePackageOrder(OrderModel $order)
|
||||
{
|
||||
/**
|
||||
@ -144,9 +139,6 @@ class OrderTask extends Task
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
protected function handleVipOrder(OrderModel $order)
|
||||
{
|
||||
$userRepo = new UserRepo();
|
||||
@ -165,17 +157,11 @@ class OrderTask extends Task
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
protected function handleRewardOrder(OrderModel $order)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
protected function handleOrderNotice(OrderModel $order)
|
||||
{
|
||||
$smser = new OrderSmser();
|
||||
@ -183,9 +169,6 @@ class OrderTask extends Task
|
||||
$smser->handle($order);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
protected function handleOrderRefund(OrderModel $order)
|
||||
{
|
||||
$trade = $this->findFinishedTrade($order->id);
|
||||
@ -205,10 +188,6 @@ class OrderTask extends Task
|
||||
$refund->create();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $courseId
|
||||
* @param int $userId
|
||||
*/
|
||||
protected function handleCourseHistory($courseId, $userId)
|
||||
{
|
||||
$courseUserRepo = new CourseUserRepo();
|
||||
@ -219,17 +198,49 @@ class OrderTask extends Task
|
||||
$courseUser->update(['deleted' => 1]);
|
||||
}
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
$chapterUsers = $this->findPlanChapterUsers($courseId, $userId);
|
||||
|
||||
$userLearnings = $courseRepo->findUserLearnings($courseId, $userId);
|
||||
if ($chapterUsers->count() > 0) {
|
||||
$chapterUsers->update(['deleted' => 1]);
|
||||
}
|
||||
|
||||
if ($userLearnings->count() > 0) {
|
||||
$userLearnings->update(['deleted' => 1]);
|
||||
$learnings = $this->findPlanLearnings($courseId, $userId);
|
||||
|
||||
if ($learnings->count() > 0) {
|
||||
$learnings->update(['deleted' => 1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $orderId
|
||||
* @param int $courseId
|
||||
* @param int $userId
|
||||
* @return ResultsetInterface|Resultset|TaskModel[]
|
||||
*/
|
||||
protected function findPlanChapterUsers($courseId, $userId)
|
||||
{
|
||||
return ChapterUserModel::query()
|
||||
->where('course_id = :course_id:', ['course_id' => $courseId])
|
||||
->andWhere('user_id = :user_id:', ['user_id' => $userId])
|
||||
->andWhere('deleted = 0')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $courseId
|
||||
* @param int $userId
|
||||
* @return ResultsetInterface|Resultset|TaskModel[]
|
||||
*/
|
||||
protected function findPlanLearnings($courseId, $userId)
|
||||
{
|
||||
return LearningModel::query()
|
||||
->where('course_id = :course_id:', ['course_id' => $courseId])
|
||||
->andWhere('user_id = :user_id:', ['user_id' => $userId])
|
||||
->andWhere('deleted = 0')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $orderId
|
||||
* @return Model|TradeModel
|
||||
*/
|
||||
protected function findFinishedTrade($orderId)
|
||||
|
@ -56,6 +56,8 @@ class Student extends Service
|
||||
|
||||
$params = $pagerQuery->getParams();
|
||||
|
||||
$params['deleted'] = 0;
|
||||
|
||||
$sort = $pagerQuery->getSort();
|
||||
$page = $pagerQuery->getPage();
|
||||
$limit = $pagerQuery->getLimit();
|
||||
|
@ -3,8 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<meta name="csrf-token-key" content="{{ security.getTokenKey() }}">
|
||||
<meta name="csrf-token-value" content="{{ security.getTokenValue() }}">
|
||||
<meta name="csrf-token" content="{{ csrfToken.getToken() }}">
|
||||
<title>管理后台</title>
|
||||
{{ icon_link("favicon.ico") }}
|
||||
{{ css_link('lib/layui/css/layui.css') }}
|
||||
|
@ -95,14 +95,14 @@
|
||||
<tr>
|
||||
<th>编号</th>
|
||||
<th>昵称</th>
|
||||
<th>邮箱</th>
|
||||
<th>手机</th>
|
||||
<th>邮箱</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ user.id }}</td>
|
||||
<td>{{ user.name }}</td>
|
||||
<td>{% if account.phone %}{{ account.phone }}{% else %}N/A{% endif %}</td>
|
||||
<td>{% if account.email %}{{ account.email }}{% else %}N/A{% endif %}</td>
|
||||
<td>{% if account.phone %} {{ account.phone }} {% else %} 未知 {% endif %}</td>
|
||||
<td>{% if account.email %} {{ account.email }} {% else %} 未知 {% endif %}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
@ -111,13 +111,13 @@
|
||||
<tr>
|
||||
<th>编号</th>
|
||||
<th>昵称</th>
|
||||
<th>邮箱</th>
|
||||
<th>手机</th>
|
||||
<th>邮箱</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ user.id }}</td>
|
||||
<td>{{ user.name }}</td>
|
||||
<td>{% if account.phone %}{{ account.phone }}{% else %}N/A{% endif %}</td>
|
||||
<td>{% if account.email %}{{ account.email }}{% else %}N/A{% endif %}</td>
|
||||
<td>{% if account.phone %} {{ account.phone }} {% else %} 未知 {% endif %}</td>
|
||||
<td>{% if account.email %} {{ account.email }} {% else %} 未知 {% endif %}</td>
|
||||
</tr>
|
||||
</table>
|
@ -1,9 +1,9 @@
|
||||
{%- macro source_type_info(value) %}
|
||||
{% if value == 'free' %}
|
||||
{% if value == 1 %}
|
||||
<span class="layui-badge layui-bg-green">免费</span>
|
||||
{% elseif value == 'charge' %}
|
||||
{% elseif value == 2 %}
|
||||
<span class="layui-badge layui-bg-orange">付费</span>
|
||||
{% elseif value == 'import' %}
|
||||
{% elseif value == 3 %}
|
||||
<span class="layui-badge layui-bg-blue">导入</span>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
@ -72,7 +72,7 @@
|
||||
<button class="layui-btn layui-btn-sm">操作 <span class="layui-icon layui-icon-triangle-d"></span></button>
|
||||
<ul>
|
||||
<li><a href="{{ url({'for':'admin.student.edit'},{'plan_id':item.id}) }}">编辑学员</a></li>
|
||||
<li><a href="javascript:" class="kg-learning" data-url="{{ url({'for':'admin.student.learning'},{'plan_id':item.id}) }}">学习记录</a></li>
|
||||
<li><a href="javascript:" class="kg-learning" data-url="{{ url({'for':'admin.student.learning'},{'course_id':item.course_id,'user_id':item.user_id}) }}">学习记录</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
|
@ -23,9 +23,9 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">加入方式</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="source" value="free" title="免费课程">
|
||||
<input type="radio" name="source" value="charge" title="付费课程">
|
||||
<input type="radio" name="source" value="import" title="后台导入">
|
||||
<input type="radio" name="source" value="1" title="免费课程">
|
||||
<input type="radio" name="source" value="2" title="付费课程">
|
||||
<input type="radio" name="source" value="3" title="后台导入">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -27,10 +27,10 @@
|
||||
|
||||
<div style="text-align: center">
|
||||
{% if trade.status == 'pending' %}
|
||||
<button class="kg-close layui-btn layui-bg-green" data-url="{{ url('for':'admin.trade.close','id':trade.id}) }}">关闭交易</button>
|
||||
<button class="kg-close layui-btn layui-bg-green" data-url="{{ url({'for':'admin.trade.close','id':trade.id}) }}">关闭交易</button>
|
||||
{% endif %}
|
||||
{% if trade.status == 'finished' %}
|
||||
<button class="kg-refund layui-btn layui-bg-green" data-url="{{ url('for':'admin.trade.refund','id':trade.id}) }}">申请退款</button>
|
||||
<button class="kg-refund layui-btn layui-bg-green" data-url="{{ url({'for':'admin.trade.refund','id':trade.id}) }}">申请退款</button>
|
||||
{% endif %}
|
||||
<button class="kg-back layui-btn layui-bg-gray">返回上页</button>
|
||||
</div>
|
||||
@ -92,14 +92,14 @@
|
||||
<tr>
|
||||
<th>编号</th>
|
||||
<th>昵称</th>
|
||||
<th>邮箱</th>
|
||||
<th>手机</th>
|
||||
<th>邮箱</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ user.id }}</td>
|
||||
<td>{{ user.name }}</td>
|
||||
<td>{% if account.phone %}{{ account.phone }}{% else %}N/A{% endif %}</td>
|
||||
<td>{% if account.email %}{{ account.email }}{% else %}N/A{% endif %}</td>
|
||||
<td>{% if account.phone %} {{ account.phone }} {% else %} 未知 {% endif %}</td>
|
||||
<td>{% if account.email %} {{ account.email }} {% else %} 未知 {% endif %}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@ -116,7 +116,7 @@
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: url,
|
||||
finished: function (res) {
|
||||
success: function (res) {
|
||||
layer.msg(res.msg, {icon: 1});
|
||||
setTimeout(function () {
|
||||
window.location.reload();
|
||||
|
@ -1,25 +1,26 @@
|
||||
{%- macro location_info(value) %}
|
||||
{% if value %}
|
||||
{{ value }}
|
||||
{% else %}
|
||||
N/A
|
||||
{%- macro last_login_info(user) %}
|
||||
{% if user.last_login_ip %}
|
||||
<span class="layui-badge layui-bg-gray">学员</span>
|
||||
{% endif %}
|
||||
{% if user.last_login_time %}
|
||||
<span class="layui-badge layui-bg-gray">学员</span>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro gender_info(value) %}
|
||||
{% if value == 'male' %}
|
||||
{% if value == 1 %}
|
||||
<span class="layui-badge layui-bg-red">男</span>
|
||||
{% elseif value == 'female' %}
|
||||
{% elseif value == 2 %}
|
||||
<span class="layui-badge layui-bg-green">女</span>
|
||||
{% elseif value == 'none' %}
|
||||
{% elseif value == 3 %}
|
||||
<span class="layui-badge layui-bg-gray">密</span>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro edu_role_info(user) %}
|
||||
{% if user.edu_role.id == 'student' %}
|
||||
{% if user.edu_role.id == 1 %}
|
||||
<span class="layui-badge layui-bg-gray">学员</span>
|
||||
{% elseif user.edu_role.id == 'teacher' %}
|
||||
{% elseif user.edu_role.id == 2 %}
|
||||
<span class="layui-badge layui-bg-blue">讲师</span>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
@ -70,8 +71,8 @@
|
||||
<tr>
|
||||
<th>编号</th>
|
||||
<th>昵称</th>
|
||||
<th>地区</th>
|
||||
<th>性别</th>
|
||||
<th>最后登录</th>
|
||||
<th>教学角色</th>
|
||||
<th>后台角色</th>
|
||||
<th>注册时间</th>
|
||||
@ -83,8 +84,8 @@
|
||||
<tr>
|
||||
<td>{{ item.id }}</td>
|
||||
<td><span title="{{ item.about }}">{{ item.name }}</span>{{ status_info(item) }}</td>
|
||||
<td>{{ location_info(item.location) }}</td>
|
||||
<td>{{ gender_info(item.gender) }}</td>
|
||||
<td>{{ last_login_info(item) }}</td>
|
||||
<td>{{ edu_role_info(item) }}</td>
|
||||
<td>{{ admin_role_info(item) }}</td>
|
||||
<td>{{ date('Y-m-d H:i',item.create_time) }}</td>
|
||||
|
@ -21,8 +21,8 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">教学角色</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="edu_role" value="student" title="学员">
|
||||
<input type="radio" name="edu_role" value="teacher" title="讲师">
|
||||
<input type="radio" name="edu_role" value="1" title="学员">
|
||||
<input type="radio" name="edu_role" value="2" title="讲师">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -18,9 +18,12 @@ class OrderController extends Controller
|
||||
*/
|
||||
public function confirmAction()
|
||||
{
|
||||
$itemId = $this->request->getQuery('item_id');
|
||||
$itemType = $this->request->getQuery('item_type');
|
||||
|
||||
$service = new OrderConfirmService();
|
||||
|
||||
$info = $service->handle();
|
||||
$info = $service->handle($itemId, $itemType);
|
||||
|
||||
$this->view->setVar('info', $info);
|
||||
}
|
||||
|
@ -18,9 +18,13 @@ class RefundController extends Controller
|
||||
*/
|
||||
public function confirmAction()
|
||||
{
|
||||
$sn = $this->request->getQuery('order_sn');
|
||||
|
||||
$service = new RefundConfirmService();
|
||||
|
||||
$info = $service->handle();
|
||||
$info = $service->handle($sn);
|
||||
|
||||
return $this->jsonSuccess(['info' => $info]);
|
||||
|
||||
$this->view->setVar('info', $info);
|
||||
}
|
||||
|
52
app/Library/CsrfToken.php
Normal file
52
app/Library/CsrfToken.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Library;
|
||||
|
||||
use Phalcon\Crypt;
|
||||
use Phalcon\Di;
|
||||
use Phalcon\Text;
|
||||
|
||||
class CsrfToken
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Crypt
|
||||
*/
|
||||
protected $crypt;
|
||||
|
||||
protected $lifetime = 60 * 60;
|
||||
|
||||
protected $delimiter = '@@';
|
||||
|
||||
protected $fixed = 'KG';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->crypt = Di::getDefault()->get('crypt');
|
||||
}
|
||||
|
||||
public function getToken()
|
||||
{
|
||||
$text = implode($this->delimiter, [time(), $this->fixed, Text::random(8)]);
|
||||
|
||||
return $this->crypt->encryptBase64($text);
|
||||
}
|
||||
|
||||
public function checkToken($token)
|
||||
{
|
||||
$text = $this->crypt->decryptBase64($token);
|
||||
|
||||
list($time, $fixed, $random) = explode($this->delimiter, $text);
|
||||
|
||||
if ($time != intval($time) || $fixed != $this->fixed || strlen($random) != 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (time() - $time > $this->lifetime) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -10,15 +10,15 @@ class CourseUser extends Model
|
||||
/**
|
||||
* 角色类型
|
||||
*/
|
||||
const ROLE_STUDENT = 'student'; // 学员
|
||||
const ROLE_TEACHER = 'teacher'; // 讲师
|
||||
const ROLE_STUDENT = 1; // 学员
|
||||
const ROLE_TEACHER = 2; // 讲师
|
||||
|
||||
/**
|
||||
* 来源类型
|
||||
*/
|
||||
const SOURCE_FREE = 'free'; // 免费
|
||||
const SOURCE_CHARGE = 'charge'; // 付费
|
||||
const SOURCE_IMPORT = 'import'; // 导入
|
||||
const SOURCE_FREE = 1; // 免费
|
||||
const SOURCE_CHARGE = 2; // 付费
|
||||
const SOURCE_IMPORT = 3; // 导入
|
||||
|
||||
/**
|
||||
* 主键编号
|
||||
|
@ -74,6 +74,13 @@ class Learning extends Model
|
||||
*/
|
||||
public $client_ip;
|
||||
|
||||
/**
|
||||
* 删除标识
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $deleted;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*
|
||||
|
@ -2,17 +2,17 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Library\Security as AppSecurity;
|
||||
use App\Library\CsrfToken as MyCsrfToken;
|
||||
|
||||
class Security extends Provider
|
||||
class CsrfToken extends Provider
|
||||
{
|
||||
|
||||
protected $serviceName = 'security';
|
||||
protected $serviceName = 'csrfToken';
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->di->setShared($this->serviceName, function () {
|
||||
return new AppSecurity();
|
||||
return new MyCsrfToken();
|
||||
});
|
||||
}
|
||||
|
@ -29,6 +29,10 @@ class Learning extends Repository
|
||||
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
|
||||
}
|
||||
|
||||
if (isset($where['deleted'])) {
|
||||
$builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]);
|
||||
}
|
||||
|
||||
switch ($sort) {
|
||||
default:
|
||||
$orderBy = 'id DESC';
|
||||
|
@ -14,11 +14,8 @@ use App\Validators\Order as OrderValidator;
|
||||
class OrderConfirm extends Service
|
||||
{
|
||||
|
||||
public function handle()
|
||||
public function handle($itemId, $itemType)
|
||||
{
|
||||
$itemId = $this->request->getQuery('item_id');
|
||||
$itemType = $this->request->getQuery('item_type');
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$validator = new OrderValidator();
|
||||
|
@ -5,19 +5,20 @@ namespace App\Services\Frontend\Refund;
|
||||
use App\Models\Refund as RefundModel;
|
||||
use App\Services\Frontend\OrderTrait;
|
||||
use App\Services\Frontend\Service;
|
||||
use App\Services\RefundCalculator;
|
||||
|
||||
class RefundConfirm extends Service
|
||||
{
|
||||
|
||||
use OrderTrait;
|
||||
|
||||
public function handle()
|
||||
public function handle($sn)
|
||||
{
|
||||
$sn = $this->request->getQuery('order_sn');
|
||||
|
||||
$order = $this->checkOrderBySn($sn);
|
||||
|
||||
$service = new RefundCalculator();
|
||||
|
||||
return $service->handle($order);
|
||||
}
|
||||
|
||||
protected function handleRefund(RefundModel $refund)
|
||||
|
120
app/Services/RefundCalculator.php
Normal file
120
app/Services/RefundCalculator.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Order as OrderModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
|
||||
class RefundCalculator extends Service
|
||||
{
|
||||
|
||||
public function handle(OrderModel $order)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
switch ($order->item_type) {
|
||||
case OrderModel::ITEM_COURSE:
|
||||
$result = $this->handleCourseRefund($order);
|
||||
break;
|
||||
case OrderModel::ITEM_PACKAGE:
|
||||
$result = $this->handlePackageRefund($order);
|
||||
break;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function handleCourseRefund(OrderModel $order)
|
||||
{
|
||||
/**
|
||||
* @var array $itemInfo
|
||||
*/
|
||||
$itemInfo = $order->item_info;
|
||||
|
||||
$refundPercent = 0.00;
|
||||
$refundAmount = 0.00;
|
||||
|
||||
if ($itemInfo['course']['refund_expiry_time'] > time()) {
|
||||
$refundPercent = $this->getCourseRefundPercent($order->item_id, $order->user_id);
|
||||
$refundAmount = $order->amount * $refundPercent;
|
||||
}
|
||||
|
||||
$itemInfo['course']['refund_percent'] = $refundPercent;
|
||||
$itemInfo['course']['refund_amount'] = $refundAmount;
|
||||
|
||||
return [
|
||||
'item_type' => $order->item_type,
|
||||
'item_info' => $itemInfo,
|
||||
'refund_amount' => $refundAmount,
|
||||
];
|
||||
}
|
||||
|
||||
protected function handlePackageRefund(OrderModel $order)
|
||||
{
|
||||
/**
|
||||
* @var array $itemInfo
|
||||
*/
|
||||
$itemInfo = $order->item_info;
|
||||
|
||||
$totalMarketPrice = 0.00;
|
||||
|
||||
foreach ($itemInfo['courses'] as $course) {
|
||||
$totalMarketPrice += $course['market_price'];
|
||||
}
|
||||
|
||||
$totalRefundAmount = 0.00;
|
||||
|
||||
/**
|
||||
* 按照占比方式计算退款
|
||||
*/
|
||||
foreach ($itemInfo['courses'] as &$course) {
|
||||
|
||||
$refundPercent = 0.00;
|
||||
$refundAmount = 0.00;
|
||||
|
||||
if ($course['refund_expiry_time'] > time()) {
|
||||
$pricePercent = round($course['market_price'] / $totalMarketPrice, 4);
|
||||
$refundPercent = $this->getCourseRefundPercent($order->user_id, $course['id']);
|
||||
$refundAmount = round($order->amount * $pricePercent * $refundPercent, 2);
|
||||
$totalRefundAmount += $refundAmount;
|
||||
}
|
||||
|
||||
$course['item_info']['refund_percent'] = $refundPercent;
|
||||
$course['item_info']['refund_amount'] = $refundAmount;
|
||||
}
|
||||
|
||||
return [
|
||||
'item_type' => $order->item_type,
|
||||
'item_info' => $itemInfo,
|
||||
'refund_amount' => $totalRefundAmount,
|
||||
];
|
||||
}
|
||||
|
||||
protected function getCourseRefundPercent($courseId, $userId)
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$courseLessons = $courseRepo->findLessons($courseId);
|
||||
|
||||
if ($courseLessons->count() == 0) {
|
||||
return 1.00;
|
||||
}
|
||||
|
||||
$userLearnings = $courseRepo->findConsumedUserLearnings($courseId, $userId);
|
||||
|
||||
if ($userLearnings->count() == 0) {
|
||||
return 1.00;
|
||||
}
|
||||
|
||||
$courseLessonIds = kg_array_column($courseLessons->toArray(), 'id');
|
||||
$userLessonIds = kg_array_column($userLearnings->toArray(), 'chapter_id');
|
||||
$consumedLessonIds = array_intersect($courseLessonIds, $userLessonIds);
|
||||
|
||||
$totalCount = count($courseLessonIds);
|
||||
$consumedCount = count($consumedLessonIds);
|
||||
$refundCount = $totalCount - $consumedCount;
|
||||
|
||||
return round($refundCount / $totalCount, 4);
|
||||
}
|
||||
|
||||
}
|
@ -11,10 +11,9 @@ class Security extends Validator
|
||||
|
||||
public function checkCsrfToken()
|
||||
{
|
||||
$tokenKey = $this->request->getHeader('X-Csrf-Token-Key');
|
||||
$tokenValue = $this->request->getHeader('X-Csrf-Token-Value');
|
||||
$token = $this->request->getHeader('X-Csrf-Token');
|
||||
|
||||
$result = $this->security->checkToken($tokenKey, $tokenValue);
|
||||
$result = $this->csrfToken->checkToken($token);
|
||||
|
||||
if (!$result) {
|
||||
throw new BadRequestException('security.invalid_csrf_token');
|
||||
|
@ -50,14 +50,14 @@ class Trade extends Validator
|
||||
}
|
||||
}
|
||||
|
||||
public function checkIfAllowClose($trade)
|
||||
public function checkIfAllowClose(TradeModel $trade)
|
||||
{
|
||||
if ($trade->status != TradeModel::STATUS_PENDING) {
|
||||
throw new BadRequestException('trade.close_not_allowed');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkIfAllowRefund($trade)
|
||||
public function checkIfAllowRefund(TradeModel $trade)
|
||||
{
|
||||
if ($trade->status != TradeModel::STATUS_FINISHED) {
|
||||
throw new BadRequestException('trade.refund_not_allowed');
|
||||
|
@ -7,6 +7,7 @@ use App\Providers\Cache as CacheProvider;
|
||||
use App\Providers\Config as ConfigProvider;
|
||||
use App\Providers\Cookie as CookieProvider;
|
||||
use App\Providers\Crypt as CryptProvider;
|
||||
use App\Providers\CsrfToken as CsrfTokenProvider;
|
||||
use App\Providers\Database as DatabaseProvider;
|
||||
use App\Providers\EventsManager as EventsManagerProvider;
|
||||
use App\Providers\Logger as LoggerProvider;
|
||||
@ -15,7 +16,6 @@ use App\Providers\Provider as AppProvider;
|
||||
use App\Providers\Request as RequestProvider;
|
||||
use App\Providers\Response as ResponseProvider;
|
||||
use App\Providers\Router as RouterProvider;
|
||||
use App\Providers\Security as SecurityProvider;
|
||||
use App\Providers\Session as SessionProvider;
|
||||
use App\Providers\Url as UrlProvider;
|
||||
use App\Providers\View as ViewProvider;
|
||||
@ -71,6 +71,7 @@ class HttpKernel extends Kernel
|
||||
CookieProvider::class,
|
||||
ConfigProvider::class,
|
||||
CryptProvider::class,
|
||||
CsrfTokenProvider::class,
|
||||
DatabaseProvider::class,
|
||||
EventsManagerProvider::class,
|
||||
LoggerProvider::class,
|
||||
@ -78,7 +79,6 @@ class HttpKernel extends Kernel
|
||||
RequestProvider::class,
|
||||
ResponseProvider::class,
|
||||
RouterProvider::class,
|
||||
SecurityProvider::class,
|
||||
SessionProvider::class,
|
||||
UrlProvider::class,
|
||||
ViewProvider::class,
|
||||
|
@ -38,7 +38,7 @@ $error['captcha.invalid_code'] = '无效的验证码';
|
||||
* 帐号相关
|
||||
*/
|
||||
$error['account.not_found'] = '账号不存在';
|
||||
$error['account.login_locked'] = '账号被锁定,无法登录';
|
||||
$error['account.login_block'] = '账号被锁定,无法登录';
|
||||
$error['account.login_name_incorrect'] = '登录账号不正确';
|
||||
$error['account.login_password_incorrect'] = '登录密码不正确';
|
||||
$error['account.invalid_email'] = '无效的电子邮箱';
|
||||
@ -60,7 +60,7 @@ $error['user.invalid_edu_role'] = '无效的教学角色';
|
||||
$error['user.invalid_admin_role'] = '无效的后台角色';
|
||||
$error['user.invalid_vip_status'] = '无效的会员状态';
|
||||
$error['user.invalid_vip_expiry_time'] = '无效的会员期限';
|
||||
$error['user.invalid_lock_status'] = '无效的锁定状态';
|
||||
$error['user.invalid_block_status'] = '无效的锁定状态';
|
||||
$error['user.invalid_lock_expiry_time'] = '无效的锁定期限';
|
||||
|
||||
/**
|
||||
@ -266,8 +266,8 @@ $error['order.trade_expired'] = '交易已过期';
|
||||
$error['trade.not_found'] = '交易不存在';
|
||||
$error['trade.create_failed'] = '创建交易失败';
|
||||
$error['trade.invalid_channel'] = '无效的平台类型';
|
||||
$error['trade.invalid_close_action'] = '当前不允许关闭交易';
|
||||
$error['trade.invalid_refund_action'] = '当前不允许交易退款';
|
||||
$error['trade.close_not_allowed'] = '当前不允许关闭交易';
|
||||
$error['trade.refund_not_allowed'] = '当前不允许交易退款';
|
||||
$error['trade.refund_existed'] = '退款申请已经存在';
|
||||
|
||||
/**
|
||||
|
@ -12,11 +12,7 @@ layui.use(['jquery', 'form', 'element', 'layer', 'dropdown'], function () {
|
||||
|
||||
$.ajaxSetup({
|
||||
beforeSend: function (xhr) {
|
||||
var csrfTokenKey = $('meta[name="csrf-token-key"]').attr('content');
|
||||
var csrfTokenValue = $('meta[name="csrf-token-value"]').attr('content');
|
||||
xhr.setRequestHeader('X-Csrf-Token-Key', csrfTokenKey);
|
||||
xhr.setRequestHeader('X-Csrf-Token-Value', csrfTokenValue);
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.setRequestHeader('X-Csrf-Token', $('meta[name="csrf-token"]').attr('content'));
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user