完善剩余退款流程:

12小时,24小时,48小时退款策略实现
This commit is contained in:
焦钰锟 2025-04-18 09:07:44 +08:00
parent 969b8319c6
commit 107fcbe698
12 changed files with 104 additions and 26 deletions

View File

@ -70,7 +70,7 @@ class Order extends Backend
$row->getRelation('user')->visible(['nickname','realname','mobile','avatar']); $row->getRelation('user')->visible(['nickname','realname','mobile','avatar']);
$row->getRelation('activity')->visible(['title','images']); $row->getRelation('activity')->visible(['title','images']);
$row->getRelation('detail')->visible(['title',"feel"]); $row->getRelation('detail')->visible(['title',"feel","price"]);
} }
$result = array("total" => $list->total(), "rows" => $list->items()); $result = array("total" => $list->total(), "rows" => $list->items());

View File

@ -24,8 +24,8 @@
<div class="input-group"> <div class="input-group">
<input id="c-images" data-rule="required" class="form-control" size="50" name="row[images]" type="text"> <input id="c-images" data-rule="required" class="form-control" size="50" name="row[images]" type="text">
<div class="input-group-addon no-border no-padding"> <div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-images" class="btn btn-danger faupload" data-input-id="c-images" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span> <span><button type="button" id="faupload-images" class="btn btn-danger faupload" data-input-id="c-images" data-maxcount="5" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-images" class="btn btn-primary fachoose" data-input-id="c-images" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span> <span><button type="button" id="fachoose-images" class="btn btn-primary fachoose" data-input-id="c-images" data-maxcount="5" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div> </div>
<span class="msg-box n-right" for="c-images"></span> <span class="msg-box n-right" for="c-images"></span>
</div> </div>

View File

@ -27,8 +27,8 @@
<div class="input-group"> <div class="input-group">
<input id="c-images" data-rule="required" class="form-control" size="50" name="row[images]" type="text" value="{$row.images|htmlentities}"> <input id="c-images" data-rule="required" class="form-control" size="50" name="row[images]" type="text" value="{$row.images|htmlentities}">
<div class="input-group-addon no-border no-padding"> <div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-images" class="btn btn-danger faupload" data-input-id="c-images" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span> <span><button type="button" id="faupload-images" class="btn btn-danger faupload" data-maxcount="5" data-input-id="c-images" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-images" class="btn btn-primary fachoose" data-input-id="c-images" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span> <span><button type="button" id="fachoose-images" class="btn btn-primary fachoose" data-maxcount="5" data-input-id="c-images" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div> </div>
<span class="msg-box n-right" for="c-images"></span> <span class="msg-box n-right" for="c-images"></span>
</div> </div>

View File

@ -27,8 +27,8 @@
<div class="input-group"> <div class="input-group">
<input id="c-images" data-rule="required" class="form-control" size="50" name="row[images]" type="text" value="{$row.images|htmlentities}"> <input id="c-images" data-rule="required" class="form-control" size="50" name="row[images]" type="text" value="{$row.images|htmlentities}">
<div class="input-group-addon no-border no-padding"> <div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-images" class="btn btn-danger faupload" data-input-id="c-images" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span> <span><button type="button" id="faupload-images" class="btn btn-danger faupload" data-maxcount="5" data-input-id="c-images" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-images" class="btn btn-primary fachoose" data-input-id="c-images" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span> <span><button type="button" id="fachoose-images" class="btn btn-primary fachoose" data-maxcount="5" data-input-id="c-images" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div> </div>
<span class="msg-box n-right" for="c-images"></span> <span class="msg-box n-right" for="c-images"></span>
</div> </div>

View File

