发布端:订单核销 活动发布和取消
用户端:订单支付,订单核销,订单完成接口,免费订单和待支付订单取消,定时取消 ,订单完成释放结算单,定时任务结算单解冻任务
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