发布端:订单核销 活动发布和取消
用户端:订单支付,订单核销,订单完成接口,免费订单和待支付订单取消,定时取消 ,订单完成释放结算单,定时任务结算单解冻任务
This commit is contained in:
parent
978b5ec335
commit
4e4c48d872
@ -5,6 +5,7 @@ use addons\epay\library\Service;
|
||||
use app\common\controller\Api;
|
||||
use app\common\library\NightSchoolBigData;
|
||||
use app\common\model\school\activity\Activity;
|
||||
use app\common\model\school\activity\order\SettleLog;
|
||||
use app\common\model\school\classes\order\Order;
|
||||
use app\common\model\school\classes\VisitDistribution;
|
||||
use bw\UrlLock;
|
||||
@ -110,7 +111,8 @@ class Crontab extends Api
|
||||
// $res = Order::timeoutCheck(true);
|
||||
// $res = \app\common\model\school\classes\activity\order\Order::timeoutCheck(true);
|
||||
Activity::timeoutCheck(true);
|
||||
|
||||
SettleLog::timeoutCheck(null,null,true);
|
||||
\app\common\model\school\activity\order\Order::timeoutCheck(0,true);
|
||||
|
||||
// $lock = new UrlLock(2,"mock-lock-suffix",5,"您的请求过于频繁,请您稍后再试!");
|
||||
// $lock->lock();
|
||||
|
@ -4,6 +4,8 @@ namespace app\api\controller\school\newactivity;
|
||||
|
||||
use app\api\controller\school\Base;
|
||||
use app\common\model\school\activity\order\Order as OrderModel;
|
||||
use app\common\model\school\activity\order\OrderCode;
|
||||
|
||||
/**
|
||||
* 用户端:新活动订单接口
|
||||
*/
|
||||
@ -137,4 +139,104 @@ class Order extends Base
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @ApiTitle( 订单确认/订单计算接口)
|
||||
* @ApiSummary(订单确认/订单计算接口【有过期时间】)
|
||||
* @ApiMethod(POST)
|
||||
* @ApiParams(name = "activity_id", type = "int",required=true,description = "活动id")
|
||||
* @ApiParams(name = "order_no", type = "string",required=false,description = "缓存key")
|
||||
* @ApiParams(name = "num", type = "int",required=true,description = "购买人数")
|
||||
* @ApiParams(name = "is_compute", type = "int",required=false,description = "是否重新计算并更新缓存 默认传1")
|
||||
* @ApiReturn({
|
||||
*
|
||||
*})
|
||||
*/
|
||||
public function confirm(){
|
||||
$user_id = 0;
|
||||
$user = $this->auth->getUser();//登录用户
|
||||
if($user)$user_id = $user['id'];
|
||||
$activity_id = $this->request->post('activity_id/d', 0); //课程id
|
||||
$num = $this->request->post('num/d', 0); //想同时约的课时id
|
||||
// $param = urldecode($this->request->post('param/s', "{}")); //参数
|
||||
$param = [];
|
||||
|
||||
//参数
|
||||
$order_no = $this->request->post('order_no/s', ''); //订单号
|
||||
$is_compute = $this->request->post('is_compute/d', 1); //是否重新计算并更新缓存
|
||||
try{
|
||||
//当前申请状态
|
||||
$res = $this->model->confirm($user_id, $activity_id,$num,$order_no,$param, $is_compute);
|
||||
}catch (\Exception $e){
|
||||
// Log::log($e->getMessage());
|
||||
$this->error($e->getMessage(),['errcode'=>$e->getCode()]);
|
||||
}
|
||||
$this->success('执行成功,可用缓存key下单', $res);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @ApiTitle( 订单下单接口)
|
||||
* @ApiSummary(订单下单接口)
|
||||
* @ApiMethod(POST)
|
||||
* @ApiParams(name = "order_no", type = "string",required=true,description = "缓存key")
|
||||
* @ApiReturn({
|
||||
*
|
||||
*})
|
||||
*/
|
||||
public function create(){
|
||||
$user_id = 0;
|
||||
$user = $this->auth->getUser();//登录用户
|
||||
if($user)$user_id = $user['id'];
|
||||
$order_no = $this->request->post('order_no/s', ''); //订单号
|
||||
$remark = $this->request->post('remark/s', ''); //下单备注
|
||||
$this->setUrlLock("only");
|
||||
// repeat_filter("appointment\order\create".$user_id, 2);
|
||||
try{
|
||||
//当前申请状态
|
||||
$res = $this->model->cacheCreateOrder($order_no,$user_id,$remark,true);
|
||||
}catch (\Throwable $e){
|
||||
// file_put_contents("test.txt",$e->getMessage().$e->getFile().$e->getLine());//写入文件,一般做正式环境测试
|
||||
// Log::log($e->getMessage());
|
||||
$this->error($e->getMessage(),['errcode'=>$e->getCode()]);;
|
||||
}
|
||||
$this->success('订单创建成功,缓存key被消耗', $res);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @ApiTitle(免费单和未支付单取消接口)
|
||||
* @ApiSummary(活动单取消接口(免费单和未支付单取消))
|
||||
* @ApiMethod(POST)
|
||||
* @ApiParams(name = "order_no", type = "string",required=true,description = "订单号")
|
||||
* @ApiReturn({
|
||||
*
|
||||
*})
|
||||
*/
|
||||
public function freecancel(){
|
||||
$user_id = 0;
|
||||
$user = $this->auth->getUser();//登录用户
|
||||
if($user)$user_id = $user['id'];
|
||||
$order_no = $this->request->post('order_no/s', ''); //订单号
|
||||
try{
|
||||
//当前申请状态
|
||||
$res = $this->model->freeCancel($order_no,$user_id,true,'user',0,true);
|
||||
}catch (\Throwable $e){
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
$this->success('活动订单取消成功', $res);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
327
application/api/controller/school/newactivity/Pay.php
Normal file
327
application/api/controller/school/newactivity/Pay.php
Normal file
@ -0,0 +1,327 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller\school\newactivity;
|
||||
|
||||
use addons\epay\library\Service;
|
||||
use addons\third\model\Third;
|
||||
use app\api\controller\school\Base;
|
||||
use app\common\model\school\activity\order\Order as OrderModel;
|
||||
use Exception;
|
||||
|
||||
use think\Log;
|
||||
|
||||
/**
|
||||
* 新活动支付接口
|
||||
*/
|
||||
class Pay extends Base
|
||||
{
|
||||
|
||||
protected $noNeedLogin = '*';
|
||||
protected $noNeedRight = '*';
|
||||
protected $model = null;
|
||||
|
||||
/**
|
||||
* 初始化操作
|
||||
* @access protected
|
||||
*/
|
||||
protected function _initialize()
|
||||
{
|
||||
|
||||
$this->model = new OrderModel;
|
||||
parent::_initialize();
|
||||
$this->setUrlLock();
|
||||
//判断登录用户是否是员工
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @ApiTitle( 活动第三方支付)
|
||||
* @ApiSummary(活动第三方支付(微信等支付))
|
||||
* @ApiMethod(POST)
|
||||
* @ApiParams(name = "order_no", type = "string",required=true,description = "订单id或订单号")
|
||||
* @ApiParams(name = "type", type = "string",required=true,description = "服务商:alipay=支付宝,wechat=微信")
|
||||
* @ApiParams(name = "platform", type = "string",required=true,description = "平台:web=PC网页支付,wap=H5手机网页支付,app=APP支付,scan=扫码支付,mp=微信公众号支付,miniapp=微信小程序支付")
|
||||
* @ApiParams(name = "openid", type = "string",required=false,description = "用户openid(非必填)")
|
||||
* @ApiReturn({
|
||||
*
|
||||
*})
|
||||
*/
|
||||
public function payment()
|
||||
{
|
||||
$order_no = $this->request->post('order_no/s');
|
||||
$type = $this->request->post('type/s');
|
||||
$method = $this->request->post('platform/s');
|
||||
$openid = $this->request->post('openid/s', "");
|
||||
$platform = $method;
|
||||
try {
|
||||
//订单支付前校验
|
||||
$this->model->checkPay($order_no,$type);
|
||||
$order = OrderModel::where('order_no', $order_no)->find();
|
||||
$amount = $order["totalprice"];
|
||||
} catch (\Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!$amount || $amount < 0) {
|
||||
$this->error("支付金额必须大于0");
|
||||
}
|
||||
|
||||
if (!$type || !in_array($type, ['alipay', 'wechat'])) {
|
||||
$this->error("支付类型不能为空");
|
||||
}
|
||||
|
||||
if (in_array($method, ['miniapp', 'mp']) && !$openid) {
|
||||
|
||||
// 微信公众号,小程序支付,必须有 openid
|
||||
if (isset($openid) && $openid) {
|
||||
// 如果传的有 openid
|
||||
} else {
|
||||
// 没有 openid 默认拿下单人的 openid
|
||||
$oauth = Third::where([
|
||||
'user_id' => $order->user_id,
|
||||
'platform' => $type,
|
||||
'apptype' => $platform
|
||||
])->find();
|
||||
|
||||
$openid = $oauth ? $oauth->openid : '';
|
||||
}
|
||||
|
||||
if (!$openid) {
|
||||
// 缺少 openid
|
||||
$this->error("请您重新授权登录再下单");
|
||||
}
|
||||
}
|
||||
|
||||
//订单号
|
||||
$out_trade_no = $order_no;
|
||||
|
||||
//订单标题
|
||||
$title = '活动订单['.$out_trade_no."]支付";
|
||||
|
||||
//回调链接
|
||||
$notifyurl = $this->request->root(true) . '/api/school.newactivity.pay/notifyx/paytype/' . $type. '/platform/' . $method;
|
||||
$returnurl = $this->request->root(true) . '/api/school.newactivity.pay/returnx/paytype/' . $type . '/out_trade_no/' . $out_trade_no;
|
||||
|
||||
$response = Service::submitOrder($amount, $out_trade_no, $type, $title, $notifyurl, $returnurl, $method, $openid);
|
||||
|
||||
$this->success('查询成功', ["paydata"=>$response]);
|
||||
|
||||
// return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ApiTitle( 第三方支付支付成功回调)
|
||||
* @ApiSummary(第三方支付成功回调)
|
||||
* @ApiMethod(GET)
|
||||
* @ApiReturn({
|
||||
*
|
||||
*})
|
||||
*/
|
||||
public function notifyx()
|
||||
{
|
||||
$paytype = $this->request->param('paytype');
|
||||
$platform = $this->request->param('platform');
|
||||
$pay = Service::checkNotify($paytype);
|
||||
if (!$pay) {
|
||||
return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
|
||||
}
|
||||
$payment = $paytype;
|
||||
// 获取回调数据,V3和V2的回调接收不同
|
||||
$data = Service::isVersionV3() ? $pay->callback() : $pay->verify();
|
||||
|
||||
|
||||
|
||||
Log::write('notifyx-result:'. json_encode($data));
|
||||
|
||||
$out_trade_no = $data['out_trade_no'];
|
||||
$out_refund_no = $data['out_biz_no'] ?? '';
|
||||
|
||||
|
||||
|
||||
// 判断是否是支付宝退款(支付宝退款成功会通知该接口)
|
||||
if ($paytype == 'alipay' // 支付宝支付
|
||||
&& $data['notify_type'] == 'trade_status_sync' // 同步交易状态
|
||||
&& $data['trade_status'] == 'TRADE_CLOSED' // 交易关闭
|
||||
&& $out_refund_no // 退款单号
|
||||
) {
|
||||
// 退款回调
|
||||
|
||||
// $this->refundFinish($out_trade_no, $out_refund_no,$platform);
|
||||
|
||||
return $pay->success()->send();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 判断支付宝微信是否是支付成功状态,如果不是,直接返回响应
|
||||
if ($payment == 'alipay' && $data['trade_status'] != 'TRADE_SUCCESS') {
|
||||
// 不是交易成功的通知,直接返回成功
|
||||
return $pay->success()->send();
|
||||
}
|
||||
if ($payment == 'wechat' && ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS')) {
|
||||
// 微信交易未成功,返回 false,让微信再次通知
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
//微信支付V3返回和V2不同
|
||||
if (Service::isVersionV3() && $paytype === 'wechat') {
|
||||
$data = $data['resource']['ciphertext'];
|
||||
$data['total_fee'] = $data['amount']['total'];
|
||||
}
|
||||
|
||||
\think\Log::record($data);
|
||||
|
||||
$payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
|
||||
$out_trade_no = $data['out_trade_no'];
|
||||
|
||||
\think\Log::record("回调成功,订单号:{$out_trade_no},金额:{$payamount}");
|
||||
|
||||
//你可以在此编写订单逻辑
|
||||
|
||||
// 支付成功流程
|
||||
//获取支付金额、订单号
|
||||
$pay_fee = $payment == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
|
||||
|
||||
//你可以在此编写订单逻辑
|
||||
$order = OrderModel::getNopayOrder($out_trade_no);
|
||||
|
||||
if (!$order || $order["status"] != '0') {
|
||||
// 订单不存在,或者订单已支付
|
||||
return $pay->success()->send();
|
||||
}
|
||||
$notify = [
|
||||
'order_no' => $data['out_trade_no'],
|
||||
'transaction_id' => $payment == 'alipay' ? $data['trade_no'] : $data['transaction_id'],
|
||||
'notify_time' => date('Y-m-d H:i:s', strtotime($data['time_end'])),
|
||||
'buyer_email' => $payment == 'alipay' ? $data['buyer_logon_id'] : $data['openid'],
|
||||
'payment_json' => json_encode($data->all()),
|
||||
'pay_fee' => $pay_fee,
|
||||
'pay_type' => $payment, // 支付方式
|
||||
'platform' => $platform,
|
||||
];
|
||||
|
||||
$this->model->paySuccess($order['order_no'],$notify,$pay_fee,true,true);
|
||||
|
||||
|
||||
|
||||
} catch (Exception $e) {
|
||||
\think\Log::record("回调逻辑处理错误:" . $e->getMessage(), "error");
|
||||
}
|
||||
|
||||
//下面这句必须要执行,且在此之前不能有任何输出
|
||||
if (Service::isVersionV3()) {
|
||||
return $pay->success()->getBody()->getContents();
|
||||
} else {
|
||||
return $pay->success()->send();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付返回,网页支付版本(小程序忽略)
|
||||
*/
|
||||
public function returnx()
|
||||
{
|
||||
$paytype = $this->request->param('paytype');
|
||||
$out_trade_no = $this->request->param('out_trade_no');
|
||||
$pay = Service::checkReturn($paytype);
|
||||
if (!$pay) {
|
||||
$this->error('签名错误', '');
|
||||
}
|
||||
|
||||
//你可以在这里定义你的提示信息,但切记不可在此编写逻辑
|
||||
$this->success("请返回网站查看支付结果", addon_url("epay/index/index"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 支付返回
|
||||
*/
|
||||
public function notifyRefund($callback)
|
||||
{
|
||||
$pay = $this->getPay();
|
||||
|
||||
try {
|
||||
$data = $pay->verify(null, true); // 是的,验签就这么简单!
|
||||
|
||||
$result = $callback($data, $pay);
|
||||
|
||||
// Log::debug('Wechat notify', $data->all());
|
||||
} catch (\Exception $e) {
|
||||
// $e->getMessage();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 退款成功回调
|
||||
*/
|
||||
public function notifyr()
|
||||
{
|
||||
Log::write('notifyreturn-comein:');
|
||||
|
||||
$payment = $this->request->param('payment');
|
||||
$platform = $this->request->param('platform');
|
||||
|
||||
$config = Service::getConfig('wechat');
|
||||
|
||||
$notify_url = request()->domain() . '/api/school.newactivity.pay/notifyr/payment/' . $payment . '/platform/' . $platform;
|
||||
|
||||
$config['notify_url'] = $notify_url;
|
||||
$pay = \Yansongda\Pay\Pay::wechat($config);
|
||||
|
||||
try {
|
||||
$data = $pay->verify(null, true); // 是的,验签就这么简单!
|
||||
|
||||
Log::write('notifyr-result:' . json_encode($data));
|
||||
|
||||
$out_refund_no = $data['out_refund_no'];
|
||||
$out_trade_no = $data['out_trade_no'];
|
||||
|
||||
// 退款
|
||||
$this->refundFinish($out_trade_no, $out_refund_no,$platform,$data);
|
||||
|
||||
|
||||
return $pay->success()->send();
|
||||
// Log::debug('Wechat notify', $data->all());
|
||||
} catch (\Exception $e) {
|
||||
Log::write('notifyreturn-error:' . $e->getMessage());
|
||||
$this->model::orderRefundFail($out_trade_no,$e->getMessage(),'user',0,true);
|
||||
|
||||
}
|
||||
return $pay->success()->send();
|
||||
}
|
||||
|
||||
|
||||
private function refundFinish($out_trade_no, $out_refund_no,$platform,$refund_json) {
|
||||
|
||||
// $order = Order::where('order_sn', $out_trade_no)->find();
|
||||
// $refundLog = \app\admin\model\shopro\order\RefundLog::where('refund_sn', $out_refund_no)->find();
|
||||
//
|
||||
// if (!$order || !$refundLog || $refundLog->status != 0) {
|
||||
// // 订单不存在,或者订单已退款
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// $item = \app\admin\model\shopro\order\OrderItem::where('id', $refundLog->order_item_id)->find();
|
||||
//
|
||||
// Db::transaction(function () use ($order, $item, $refundLog) {
|
||||
// \app\admin\model\shopro\order\Order::refundFinish($order, $item, $refundLog);
|
||||
// });
|
||||
$this->model::refundSuccess($out_refund_no,$refund_json,true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -5,6 +5,8 @@ namespace app\api\controller\school\newworker\activity;
|
||||
use app\api\controller\school\newworker\Base;
|
||||
|
||||
use app\common\model\school\activity\order\Order as OrderModel;
|
||||
use app\common\model\school\activity\order\OrderCode;
|
||||
|
||||
/**
|
||||
* 员工端:活动订单管理接口
|
||||
*/
|
||||
@ -131,5 +133,33 @@ class Order extends Base
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @ApiTitle( 员工操作:订单核销接口)
|
||||
* @ApiSummary(订单核销接口)
|
||||
* @ApiMethod(POST)
|
||||
* @ApiParams(name = "code", type = "string",required=true,description = "核销码")
|
||||
* @ApiReturn({
|
||||
*
|
||||
*})
|
||||
*/
|
||||
public function verification(){
|
||||
$this->model = new OrderCode();
|
||||
|
||||
$this->setUrlLock();
|
||||
|
||||
$user_id = 0;
|
||||
$user = $this->auth->getUser();//登录用户
|
||||
if($user)$user_id = $user['id'];
|
||||
$code = $this->request->post('code/s', ''); //订单号
|
||||
try{
|
||||
//当前申请状态
|
||||
$res = $this->model->verification($code,0,true,'user',$user_id,true);
|
||||
}catch (\Throwable $e){
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
$this->success('预约课时核销成功', $res);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -282,9 +282,14 @@ $newactivityOrderHooks = [
|
||||
'activity_order_payed_after' => [ // 订单支付成功
|
||||
'app\\common\\listener\\activity\\OrderHook'
|
||||
],
|
||||
// 'classes_activity_order_cancel_after' => [ // 订单取消后
|
||||
// 'app\\common\\listener\\activityorder\\OrderHook'
|
||||
// ],
|
||||
|
||||
'activity_order_verification_after' => [ // 订单核销成功后
|
||||
'app\\common\\listener\\activity\\OrderHook'
|
||||
],
|
||||
|
||||
'activity_order_cancel_after' => [ // 订单取消后
|
||||
'app\\common\\listener\\activity\\OrderHook'
|
||||
],
|
||||
// 'classes_activity_order_auth_success_after' => [ // 订单审核通过后
|
||||
// 'app\\common\\listener\\activityorder\\OrderHook'
|
||||
// ],
|
||||
@ -298,9 +303,9 @@ $newactivityOrderHooks = [
|
||||
// 'classes_activity_order_refund_fail_after'=> [ // 订单审核失败后退款成功
|
||||
// 'app\\common\\listener\\activityorder\\OrderHook'
|
||||
// ],
|
||||
// 'classes_activity_order_finish_after' => [ // 订单完成后
|
||||
// 'app\\common\\listener\\activityorder\\OrderHook'
|
||||
// ],
|
||||
'activity_order_finish_after' => [ // 订单完成后
|
||||
'app\\common\\listener\\activity\\OrderHook'
|
||||
],
|
||||
|
||||
|
||||
];
|
||||
|
@ -131,6 +131,171 @@ class OrderHook
|
||||
}
|
||||
|
||||
|
||||
public function activityOrderVerificationAfter(&$params)
|
||||
{
|
||||
["order"=>$order] = $params;
|
||||
|
||||
$order = Order::where("id" , $order["id"])->find();
|
||||
|
||||
$detail = $order->detail;
|
||||
$user = $order->user;
|
||||
//记录订单日志
|
||||
$mini_type = "activity_order";
|
||||
$to_id = $order["user_id"];
|
||||
$status ="activity";
|
||||
$params=[
|
||||
"event"=>"activity_order_verification_after",
|
||||
"order_id"=>$order["id"],
|
||||
"order_no"=>$order["order_no"],
|
||||
"activity_id"=>$order["activity_id"],
|
||||
];
|
||||
$param = [
|
||||
"title"=>$detail["title"],
|
||||
"order_no" => $order["order_no"],
|
||||
"nickname" => $user["nickname"],
|
||||
"realname" => $user["realname"],
|
||||
"mobile" => $user["mobile"],
|
||||
"price" => $order["totalprice"],
|
||||
"payprice" => $order["payprice"],
|
||||
"real_refundprice" => $order["real_refundprice"],
|
||||
"sub_refundprice" => $order["sub_refundprice"],
|
||||
"reason" => $order["reason"],
|
||||
"address"=>$detail["address"]."(".$detail["address_detail"].")",
|
||||
"start_time" => date("Y-m-d H:i",$detail["start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式
|
||||
"end_time" => date("Y-m-d H:i",$detail["end_time"]),
|
||||
"sign_start_time" => date("Y-m-d H:i",$detail["sign_start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式
|
||||
"sign_end_time" => date("Y-m-d H:i",$detail["sign_end_time"]),
|
||||
];
|
||||
|
||||
(new MessageConfig)
|
||||
->setTemplate($params["event"])
|
||||
->setTemplateData($param)
|
||||
->setToUid($to_id)
|
||||
->setMessageStatus($status)
|
||||
->setMessageMiniType($mini_type)
|
||||
->setMessageParams($params)
|
||||
->sendMessage();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 订单核销完成后
|
||||
public function activityOrderFinishAfter(&$params)
|
||||
{
|
||||
['order' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id] = $params;
|
||||
|
||||
|
||||
$order = Order::where("id" , $order["id"])->find();
|
||||
$detail = $order->detail;
|
||||
$user = $order->user;
|
||||
//记录订单日志
|
||||
$mini_type = "activity_order";
|
||||
$to_id = $order["user_id"];
|
||||
$status ="activity";
|
||||
$params=[
|
||||
"event"=>"activity_order_finish_after",
|
||||
"order_id"=>$order["id"],
|
||||
"order_no"=>$order["order_no"],
|
||||
"activity_id"=>$order["activity_id"],
|
||||
];
|
||||
$param = [
|
||||
"title"=>$detail["title"],
|
||||
"order_no" => $order["order_no"],
|
||||
"nickname" => $user["nickname"],
|
||||
"realname" => $user["realname"],
|
||||
"mobile" => $user["mobile"],
|
||||
"price" => $order["totalprice"],
|
||||
"payprice" => $order["payprice"],
|
||||
"real_refundprice" => $order["real_refundprice"],
|
||||
"sub_refundprice" => $order["sub_refundprice"],
|
||||
"reason" => $order["reason"],
|
||||
"address"=>$detail["address"]."(".$detail["address_detail"].")",
|
||||
"start_time" => date("Y-m-d H:i",$detail["start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式
|
||||
"end_time" => date("Y-m-d H:i",$detail["end_time"]),
|
||||
"sign_start_time" => date("Y-m-d H:i",$detail["sign_start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式
|
||||
"sign_end_time" => date("Y-m-d H:i",$detail["sign_end_time"]),
|
||||
];
|
||||
|
||||
//发用户
|
||||
(new MessageConfig)
|
||||
->setTemplate($params["event"]."_user")
|
||||
->setTemplateData($param)
|
||||
->setToUid($to_id)
|
||||
->setMessageStatus($status)
|
||||
->setMessageMiniType($mini_type)
|
||||
->setMessageParams($params)
|
||||
->sendMessage();
|
||||
//发所有核销员
|
||||
(new MessageConfig)
|
||||
->setTemplate($params["event"]."_verification")
|
||||
->setTemplateData($param)
|
||||
->setToUid($detail["user_id"])
|
||||
->setMessageStatus($status)
|
||||
->setMessageMiniType($mini_type)
|
||||
->setMessageParams($params)
|
||||
->sendMessage();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 订单取消成功后
|
||||
public function activityOrderCancelAfter(&$params)
|
||||
{
|
||||
["order"=>$order] = $params;
|
||||
|
||||
$order = Order::where("id" , $order["id"])->find();
|
||||
|
||||
$detail = $order->detail;
|
||||
$user = $order->user;
|
||||
//记录订单日志
|
||||
$mini_type = "activity_order";
|
||||
$to_id = $order["user_id"];
|
||||
$status ="activity";
|
||||
$params=[
|
||||
"event"=>"activity_order_cancel_after",
|
||||
"order_id"=>$order["id"],
|
||||
"order_no"=>$order["order_no"],
|
||||
"activity_id"=>$order["activity_id"],
|
||||
];
|
||||
$param = [
|
||||
"title"=>$detail["title"],
|
||||
"order_no" => $order["order_no"],
|
||||
"nickname" => $user["nickname"],
|
||||
"realname" => $user["realname"],
|
||||
"mobile" => $user["mobile"],
|
||||
"price" => $order["totalprice"],
|
||||
"payprice" => $order["payprice"],
|
||||
"real_refundprice" => $order["real_refundprice"],
|
||||
"sub_refundprice" => $order["sub_refundprice"],
|
||||
"reason" => $order["reason"],
|
||||
"address"=>$detail["address"]."(".$detail["address_detail"].")",
|
||||
"start_time" => date("Y-m-d H:i",$detail["start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式
|
||||
"end_time" => date("Y-m-d H:i",$detail["end_time"]),
|
||||
"sign_start_time" => date("Y-m-d H:i",$detail["sign_start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式
|
||||
"sign_end_time" => date("Y-m-d H:i",$detail["sign_end_time"]),
|
||||
];
|
||||
|
||||
(new MessageConfig)
|
||||
->setTemplate($params["event"])
|
||||
->setTemplateData($param)
|
||||
->setToUid($to_id)
|
||||
->setMessageStatus($status)
|
||||
->setMessageMiniType($mini_type)
|
||||
->setMessageParams($params)
|
||||
->sendMessage();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -416,8 +416,9 @@ class Activity extends BaseModel
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//settlement_time 最后结算时间等于活动结束时间往后延长n秒,n取配置
|
||||
$activity_end_settle = config("site.activity_end_settle") ?:0;
|
||||
$params["settlement_time"] = $end_time + $activity_end_settle;
|
||||
|
||||
$rule = [
|
||||
'user_id'=>'require',
|
||||
@ -1092,7 +1093,7 @@ class Activity extends BaseModel
|
||||
$res = true;
|
||||
try{
|
||||
$row = self::get($id);
|
||||
if(!$row)throw new \Exception("找不到活动!");
|
||||
if(!$row)return false;
|
||||
|
||||
$now_time = time();
|
||||
$sign_start_time = $row["sign_start_time"];
|
||||
|
@ -433,6 +433,9 @@ class Order extends BaseModel
|
||||
// $data->user;
|
||||
$data->user->visible(['id','nickname','mobile','avatar','realname']);
|
||||
|
||||
//超时检测
|
||||
self::timeoutCheck($data["id"]);
|
||||
|
||||
//规格信息
|
||||
$data->ordercode;
|
||||
|
||||
@ -533,11 +536,13 @@ class Order extends BaseModel
|
||||
//校验订单参数
|
||||
//课程活动是否存在并上架
|
||||
$activity = Activity::where('id',$activity_id)->find();
|
||||
if(!$activity || $activity['status']!='2' || $activity['auth_status']!='1') throw new \Exception("该活动不在可报名时间段!");
|
||||
if(!$activity ) throw new \Exception("该活动不存在!");
|
||||
|
||||
|
||||
//默认校验订单是否已创建
|
||||
if($check){
|
||||
if($activity['status']!='2' || $activity['auth_status']!='1') throw new \Exception("该活动不在可报名时间段!");
|
||||
|
||||
//此为创建订单时判断
|
||||
//判断订单是否已创建
|
||||
$order_info = self::where(['order_no'=>$order_no])->find();
|
||||
@ -601,6 +606,8 @@ class Order extends BaseModel
|
||||
// $activity_info["used_price"] = 0;
|
||||
|
||||
$totalprice = bcmul($num,$activity_info["price"],2);
|
||||
|
||||
|
||||
//组装订单下单数据
|
||||
$order_data = [];
|
||||
$order_data["user_id"] = $user_id;
|
||||
@ -612,6 +619,9 @@ class Order extends BaseModel
|
||||
$order_data["totalprice"] = $totalprice;
|
||||
$order_data["payprice"] = 0;
|
||||
$order_data["status"] = '0';
|
||||
$order_data["settle_log_time"] = $activity_info["settlement_time"];
|
||||
//根据手续费比例$activity_info["fee_scale"] 计算手续费
|
||||
$order_data["fee_price"] = bcmul($order_data["totalprice"],$order_data["fee_scale"],2);
|
||||
|
||||
|
||||
return compact('order_data','activity_info','user_data',"num");
|
||||
@ -667,7 +677,7 @@ class Order extends BaseModel
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function getNopayOrder($order_no){
|
||||
$order = self::where('order_no|id|pay_no',$order_no)->where("status",'0')->find();
|
||||
$order = self::where('order_no|id|pay_no',$order_no)->where("status","in",['0',"-3"])->find();
|
||||
if(!$order)throw new \Exception("待支付订单不存在");
|
||||
return $order;
|
||||
}
|
||||
@ -698,6 +708,9 @@ class Order extends BaseModel
|
||||
//不拆分订单,直接执行
|
||||
self::paySetData($order,$notify);
|
||||
|
||||
//释放结算订单
|
||||
(new SettleLog)->generatorLog($order['id']);
|
||||
|
||||
// //如果需要快捷预约
|
||||
// $classes_lib_spec_id = $order['classes_lib_spec_id'];
|
||||
// if($classes_lib_spec_id){
|
||||
@ -1009,6 +1022,478 @@ class Order extends BaseModel
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 检测支付开关(待扩展)
|
||||
*/
|
||||
public static function checkPaySwitch($pay_type,$user_id){
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**订单支付前判断
|
||||
* @param $order_no
|
||||
* @param $pay_type
|
||||
* @return array|false|\PDOStatement|string|Model
|
||||
*/
|
||||
public function checkPay($order_no,$pay_type,$password = null){
|
||||
$order = self::getNopayOrder($order_no);
|
||||
|
||||
//支付前判断
|
||||
//TODO通用判
|
||||
|
||||
$this->orderVaild($order['user_id'],$order['activity_id'],$order['num'],$order['order_no'], []);
|
||||
|
||||
//...
|
||||
$user = User::where('id',$order['user_id'])->find();
|
||||
if(!$user)throw new \Exception("支付用户异常");
|
||||
|
||||
//是否开通此支付方式
|
||||
self::checkPaySwitch($pay_type,$order['user_id']);
|
||||
|
||||
//各自币种判断
|
||||
switch ($pay_type) {
|
||||
case "wechat": //微信支付
|
||||
//..
|
||||
break;
|
||||
case "alipay": //支付宝支付
|
||||
//...
|
||||
break;
|
||||
case "offline": //线下支付
|
||||
//..
|
||||
break;
|
||||
case "yue": //余额支付
|
||||
//支付密码判断
|
||||
// $res = User::checkPayPassword($order['user_id'],$password,true);
|
||||
// if(!$res['is_setting'])throw new \Exception("您还未设置支付密码,请您先去设置支付密码");
|
||||
// if(!$res['is_right'])throw new \Exception("支付密码错误");
|
||||
//判断余额是否充足
|
||||
//得到支付余额
|
||||
$total_amount = $order['totalprice'] ?:0;
|
||||
//得到用户余额
|
||||
$money = $user['money'];
|
||||
if(bccomp($money,$total_amount)==-1)throw new \Exception("当前余额不足以完成本次支付!");
|
||||
break;
|
||||
default:
|
||||
throw new \Exception("不支持的支付类型验证");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** 课时订单操作权限检测
|
||||
* @param $order 订单
|
||||
* @param $oper_id 操作人id
|
||||
* @param $oper_type 操作人类型:user-用户或员工,admin-管理员
|
||||
* @return void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function checkOptionAuth($classes_order_id,$oper_id,$oper_type,$only_user=false,$only_shop=false,$only_admin=false){
|
||||
|
||||
//课程是否存在并上架
|
||||
$classesOrder = Order::where("id",$classes_order_id)->find();
|
||||
if(!$classesOrder)throw new \Exception("订单不存在!");
|
||||
|
||||
switch ($oper_type) {
|
||||
case 'user':
|
||||
if($only_admin)throw new \Exception("您无权操作该订单!");
|
||||
|
||||
//自己或操作员
|
||||
if($oper_id != $classesOrder["user_id"]){
|
||||
if($only_user) throw new \Exception("您无权操作该订单!");
|
||||
|
||||
//说明是操作员
|
||||
$help_user_info = User::where('id',$oper_id)->find();
|
||||
if(!$help_user_info) throw new \Exception("代下单员工不存在!");
|
||||
$classes_activity_ids = (new Activity())->getActivityAuthIds($oper_id);
|
||||
//判断当前订单课程是否在此课程授权范围内
|
||||
if(!in_array($classesOrder["activity_id"],$classes_activity_ids)) throw new \Exception("该活动不在您的授权范围内,无法代操作!");
|
||||
}else{
|
||||
$classes_activity_ids = (new Activity())->getActivityAuthIds($oper_id);
|
||||
//不是员工并且想操作只有机构能操作的单
|
||||
if(!in_array($classesOrder["activity_id"],$classes_activity_ids) && $only_shop)throw new \Exception("您无权操作该订单!");
|
||||
}
|
||||
break;
|
||||
case 'admin':
|
||||
$admin_info = Admin::where('id',$oper_id)->find();
|
||||
if(!$admin_info) throw new \Exception("代下单管理员不存在!");
|
||||
break;
|
||||
case 'shop':
|
||||
if($only_admin)throw new \Exception("您无权操作该订单!");
|
||||
|
||||
if($only_user) throw new \Exception("您无权操作该订单!");
|
||||
|
||||
$admin_info = Manystore::where('id',$oper_id)->find();
|
||||
if(!$admin_info) throw new \Exception("代下单管理员不存在!");
|
||||
$classes_activity_ids = (new Activity())->getActivityAuthIds($admin_info["user_id"]);
|
||||
//判断当前订单课程是否在此课程授权范围内
|
||||
if(!in_array($classesOrder["activity_id"],$classes_activity_ids)) throw new \Exception("该活动不在您的授权范围内,无法代操作!");
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new \Exception("请选择正确的代下单类型!");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** 检测订单完成状态
|
||||
* @param $order
|
||||
* @return void
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function statisticsAndUpdateOrderFinish($order){
|
||||
if(is_string($order)||is_numeric($order))$order = self::getOrder($order);
|
||||
$detail = $order->detail;
|
||||
if(!$detail)throw new \think\Exception("订单信息缺失!");
|
||||
//得到当前订单的所有已完成课时订单
|
||||
$hourorderOrderCount = OrderCode::where("status","=",'6')
|
||||
->where("activity_order_id","=",$order["id"])
|
||||
->count();
|
||||
//可完成的订单
|
||||
if(in_array($order["status"],["2",'3']) && (in_array($order["server_status"],['0'])) && !$order['finishtime']){
|
||||
//判定是否达成完成条件
|
||||
//条件:课程课时已全部完成
|
||||
if($hourorderOrderCount >= $order->num){
|
||||
//执行订单完成的更新逻辑
|
||||
self::updateFinish($order);
|
||||
}elseif($order["status"] == "2"){
|
||||
//更新订单状态成核销中
|
||||
$order["status"] = '3';
|
||||
$order["reservation_time"] = time();
|
||||
$order->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 更新订单成已完成
|
||||
* @param $order
|
||||
* @return void
|
||||
*/
|
||||
public static function updateFinish($order){
|
||||
if(is_string($order)||is_numeric($order))$order = self::getOrder($order);
|
||||
|
||||
//检测未核销订单,强制核销
|
||||
$orderCodes = OrderCode::where("status","=",'3')
|
||||
->where("activity_order_id","=",$order["id"])
|
||||
->select();
|
||||
foreach ($orderCodes as $k=>$orderCode){
|
||||
//强制核销
|
||||
(new OrderCode)->forceVerification($orderCode["code"],"admin",0,false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//更新订单
|
||||
$order["status"] = '9';
|
||||
|
||||
|
||||
$order["finishtime"] = time();
|
||||
|
||||
$order->save();
|
||||
//记录订单日志
|
||||
OrderLog::log($order['id'],"活动订单完成,人数已全部核销",'user',$order['user_id']);
|
||||
|
||||
|
||||
//释放结算订单
|
||||
(new SettleLog)->generatorLog($order['id']);
|
||||
|
||||
//调用支付成功事件
|
||||
$data = ['order' => $order];
|
||||
\think\Hook::listen('activity_order_finish_after', $data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**得到可取消的免费订单以及未支付取消
|
||||
* @param $order_no
|
||||
* @return array|false|\PDOStatement|string|Model
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function getHaveCancelFreeOrder($order_no){
|
||||
// $where = [self::STATUS_NOPAY,self::STATUS_PAYED];
|
||||
$order = self::where('order_no|id|pay_no',$order_no)->find();
|
||||
$detail = $order->detail;
|
||||
if(!$detail) throw new \Exception("订单信息缺失!");
|
||||
if(!$order)throw new \Exception("订单信息缺失!");
|
||||
//非免费单进行中无法取消
|
||||
if($order['totalprice'] != 0){
|
||||
//非免费单只有未支付的单才可以取消
|
||||
if($order['status'] != '0'){
|
||||
throw new \Exception("只有未支付的单才可以取消!");
|
||||
}
|
||||
}else{
|
||||
if(!in_array($order['status'],['0','2'])){
|
||||
throw new \Exception("免费单只有进行中订单可取消,已取消请忽重复取消!");
|
||||
}
|
||||
}
|
||||
|
||||
//活动开始后不可取消
|
||||
$time = time();
|
||||
if ($detail['start_time'] < $time) throw new \Exception("活动开始后不可取消!");
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
|
||||
/**更新免费订单取消状态以及未支付取消
|
||||
* @param $order
|
||||
* @return array|false|\PDOStatement|string|Model
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function updateFreeCancel($order){
|
||||
if(is_string($order))$order = self::getHaveCancelFreeOrder($order);
|
||||
$order->status = "-3";//refund_status
|
||||
$order->canceltime = time();
|
||||
$order->save();
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**免费订单取消以及未支付取消
|
||||
* @param $order_no
|
||||
* @param int $user_id
|
||||
* @param bool $check
|
||||
* @param bool $trans
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function freeCancel($order_no,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){
|
||||
//得到可取消订单
|
||||
$order = self::getHaveCancelFreeOrder($order_no);
|
||||
if($check){
|
||||
//用户操作权限检测
|
||||
self::checkOptionAuth($order['id'],$user_id ?: $oper_id,$oper_type);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//判断逻辑
|
||||
if($trans){
|
||||
self::beginTrans();
|
||||
}
|
||||
$res = true;
|
||||
try{
|
||||
//事务逻辑
|
||||
|
||||
//更新订单取消状态
|
||||
$order = self::updateFreeCancel($order);
|
||||
//插入订单取消日志
|
||||
if(!$user_id ||$order["user_id"] !=$user_id ){
|
||||
OrderLog::log($order['id'],"[系统操作]活动订单取消成功",$oper_type ?: 'user', $oper_id ?: $order['user_id']);
|
||||
}else{
|
||||
OrderLog::log($order['id'],"活动订单取消成功",$oper_type ?: 'user', $oper_id ?: $order['user_id']);
|
||||
}
|
||||
|
||||
//调用订单取消事件
|
||||
$data = ['order' => self::where("id",$order['id'])->find(),"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id];
|
||||
\think\Hook::listen('activity_order_cancel_after', $data);
|
||||
//执行课时数更新
|
||||
$res1 = self::statisticsAndUpdateClassesNumber($order['id']);
|
||||
|
||||
|
||||
if($trans){
|
||||
self::commitTrans();
|
||||
}
|
||||
}catch (\Exception $e){
|
||||
if($trans){
|
||||
self::rollbackTrans();
|
||||
}
|
||||
throw new \Exception($e->getMessage().$e->getFile().$e->getLine());
|
||||
}
|
||||
return $res1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 超时取消检测(未支付取消)
|
||||
*/
|
||||
public static function timeoutCheck($order_id=0,$trans = false){
|
||||
$count = 0;
|
||||
$unpaid_order_expire_time = config("site.unpaid_activity_cancel_time");
|
||||
if(!$unpaid_order_expire_time|| $unpaid_order_expire_time < 0)return $count;
|
||||
$unpaid_order_expire_time = time() - $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);
|
||||
$list = $model->select();
|
||||
|
||||
if ($trans) {
|
||||
self::beginTrans();
|
||||
}
|
||||
try {
|
||||
|
||||
|
||||
foreach ($list as $order)
|
||||
{
|
||||
//取消订单
|
||||
self::freeCancel($order['id'],0,false,'admin',0);
|
||||
$count++;
|
||||
}
|
||||
if ($trans) {
|
||||
self::commitTrans();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if ($trans) {
|
||||
self::rollbackTrans();
|
||||
}
|
||||
throw new \Exception($e->getMessage());
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**得到可取消的付费订单
|
||||
* @param $order_no
|
||||
* @return array|false|\PDOStatement|string|Model
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function getHaveCancelPaidOrder($order_no){
|
||||
// $where = [self::STATUS_NOPAY,self::STATUS_PAYED];
|
||||
$order = self::where('order_no|id|pay_no',$order_no)->find();
|
||||
$detail = $order->detail;
|
||||
if(!$detail) throw new \Exception("订单信息缺失!");
|
||||
if(!$order)throw new \Exception("订单信息缺失!");
|
||||
//非免费单进行中无法取消
|
||||
if($order['totalprice'] != 0){
|
||||
//非免费单只有未退款可退
|
||||
if(!in_array($order['status'],["2","3"])){
|
||||
throw new \Exception("只有已报名和核销中的单才可以取消!");
|
||||
}
|
||||
}else{
|
||||
throw new \Exception("免费单请走免费订单取消接口!");
|
||||
}
|
||||
//根据不同退款策略判断当前时间点是否可取消并退款
|
||||
$refund_status = $detail["refund_status"];
|
||||
//活动开始后不可取消,只能走售后
|
||||
$time = time();
|
||||
switch ($refund_status){
|
||||
case "1": //不退款
|
||||
|
||||
throw new \Exception("当前活动不支持取消退款,请走售后流程!");
|
||||
break;
|
||||
case "3": //开始前退
|
||||
case "5": //随时退
|
||||
if ($detail['start_time'] < $time) throw new \Exception("活动开始后不可取消,请走售后流程!");
|
||||
break;
|
||||
default:
|
||||
throw new \Exception("不支持的退款策略,请走售后流程!");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
|
||||
/**更新免费订单取消状态以及未支付取消
|
||||
* @param $order
|
||||
* @return array|false|\PDOStatement|string|Model
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function updatePaidCancel($order){
|
||||
if(is_string($order))$order = self::getHaveCancelFreeOrder($order);
|
||||
$order->status = "-3";//refund_status
|
||||
$order->canceltime = time();
|
||||
$order->save();
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**免费订单取消以及未支付取消
|
||||
* @param $order_no
|
||||
* @param int $user_id
|
||||
* @param bool $check
|
||||
* @param bool $trans
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function paidCancel($order_no,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){
|
||||
//得到可取消订单
|
||||
$order = self::getHaveCancelFreeOrder($order_no);
|
||||
if($check){
|
||||
//用户操作权限检测
|
||||
self::checkOptionAuth($order['id'],$user_id ?: $oper_id,$oper_type);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//判断逻辑
|
||||
if($trans){
|
||||
self::beginTrans();
|
||||
}
|
||||
$res = true;
|
||||
try{
|
||||
//事务逻辑
|
||||
|
||||
//更新订单取消状态
|
||||
$order = self::updateFreeCancel($order);
|
||||
//插入订单取消日志
|
||||
if(!$user_id ||$order["user_id"] !=$user_id ){
|
||||
OrderLog::log($order['id'],"[系统操作]活动订单取消成功",$oper_type ?: 'user', $oper_id ?: $order['user_id']);
|
||||
}else{
|
||||
OrderLog::log($order['id'],"活动订单取消成功",$oper_type ?: 'user', $oper_id ?: $order['user_id']);
|
||||
}
|
||||
|
||||
//调用订单取消事件
|
||||
$data = ['order' => self::where("id",$order['id'])->find(),"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id];
|
||||
\think\Hook::listen('activity_order_cancel_after', $data);
|
||||
//执行课时数更新
|
||||
$res1 = self::statisticsAndUpdateClassesNumber($order['id']);
|
||||
|
||||
|
||||
if($trans){
|
||||
self::commitTrans();
|
||||
}
|
||||
}catch (\Exception $e){
|
||||
if($trans){
|
||||
self::rollbackTrans();
|
||||
}
|
||||
throw new \Exception($e->getMessage().$e->getFile().$e->getLine());
|
||||
}
|
||||
return $res1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace app\common\model\school\activity\order;
|
||||
|
||||
use app\common\model\BaseModel;
|
||||
use app\common\model\school\activity\Activity;
|
||||
use think\Model;
|
||||
use traits\model\SoftDelete;
|
||||
|
||||
@ -68,4 +69,141 @@ class OrderCode extends BaseModel
|
||||
{
|
||||
return $this->belongsTo('app\common\model\User', 'verification_user_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**更新订单核销状态
|
||||
* @param $order
|
||||
* @return array|false|\PDOStatement|string|Model
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function updateVerification($code,$oper_id = 0,$oper_type='user',$check=true){
|
||||
if(is_string($code))$code = self::getHaveVerificationOrderCode($code,$check);
|
||||
$code->status = "6";//refund_status
|
||||
$code->verification_user_id = $oper_id;
|
||||
$code->verification_type = $oper_type;
|
||||
$code->verificationtime = time();
|
||||
$code->save();
|
||||
return $code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**得到可核销订单
|
||||
* @param $order_no
|
||||
* @return array|false|\PDOStatement|string|Model
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function getHaveVerificationOrderCode($code,$check=true){
|
||||
// $where = [self::STATUS_NOPAY,self::STATUS_PAYED];
|
||||
$ordercode = self::where('code',$code)->where("status","in",['3'])->find();
|
||||
if(!$ordercode)throw new \Exception("当前码已存在或核销过!");
|
||||
$order = $ordercode->order;
|
||||
if(!$order)throw new \Exception("订单异常!");
|
||||
if(!$check) return $ordercode;
|
||||
|
||||
if(!in_array($order["status"],['2','3']))throw new \Exception("当前订单不可核销!");
|
||||
//过了可核销时间段
|
||||
Activity::update_classes($order["activity_id"]);
|
||||
$activity = $order->activity;
|
||||
if(!$activity)throw new \Exception("活动异常!");
|
||||
if($activity["status"] != "4")throw new \Exception("当前活动还不能核销!");
|
||||
|
||||
return $ordercode;
|
||||
}
|
||||
|
||||
/** 强制核销订单
|
||||
* @param $code
|
||||
* @param $oper_type
|
||||
* @param $oper_id
|
||||
* @return array|false|\PDOStatement|string|Model
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function forceVerification($code,$oper_type='user',$oper_id=0,$check=true)
|
||||
{
|
||||
|
||||
$ordercode = self::updateVerification($code,$oper_id,$oper_type,$check);
|
||||
$order = $ordercode->order;
|
||||
if($check){
|
||||
|
||||
//插入订单取消日志
|
||||
if($oper_type!='user' || $order["user_id"] !=$oper_id ){
|
||||
OrderLog::log($order['id'],"[员工操作]活动订单成功核销一人",$oper_type ?: 'user', $oper_id ?: $order['user_id']);
|
||||
}else{
|
||||
OrderLog::log($order['id'],"活动订单成功核销一人",$oper_type ?: 'user', $oper_id ?: $order['user_id']);
|
||||
}
|
||||
|
||||
}else{
|
||||
OrderLog::log($order['id'],"活动结束订单强制完成核销(超时结算或特殊情况)",$oper_type ?: 'user', $oper_id ?: $order['user_id']);
|
||||
}
|
||||
|
||||
|
||||
//调用订单取消事件
|
||||
$data = ['order' => self::where("id",$order['id'])->find(),"user_id"=>$order["user_id"],"oper_type"=>$oper_type,"oper_id"=>$oper_id];
|
||||
\think\Hook::listen('activity_order_verification_after', $data);
|
||||
|
||||
//过了可核销时间段
|
||||
Activity::update_classes($order["activity_id"]);
|
||||
return $ordercode;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**订单核销
|
||||
* @param $code
|
||||
* @param int $user_id
|
||||
* @param bool $check
|
||||
* @param bool $trans
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function verification($code,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){
|
||||
//得到可取消订单
|
||||
$ordercode = self::getHaveVerificationOrderCode($code);
|
||||
$order = $ordercode->order;
|
||||
if($check){
|
||||
//用户操作权限检测
|
||||
Order::checkOptionAuth($order['id'],$user_id ?: $oper_id,$oper_type);
|
||||
|
||||
}
|
||||
|
||||
//判断逻辑
|
||||
if($trans){
|
||||
self::beginTrans();
|
||||
}
|
||||
$res = true;
|
||||
try{
|
||||
//事务逻辑
|
||||
//更新订单状态
|
||||
|
||||
$ordercode = $this->forceVerification($code,$oper_type,$oper_id);
|
||||
|
||||
//检测订单完成状态
|
||||
Order::statisticsAndUpdateOrderFinish($order['id']);
|
||||
|
||||
if($trans){
|
||||
self::commitTrans();
|
||||
}
|
||||
}catch (\Exception $e){
|
||||
if($trans){
|
||||
self::rollbackTrans();
|
||||
}
|
||||
throw new \Exception($e->getMessage());
|
||||
}
|
||||
return $ordercode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -107,4 +107,171 @@ class SettleLog extends BaseModel
|
||||
{
|
||||
return $this->belongsTo('app\common\model\User', 'pay_user_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||||
}
|
||||
|
||||
|
||||
/** 生成结算记录
|
||||
* @param $order_id
|
||||
* @param $trans
|
||||
* @return true
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function generatorLog($order_id,$trans=false){
|
||||
$order = Order::where("id" ,$order_id)->find();
|
||||
if(!$order) return false;
|
||||
//免费的忽略
|
||||
if($order->payprice <= 0) return false;
|
||||
$detail = $order->detail;
|
||||
if(!$detail) return false;
|
||||
$data = [
|
||||
"activity_order_id" => $order_id,
|
||||
"withdrawal_log_id" =>0,
|
||||
"to_user_id" => $detail->user_id,
|
||||
"pay_user_id" => $order->user_id,
|
||||
"status" =>'1',
|
||||
"unfreezetime" => $detail->settlement_time,
|
||||
"order_price" => $order->payprice,
|
||||
"sub_refundprice" =>$order->sub_refundprice,
|
||||
"fee_scale" => $order->fee_scale,
|
||||
"fee_price" => $order->fee_price,
|
||||
"settle_price" => bcsub($order->sub_refundprice,$order->fee_price,2)
|
||||
];
|
||||
//判断逻辑
|
||||
if($trans){
|
||||
self::beginTrans();
|
||||
}
|
||||
$res = true;
|
||||
try{
|
||||
$res =self::where([
|
||||
"activity_order_id" => $order_id,
|
||||
"status" =>'1',
|
||||
"to_user_id" => $detail->user_id,
|
||||
])->find();
|
||||
//保存
|
||||
if(!$res)$res = self::create($data);
|
||||
//记录状态检测
|
||||
$this->settleCheck($res["id"]);
|
||||
|
||||
if($trans){
|
||||
self::commitTrans();
|
||||
}
|
||||
}catch (\Exception $e){
|
||||
if($trans){
|
||||
self::rollbackTrans();
|
||||
}
|
||||
throw new \Exception($e->getMessage().$e->getFile().$e->getLine());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/** 结算冻结状态更新
|
||||
* @param $log_id
|
||||
* @param $trans
|
||||
* @return true
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function settleCheck($log,$trans=false){
|
||||
if(is_string($log)||is_numeric($log))$log = self::where("id" ,$log)->where("status",'1')->find();
|
||||
if(!$log) return false;
|
||||
//判断逻辑
|
||||
if($trans){
|
||||
self::beginTrans();
|
||||
}
|
||||
$res = true;
|
||||
try{
|
||||
$time = time();
|
||||
if($log->unfreezetime < $time){
|
||||
//更新状态
|
||||
$res = self::where("id" ,$log["id"])->update(["status" =>'2']);
|
||||
}
|
||||
|
||||
|
||||
if($trans){
|
||||
self::commitTrans();
|
||||
}
|
||||
}catch (\Exception $e){
|
||||
if($trans){
|
||||
self::rollbackTrans();
|
||||
}
|
||||
throw new \Exception($e->getMessage().$e->getFile().$e->getLine());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 超时检测
|
||||
*/
|
||||
public static function timeoutCheck($activity_order_id=null,$to_user_id=null,$trans = false){
|
||||
$count = 0;
|
||||
$model = self::where("status",'1');
|
||||
if($activity_order_id)$model = $model->where("activity_order_id",$activity_order_id);
|
||||
if($to_user_id)$model = $model->where("to_user_id",$to_user_id);
|
||||
//得到所有过期的队列
|
||||
$list = $model->select();
|
||||
|
||||
if ($trans) {
|
||||
self::beginTrans();
|
||||
}
|
||||
try {
|
||||
|
||||
foreach ($list as $log)
|
||||
{
|
||||
//更新结算状态
|
||||
(new self)->settleCheck($log,$trans=false);
|
||||
$count++;
|
||||
}
|
||||
if ($trans) {
|
||||
self::commitTrans();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if ($trans) {
|
||||
self::rollbackTrans();
|
||||
}
|
||||
throw new \Exception($e->getMessage());
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 批量关闭
|
||||
*/
|
||||
public static function allClose($activity_order_id=null,$to_user_id=null,$trans = false){
|
||||
$count = 0;
|
||||
$model = self::where("status",'2');
|
||||
if($activity_order_id)$model = $model->where("activity_order_id",$activity_order_id);
|
||||
if($to_user_id)$model = $model->where("to_user_id",$to_user_id);
|
||||
//得到所有过期的队列
|
||||
$list = $model->select();
|
||||
|
||||
if ($trans) {
|
||||
self::beginTrans();
|
||||
}
|
||||
try {
|
||||
|
||||
foreach ($list as $log)
|
||||
{
|
||||
|
||||
$log["status"] = "-1";
|
||||
$log["canceltime"] = time();
|
||||
$log->save();
|
||||
$count++;
|
||||
}
|
||||
if ($trans) {
|
||||
self::commitTrans();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if ($trans) {
|
||||
self::rollbackTrans();
|
||||
}
|
||||
throw new \Exception($e->getMessage());
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
||||
{field: 'id', title: __('Id')},
|
||||
// {field: 'config.name', title: __('Config.name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
|
||||
{field: 'config.logo_image', title: __('Config.logo_image'), operate: false, events: Table.api.events.image, formatter: Table.api.formatter.image},
|
||||
{field: 'event', title: __('Event'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
|
||||
{field: 'event_two', title: __('Event_two'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
|
||||
{field: 'event', title: __('Event'), table: table, class: 'autocontent', formatter: Table.api.formatter.content},
|
||||
{field: 'event_two', title: __('Event_two'), table: table, class: 'autocontent', formatter: Table.api.formatter.content},
|
||||
{field: 'name', title: __('Name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
|
||||
{field: 'wechat_wap', title: __('Wechat_wap'), searchList: {"1":__('Wechat_wap 1'),"2":__('Wechat_wap 2')}, formatter: Table.api.formatter.normal},
|
||||
{field: 'message', title: __('Message'), searchList: {"1":__('Message 1'),"2":__('Message 2')}, formatter: Table.api.formatter.normal},
|
||||
|
Loading…
x
Reference in New Issue
Block a user