@ -19,10 +19,10 @@
<div id="status_yes" > <div id="status_yes" >
<div class="form-group"> <div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('同意退款金额')}(默认损耗后额度):</label> <label class="control-label col-xs-12 col-sm-2">{:__('同意退款金额')}:</label>
<div class="col-xs-12 col-sm-8"> <div class="col-xs-12 col-sm-8">
<input id="c-price" data-rule="required" class="form-control" step="0.01" name="row[price]" type="number" value="{$row.auto_recommend_price >0 ? $row.auto_recommend_price : $row.sub_refundprice }"> <input id="c-price" data-rule="required" class="form-control" step="0.01" name="row[price]" type="number" value="{$row.total_refundprice >0 ? $row.total_refundprice : $row.sub_refundprice }">
<span style="color: red">( 当前订单损耗比为 {$row.loss_proportion|htmlentities}% | 忽略损耗应退全额为 {$row.auto_price|htmlentities} [若为0说明课时已用完或计算应退金额小于0.01,请自行决定是否退全款] | 退款金额不能超过订单应退全额{$row.sub_refundprice|htmlentities} )</span> <span style="color: red">( 当前订单手续费为 {$row.fee_price|htmlentities} | 未退全额为 {$row.sub_refundprice|htmlentities} 退款金额不能超过订单剩余未退额)</span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -112,9 +112,10 @@ class Crontab extends Api
// $res = Order::timeoutCheck(true); // $res = Order::timeoutCheck(true);
// $res = \app\common\model\school\classes\activity\order\Order::timeoutCheck(true); // $res = \app\common\model\school\classes\activity\order\Order::timeoutCheck(true);
\app\common\model\school\activity\order\Order::timeoutCheck(0,true);
Activity::timeoutCheck(true); Activity::timeoutCheck(true);
SettleLog::timeoutCheck(null,null,true); SettleLog::timeoutCheck(null,null,true);
\app\common\model\school\activity\order\Order::timeoutCheck(0,true); // \app\common\model\school\activity\order\Order::timeoutCheck(0,true);
// $lock = new UrlLock(2,"mock-lock-suffix",5,"您的请求过于频繁,请您稍后再试!"); // $lock = new UrlLock(2,"mock-lock-suffix",5,"您的请求过于频繁,请您稍后再试!");
// $lock->lock(); // $lock->lock();

View File

@ -108,7 +108,12 @@ class Index extends Api
]; ];
$upload_config = config('upload'); $upload_config = config('upload');
$this->success('',["customer_service"=>$customer_service,"upload_config"=>$upload_config,"base_info"=>$base_info,"home_data"=>$home_data]); $withdrawal_info = [
"withdrawal_confirmation"=>config("site.withdrawal_confirmation"),
"withdrawal_min"=>config("site.withdrawal_min"),
];
$this->success('',["withdrawal_info"=>$withdrawal_info,"customer_service"=>$customer_service,"upload_config"=>$upload_config,"base_info"=>$base_info,"home_data"=>$home_data]);
} }
/** /**

View File

@ -486,6 +486,13 @@ class Activity extends BaseModel
self::check($params,$rule,$rule_msg); self::check($params,$rule,$rule_msg);
$images = is_array($params["images"]) ? $params["images"] : explode(",",$params["images"]);
//轮播图至少3张
if(count($images) < 3 || count($images) > 5){
throw new \Exception("轮播图至少3张,最多5张");
}
if($params["price"]>0){ if($params["price"]>0){
if(empty($params["refund_id"])) throw new \Exception("退款策略必填"); if(empty($params["refund_id"])) throw new \Exception("退款策略必填");
$refund_id = $params["refund_id"]; $refund_id = $params["refund_id"];

View File

@ -49,10 +49,24 @@ class Order extends BaseModel
'finishtime_text', 'finishtime_text',
'refundtime_text', 'refundtime_text',
'auth_status_text', 'auth_status_text',
'refundsendtime_text' 'refundsendtime_text',
'cancel_last_seconds',
]; ];
public function getCancelLastSecondsAttr($value, $data)
{
$value = $value ? $value : (isset($data['createtime']) ? $data['createtime'] : '');
if(!$value) return 0;
//活动未支付超时取消(秒)
$unpaid_activity_cancel_time = config("site.unpaid_activity_cancel_time");
//得到倒计时剩余秒数
$cancel_last_seconds = $unpaid_activity_cancel_time - (time() - $value);
return $cancel_last_seconds > 0 ? $cancel_last_seconds : 0;
}
public function getPayTypeList() public function getPayTypeList()
{ {
@ -279,8 +293,8 @@ class Order extends BaseModel
} }
if (isset($whereData['status'])) $model = $model->where("{$alisa}status", 'in', $whereData['status']); if (isset($whereData['status']) && $whereData['status']!=="") $model = $model->where("{$alisa}status", 'in', $whereData['status']);
if (isset($whereData['not_status'])) $model = $model->where("{$alisa}status", 'not in', $whereData['not_status']); if (isset($whereData['not_status']) && $whereData['not_status']!=="") $model = $model->where("{$alisa}status", 'not in', $whereData['not_status']);
if (isset($whereData['server_status']) && $whereData['server_status']!=="") $model = $model->where("{$alisa}server_status", 'in', $whereData['server_status']); if (isset($whereData['server_status']) && $whereData['server_status']!=="") $model = $model->where("{$alisa}server_status", 'in', $whereData['server_status']);
if (isset($whereData['not_server_status'])&& $whereData['not_server_status']!=="") $model = $model->where("{$alisa}server_status", 'not in', $whereData['not_server_status']); if (isset($whereData['not_server_status'])&& $whereData['not_server_status']!=="") $model = $model->where("{$alisa}server_status", 'not in', $whereData['not_server_status']);
@ -444,6 +458,10 @@ class Order extends BaseModel
* @param $order_no * @param $order_no
*/ */
public static function getDetail($order_no,$activity_id = []){ public static function getDetail($order_no,$activity_id = []){
//超时检测
self::timeoutCheck($order_no);
$model = self::where('order_no|id|pay_no',$order_no); $model = self::where('order_no|id|pay_no',$order_no);
if($activity_id)$model = $model->where("activity_id","in",$activity_id); if($activity_id)$model = $model->where("activity_id","in",$activity_id);
$data = $model->find(); $data = $model->find();
@ -455,8 +473,6 @@ class Order extends BaseModel
// $data->user; // $data->user;
$data->user->visible(['id','nickname','mobile','avatar','realname']); $data->user->visible(['id','nickname','mobile','avatar','realname']);
//超时检测
self::timeoutCheck($data["id"]);
//规格信息 //规格信息
$data->ordercode; $data->ordercode;
@ -1371,7 +1387,7 @@ class Order extends BaseModel
$unpaid_order_expire_time = time() - $unpaid_order_expire_time; $unpaid_order_expire_time = time() - $unpaid_order_expire_time;
//得到所有过期的队列 //得到所有过期的队列
$model = self::where("status",'in',['0'])->where("createtime","<=",$unpaid_order_expire_time); $model = self::where("status",'in',['0'])->where("createtime","<=",$unpaid_order_expire_time);
if($order_id)$model = $model->where("id",$order_id); if($order_id)$model = $model->where("id|order_no",$order_id);
$list = $model->select(); $list = $model->select();
if ($trans) { if ($trans) {
@ -1440,6 +1456,18 @@ class Order extends BaseModel
case "3": //开始前退 case "3": //开始前退
case "5": //随时退 case "5": //随时退
if ($detail['start_time'] < $time) throw new \Exception("活动开始后不可取消,请走售后流程!"); if ($detail['start_time'] < $time) throw new \Exception("活动开始后不可取消,请走售后流程!");
break;
case "7": //前12小时退
if ($detail['start_time'] < $time) throw new \Exception("活动开始后不可取消,请走售后流程!");
break;
case "9": //前24小时退
if ($detail['start_time'] < $time) throw new \Exception("活动开始后不可取消,请走售后流程!");
break;
case "11": //前24小时退
if ($detail['start_time'] < $time) throw new \Exception("活动开始后不可取消,请走售后流程!");
break; break;
default: default:
throw new \Exception("不支持的退款策略,请走售后流程!"); throw new \Exception("不支持的退款策略,请走售后流程!");
@ -1628,6 +1656,38 @@ class Order extends BaseModel
case "3": //开始前退 case "3": //开始前退
case "5": //随时退 退全款 case "5": //随时退 退全款
$price = $order["sub_refundprice"]; $price = $order["sub_refundprice"];
break;
case "7": //前12小时退
//还没到开始前12小时退100%
//过了开始前12小时退50%
if($time < ($detail["start_time"]-(12*3600))){
$price = $order["sub_refundprice"];
}else{
$price = bcdiv($order["sub_refundprice"],2,2);
}
break;
case "9": //前24小时退
//还没到开始前24小时退100%
//过了开始前24小时退50%
if($time < ($detail["start_time"]-(24*3600))){
$price = $order["sub_refundprice"];
}else{
$price = bcdiv($order["sub_refundprice"],2,2);
}
break;
case "11": //前48小时退
//还没到开始前48小时退100%
//过了开始前48小时退50%
if($time < ($detail["start_time"]-(48*3600))){
$price = $order["sub_refundprice"];
}else{
$price = bcdiv($order["sub_refundprice"],2,2);
}
break; break;
default: default:
throw new \Exception("不支持的退款策略,请走售后流程!"); throw new \Exception("不支持的退款策略,请走售后流程!");

View File

@ -315,8 +315,8 @@ class Order extends BaseModel
} }
if (isset($whereData['status'])) $model = $model->where("{$alisa}status", 'in', $whereData['status']); if (isset($whereData['status']) && $whereData['status']!=="") $model = $model->where("{$alisa}status", 'in', $whereData['status']);
if (isset($whereData['not_status'])) $model = $model->where("{$alisa}status", 'not in', $whereData['not_status']); if (isset($whereData['not_status']) && $whereData['status']!=="") $model = $model->where("{$alisa}status", 'not in', $whereData['not_status']);
if (isset($whereData['auth_status'] ) && $whereData['auth_status']!=="") $model = $model->where("{$alisa}auth_status", 'in', $whereData['auth_status']); if (isset($whereData['auth_status'] ) && $whereData['auth_status']!=="") $model = $model->where("{$alisa}auth_status", 'in', $whereData['auth_status']);
if (isset($whereData['not_auth_status'])&& $whereData['not_auth_status']!=="") $model = $model->where("{$alisa}auth_status", 'not in', $whereData['not_auth_status']); if (isset($whereData['not_auth_status'])&& $whereData['not_auth_status']!=="") $model = $model->where("{$alisa}auth_status", 'not in', $whereData['not_auth_status']);

View File

@ -208,6 +208,9 @@ class UserwithdrawalLog extends BaseModel
$price = bcadd($real_price,$fee_price,2); $price = bcadd($real_price,$fee_price,2);
$status = '1'; $status = '1';
$min_price = config("site.withdrawal_min");
if( $real_price < $min_price)throw new \Exception("最低提现金额为".$min_price);
//查询是否有提现银行卡信息 //查询是否有提现银行卡信息
$userWithdrawal = Userwithdrawal::where('user_id',$user_id)->find(); $userWithdrawal = Userwithdrawal::where('user_id',$user_id)->find();

View File

@ -58,6 +58,8 @@ define(['jquery', 'bootstrap', 'backend', 'csmtable', 'form'], function ($, unde
{field: 'beforeprice', title: __('Beforeprice'), operate:'BETWEEN'}, {field: 'beforeprice', title: __('Beforeprice'), operate:'BETWEEN'},
{field: 'totalprice', title: __('Totalprice'), operate:'BETWEEN'}, {field: 'totalprice', title: __('Totalprice'), operate:'BETWEEN'},
{field: 'num', title: __('购买人数'), operate:'BETWEEN'}, {field: 'num', title: __('购买人数'), operate:'BETWEEN'},
{field: 'detail.price', title: __('购买单价'), operate:'BETWEEN'},
{field: 'payprice', title: __('Payprice'), operate:'BETWEEN'}, {field: 'payprice', title: __('Payprice'), operate:'BETWEEN'},
{field: 'pay_type', title: __('Pay_type'), searchList: {"yue":__('Pay_type yue'),"wechat":__('Pay_type wechat')}, formatter: Table.api.formatter.normal}, {field: 'pay_type', title: __('Pay_type'), searchList: {"yue":__('Pay_type yue'),"wechat":__('Pay_type wechat')}, formatter: Table.api.formatter.normal},
{field: 'before_status',visible:false, title: __('Before_status'), searchList: {"-3":__('Before_status -3'),"0":__('Before_status 0'),"2":__('Before_status 2'),"3":__('Before_status 3'),"4":__('Before_status 4'),"6":__('Before_status 6'),"9":__('Before_status 9')}, formatter: Table.api.formatter.status}, {field: 'before_status',visible:false, title: __('Before_status'), searchList: {"-3":__('Before_status -3'),"0":__('Before_status 0'),"2":__('Before_status 2'),"3":__('Before_status 3'),"4":__('Before_status 4'),"6":__('Before_status 6'),"9":__('Before_status 9')}, formatter: Table.api.formatter.status},