1953 lines
69 KiB
PHP
1953 lines
69 KiB
PHP
<?php
|
||
|
||
namespace app\common\model\school\classes\activity\order;
|
||
|
||
use addons\epay\library\Service;
|
||
use app\admin\model\Admin;
|
||
use app\admin\model\manystore\Shop;
|
||
use app\common\model\BaseModel;
|
||
use app\common\model\dyqc\ManystoreShop;
|
||
use app\common\model\school\classes\activity\Activity;
|
||
use app\common\model\school\classes\activity\ActivityItem;
|
||
use app\common\model\school\classes\ClassesLib;
|
||
use app\common\model\school\classes\ClassesSpec;
|
||
use app\common\model\school\classes\order\ServiceOrder;
|
||
use app\common\model\User;
|
||
use app\manystore\model\Manystore;
|
||
use bw\Common;
|
||
use fast\Random;
|
||
use think\Cache;
|
||
use think\Model;
|
||
use traits\model\SoftDelete;
|
||
use Yansongda\Pay\Pay;
|
||
|
||
class Order extends BaseModel
|
||
{
|
||
|
||
use SoftDelete;
|
||
|
||
|
||
|
||
// 表名
|
||
protected $name = 'school_classes_activity_order';
|
||
|
||
// 自动写入时间戳字段
|
||
protected $autoWriteTimestamp = 'integer';
|
||
|
||
// 定义时间戳字段名
|
||
protected $createTime = 'createtime';
|
||
protected $updateTime = 'updatetime';
|
||
protected $deleteTime = 'deletetime';
|
||
|
||
// 追加属性
|
||
protected $append = [
|
||
'pay_type_text',
|
||
'status_text',
|
||
'before_status_text',
|
||
'server_status_text',
|
||
'canceltime_text',
|
||
'paytime_text',
|
||
'auth_time_text',
|
||
'reservation_time_text',
|
||
'finishtime_text',
|
||
'refundtime_text',
|
||
'auth_status_text'
|
||
];
|
||
|
||
|
||
|
||
public function getPayTypeList()
|
||
{
|
||
return ['yue' => __('Pay_type yue'), 'wechat' => __('Pay_type wechat')];
|
||
}
|
||
|
||
public function getStatusList()
|
||
{
|
||
return ['-3' => __('Status -3'), '0' => __('Status 0'), '2' => __('Status 2'), '3' => __('Status 3'), '4' => __('Status 4'), '5' => __('Status 5'), '6' => __('Status 6'), '9' => __('Status 9')];
|
||
}
|
||
|
||
public function getBeforeStatusList()
|
||
{
|
||
return ['-3' => __('Before_status -3'), '0' => __('Before_status 0'), '2' => __('Before_status 2'), '3' => __('Before_status 3'), '4' => __('Before_status 4'), '6' => __('Before_status 6'), '9' => __('Before_status 9')];
|
||
}
|
||
|
||
public function getServerStatusList()
|
||
{
|
||
return ['0' => __('Server_status 0'), '3' => __('Server_status 3'), '6' => __('Server_status 6')];
|
||
}
|
||
|
||
public function getAuthStatusList()
|
||
{
|
||
return ['0' => __('Auth_status 0'), '1' => __('Auth_status 1'), '2' => __('Auth_status 2')];
|
||
}
|
||
|
||
|
||
public function getPayTypeTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['pay_type']) ? $data['pay_type'] : '');
|
||
$list = $this->getPayTypeList();
|
||
return isset($list[$value]) ? $list[$value] : '';
|
||
}
|
||
|
||
|
||
public function getStatusTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
|
||
$list = $this->getStatusList();
|
||
return isset($list[$value]) ? $list[$value] : '';
|
||
}
|
||
|
||
|
||
public function getBeforeStatusTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['before_status']) ? $data['before_status'] : '');
|
||
$list = $this->getBeforeStatusList();
|
||
return isset($list[$value]) ? $list[$value] : '';
|
||
}
|
||
|
||
|
||
public function getServerStatusTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['server_status']) ? $data['server_status'] : '');
|
||
$list = $this->getServerStatusList();
|
||
return isset($list[$value]) ? $list[$value] : '';
|
||
}
|
||
|
||
|
||
public function getCanceltimeTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['canceltime']) ? $data['canceltime'] : '');
|
||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||
}
|
||
|
||
|
||
public function getPaytimeTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['paytime']) ? $data['paytime'] : '');
|
||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||
}
|
||
|
||
|
||
public function getAuthTimeTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['auth_time']) ? $data['auth_time'] : '');
|
||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||
}
|
||
|
||
|
||
public function getReservationTimeTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['reservation_time']) ? $data['reservation_time'] : '');
|
||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||
}
|
||
|
||
|
||
public function getFinishtimeTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['finishtime']) ? $data['finishtime'] : '');
|
||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||
}
|
||
|
||
|
||
public function getRefundtimeTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['refundtime']) ? $data['refundtime'] : '');
|
||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||
}
|
||
|
||
|
||
public function getAuthStatusTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['auth_status']) ? $data['auth_status'] : '');
|
||
$list = $this->getAuthStatusList();
|
||
return isset($list[$value]) ? $list[$value] : '';
|
||
}
|
||
|
||
protected function setCanceltimeAttr($value)
|
||
{
|
||
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
|
||
}
|
||
|
||
protected function setPaytimeAttr($value)
|
||
{
|
||
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
|
||
}
|
||
|
||
protected function setAuthTimeAttr($value)
|
||
{
|
||
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
|
||
}
|
||
|
||
protected function setReservationTimeAttr($value)
|
||
{
|
||
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
|
||
}
|
||
|
||
protected function setFinishtimeAttr($value)
|
||
{
|
||
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
|
||
}
|
||
|
||
protected function setRefundtimeAttr($value)
|
||
{
|
||
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
|
||
}
|
||
|
||
|
||
public function getCodeimageAttr($value, $data)
|
||
{
|
||
if (!empty($value)) return cdnurl($value, true);
|
||
}
|
||
|
||
public function getCodeoneimageAttr($value, $data)
|
||
{
|
||
if (!empty($value)) return cdnurl($value, true);
|
||
}
|
||
|
||
|
||
public function user()
|
||
{
|
||
return $this->belongsTo('app\admin\model\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
|
||
public function manystore()
|
||
{
|
||
return $this->belongsTo(Manystore::class, 'manystore_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
|
||
public function shop()
|
||
{
|
||
return $this->belongsTo(ManystoreShop::class, 'shop_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
|
||
public function activity()
|
||
{
|
||
return $this->belongsTo(Activity::class, 'classes_activity_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
|
||
public function detail()
|
||
{
|
||
return $this->belongsTo(OrderDetail::class, 'activity_order_detail_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
public function orderitem()
|
||
{
|
||
return $this->belongsTo(OrderItem::class, 'activity_order_item_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
|
||
|
||
|
||
//统计并更新活动数等相关统计数据
|
||
public static function statisticsAndUpdateClassesNumber($order){
|
||
if(is_string($order)||is_numeric($order))$order = self::getOrder($order);
|
||
$detail = $order->detail;
|
||
if(!$detail)throw new \think\Exception("订单信息缺失!");
|
||
// //得到当前订单的所有未取消课时订单
|
||
// $hourorderOrderCount = \app\common\model\school\classes\activity\order\Order::where("status","<>",'-3')
|
||
// ->where("classes_order_id","=",$order["id"])
|
||
// ->count();
|
||
// //更新已用课程数和剩余课程数
|
||
// $detail->use_num = $hourorderOrderCount;
|
||
// $detail->sub_num = $detail->classes_num - $detail->use_num;
|
||
// //更新已用课程金额和剩余课程金额
|
||
//// $detail->used_price = bcmul($detail->unit_price , $detail->use_num,2);
|
||
// $detail->save();
|
||
|
||
// //得到所有售后单的已退金额
|
||
// $order->real_refundprice = ServiceOrder::where("classes_order_id" , $order["id"])->where("status","in",['7'])->where("sales_type","in",['10'])->sum("real_refundprice");
|
||
// //实际付款额 - 已退金额 = 剩余未退
|
||
// //更新剩余未退
|
||
// $order->sub_refundprice = bcsub($order->payprice,$order->real_refundprice,2);
|
||
// //更新订单应退金额
|
||
// $order->total_refundprice = bcsub($order->totalprice,$detail->used_price,2);
|
||
// $order->save();
|
||
|
||
|
||
//课程下单时已核销人数更新
|
||
$lib = $order->activity;
|
||
if($lib){
|
||
|
||
}
|
||
|
||
|
||
//将课程信息和课时信息同步到所有已下单的订单信息中
|
||
Activity::update_classes($order["classes_activity_id"]);
|
||
|
||
//如果有评价执行评价更新
|
||
return $order;
|
||
}
|
||
|
||
|
||
|
||
|
||
/**得到基础条件
|
||
* @param $status
|
||
* @param null $model
|
||
* @param string $alisa
|
||
*/
|
||
public static function getBaseWhere($whereData = [], $model = null, $alisa = '',$with = false)
|
||
{
|
||
|
||
if (!$model) {
|
||
$model = new static;
|
||
if ($alisa&&!$with) $model = $model->alias($alisa);
|
||
}
|
||
if ($alisa) $alisa = $alisa . '.';
|
||
$tableFields = (new static)->getTableFields();
|
||
foreach ($tableFields as $fields)
|
||
{
|
||
if(in_array($fields, ['status',"auth_status",'classes_activity_id']))continue;
|
||
// if (isset($whereData[$fields]) && $whereData[$fields]) $model = $model->where("{$alisa}{$fields}", '=', $whereData[$fields]);
|
||
|
||
if (isset($whereData[$fields]) && $whereData[$fields]){
|
||
if(is_array($whereData[$fields])){
|
||
$model = $model->where("{$alisa}{$fields}", $whereData[$fields][0], $whereData[$fields][1]);
|
||
}else{
|
||
$model = $model->where("{$alisa}{$fields}", '=', $whereData[$fields]);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
}
|
||
if (isset($whereData['status'])) $model = $model->where("{$alisa}status", 'in', $whereData['status']);
|
||
if (isset($whereData['not_status'])) $model = $model->where("{$alisa}status", 'not in', $whereData['not_status']);
|
||
|
||
if (isset($whereData['auth_status']) && $whereData['auth_status']!=="") $model = $model->where("{$alisa}auth_status", 'in', $whereData['auth_status']);
|
||
if (isset($whereData['not_auth_status'])&& $whereData['not_auth_status']!=="") $model = $model->where("{$alisa}auth_status", 'not in', $whereData['not_auth_status']);
|
||
|
||
|
||
if (isset($whereData['keywords'])&&$whereData['keywords']) $model = $model->where("{$alisa}order_no|{$alisa}pay_no|{$alisa}code", '=', $whereData['keywords']);
|
||
if (isset($whereData['time'])&&$whereData['time']){
|
||
|
||
$model = $model->time(["{$alisa}createtime",$whereData['time']]);
|
||
}
|
||
if (isset($whereData['user_id']) && $whereData['user_id']) $model = $model->where("{$alisa}user_id", '=', $whereData['user_id']);
|
||
|
||
if (isset($whereData['classes_activity_ids']) && $whereData['classes_activity_ids']) $model = $model->where("{$alisa}classes_activity_id", 'in', $whereData['classes_activity_ids']);
|
||
if (isset($whereData['classes_activity_id']) && $whereData['classes_activity_id']) $model = $model->where("{$alisa}classes_activity_id", 'in', $whereData['classes_activity_id']);
|
||
|
||
// if (isset($whereData['has_evaluate'])&&$whereData['has_evaluate']){
|
||
// //1查已评价 2查未评价
|
||
// if($whereData['has_evaluate'] == 1){
|
||
// //1查已评价
|
||
// $model = $model->where("{$alisa}classes_evaluate_id", '<>', 0);
|
||
// }else{
|
||
// //2查未评价
|
||
// $model = $model->whereExists(function ($query) use ($alisa) {
|
||
// $order_table_name = (new \app\common\model\school\classes\hourorder\Order())->getQuery()->getTable();
|
||
// $query->table($order_table_name)->where($order_table_name . '.classes_order_id=' . $alisa . 'id')->where('status', '=', '3');
|
||
// })->where("{$alisa}classes_evaluate_id", '=', 0);
|
||
//
|
||
// }
|
||
// }
|
||
|
||
return $model;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
public static function allList($user_id,$page, $limit,$keywords,$status,$classes_activity_id=[],$has_evaluate=0,$auth_status=""){
|
||
$with_field = [
|
||
'user'=>['nickname','mobile','avatar','realname'],
|
||
'base'=>['*'],
|
||
'shop'=>['name','logo','image'],
|
||
'detail'=>['*'],
|
||
'orderitem'=>['*'],
|
||
];
|
||
$CANCEL = '-3';
|
||
$NOPAY = '0';
|
||
$PAYED = '2';
|
||
$RESERV = '3';
|
||
$REFUND = '6';
|
||
$FINISH = '9';
|
||
$IN_SERVICE = '4';
|
||
$IN_REFUND = '5';
|
||
|
||
$alisa = (new self)->getWithAlisaName();
|
||
$sort = "field({$alisa}.status,'{$NOPAY}','{$PAYED}','{$RESERV}','{$FINISH}','{$REFUND}','{$IN_SERVICE}','{$CANCEL}' ,'{$IN_REFUND}') asc,{$alisa}.id desc";
|
||
$serch_where = ['status'=>$status,'user_id'=>$user_id,'keywords'=>$keywords,"classes_activity_id"=>$classes_activity_id,"has_evaluate"=>$has_evaluate,"auth_status"=>$auth_status];
|
||
// if($type)$serch_where['type'] = $type;
|
||
return (new self)->getBaseList($serch_where, $page, $limit,$sort,$with_field);
|
||
}
|
||
|
||
|
||
|
||
|
||
public static function baseCount($where = []){
|
||
$CANCEL = '-3';
|
||
$NOPAY = '0';
|
||
$PAYED = '2';
|
||
$RESERV = '3';
|
||
$REFUND = '6';
|
||
$FINISH = '9';
|
||
$IN_SERVICE = '4';
|
||
$IN_REFUND = '5';
|
||
|
||
$cancel_number = self::getBaseWhere(array_merge(['status'=>$CANCEL],$where))->count();
|
||
$nopay_number = self::getBaseWhere(array_merge(['status'=>$NOPAY],$where))->count();
|
||
$payed_number = self::getBaseWhere(array_merge(['status'=>$PAYED],$where))->count();
|
||
$reserv_number = self::getBaseWhere(array_merge(['status'=>$RESERV],$where))->count();
|
||
|
||
|
||
$retund_number = self::getBaseWhere(array_merge(['status'=>$REFUND],$where))->count();
|
||
$in_retund_number = self::getBaseWhere(array_merge(['status'=>$IN_REFUND],$where))->count();
|
||
|
||
$finish_number = self::getBaseWhere(array_merge(['status'=>$FINISH],$where))->count();
|
||
$in_service_number = self::getBaseWhere(array_merge(['status'=>$IN_SERVICE],$where))->count();
|
||
|
||
return compact('cancel_number','nopay_number','payed_number','in_service_number','retund_number','in_retund_number','finish_number','reserv_number');
|
||
}
|
||
|
||
|
||
|
||
/**订单数量统计
|
||
* @param int $user_id
|
||
* @return array
|
||
*/
|
||
public static function orderCount($user_id = 0,$classes_activity_id=[]){
|
||
return self::baseCount(['user_id'=>$user_id,"classes_activity_id"=>$classes_activity_id]);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
public static function workList($user_id,$page, $limit,$keywords,$status,$classes_activity_id=[],$classes_activity_ids=[],$has_evaluate=0,$auth_status=""){
|
||
if(!$classes_activity_ids) $classes_activity_ids = [-5];
|
||
|
||
$with_field = [
|
||
'user'=>['nickname','mobile','avatar','realname'],
|
||
'base'=>['*'],
|
||
'shop'=>['name','logo','image'],
|
||
'detail'=>['*'],
|
||
'orderitem'=>['*'],
|
||
];
|
||
$CANCEL = '-3';
|
||
$NOPAY = '0';
|
||
$PAYED = '2';
|
||
$RESERV = '3';
|
||
$REFUND = '6';
|
||
$FINISH = '9';
|
||
$IN_SERVICE = '4';
|
||
$IN_REFUND = '5';
|
||
$alisa = (new self)->getWithAlisaName();
|
||
$sort = "field({$alisa}.status,'{$NOPAY}','{$PAYED}','{$RESERV}','{$FINISH}','{$REFUND}','{$IN_SERVICE}','{$CANCEL}','{$IN_REFUND}') asc,{$alisa}.id desc";
|
||
$serch_where = ['status'=>$status,'keywords'=>$keywords,"classes_activity_id"=>$classes_activity_id,"classes_activity_ids"=>$classes_activity_ids,"auth_status"=>$auth_status];
|
||
// if($type)$serch_where['type'] = $type;
|
||
return (new self)->getBaseList($serch_where, $page, $limit,$sort,$with_field);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/**订单数量统计
|
||
* @param int $user_id
|
||
* @return array
|
||
*/
|
||
public static function workCount($classes_activity_id=[],$classes_activity_ids=[]){
|
||
if(!$classes_activity_ids) $classes_activity_ids = [-5];
|
||
|
||
return self::baseCount(["classes_activity_id"=>$classes_activity_id,"classes_activity_ids"=>$classes_activity_ids]);
|
||
}
|
||
|
||
|
||
|
||
|
||
/**得到订单详情
|
||
* @param $order_no
|
||
*/
|
||
public static function getDetail($order_no,$classes_activity_id = []){
|
||
$model = self::where('order_no|id|pay_no|code',$order_no);
|
||
if($classes_activity_id)$model = $model->where("classes_activity_id","in",$classes_activity_id);
|
||
$data = $model->find();
|
||
|
||
if(!$data) return $data;
|
||
//加载订单详情
|
||
$data->detail;
|
||
//订单用户
|
||
// $data->user;
|
||
$data->user->visible(['id','nickname','mobile','avatar','realname']);
|
||
//订单机构
|
||
$data->shop;
|
||
//规格信息
|
||
$data->orderitem;
|
||
//售后单信息
|
||
// $data->serviceorder;
|
||
|
||
// //得到二维码
|
||
// $data->code_url = Common::getQrcode([
|
||
// 'text' => $data['code'],
|
||
// 'size' => 200,
|
||
// ]);
|
||
// $data->one_code_url = Common::getBarcode([
|
||
// 'text' => $data['code'],
|
||
// 'size' => 200,
|
||
// ]);
|
||
//评价
|
||
// $data->evaluate;
|
||
|
||
return $data;
|
||
}
|
||
|
||
|
||
/**展示订单信息
|
||
* @param $order_no
|
||
* @param $price_info
|
||
* @return array
|
||
*/
|
||
public static function showInfo($order_no, $price_info = []){
|
||
$data = [];
|
||
$data['order_no'] =$order_no;
|
||
$data['order_info'] = self::getDetail($order_no);
|
||
return array_merge($data,$price_info);
|
||
}
|
||
|
||
/**得到订单
|
||
* @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 getOrder($order_no){
|
||
$order = self::where('order_no|id|pay_no|code',$order_no)->find();
|
||
if(!$order)throw new \Exception("订单不存在");
|
||
return $order;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 设置订单缓存
|
||
* @param $uid
|
||
* @param $data
|
||
* @return bool
|
||
*/
|
||
public static function setOrderCache($uid, $data)
|
||
{
|
||
//缓存名 = uid + order_no
|
||
$cacheNmae = 'classes_activity_order_cache' . $uid . $data['order_no'];
|
||
// 缓存在3600秒之后过期
|
||
return Cache::set($cacheNmae, $data, config("site.unpaid_order_expire_time"));
|
||
}
|
||
|
||
/**
|
||
* 得到订单缓存
|
||
* @param $uid
|
||
* @param $order_no
|
||
* @return mixed
|
||
*/
|
||
public static function getOrderCache($uid, $order_no)
|
||
{
|
||
//缓存名 = uid + order_no
|
||
$cacheNmae = 'classes_activity_order_cache' . $uid . $order_no;
|
||
// 缓存在3600秒之后过期
|
||
return Cache::get($cacheNmae);
|
||
}
|
||
|
||
|
||
/**
|
||
* 删除订单缓存
|
||
* @param $uid
|
||
* @param $order_no
|
||
* @return mixed
|
||
*/
|
||
public static function deleteOrderCache($uid, $order_no)
|
||
{
|
||
//缓存名 = uid + order_no
|
||
$cacheNmae = 'classes_activity_order_cache' . $uid . $order_no;
|
||
// 缓存在3600秒之后过期
|
||
return Cache::rm($cacheNmae);
|
||
}
|
||
|
||
|
||
|
||
|
||
//计算订单所需返回数据接口
|
||
public static function getCost($user_id,$classes_activity_id,$classes_activity_item_id,$param=[],$other_params=[],$check = false){
|
||
//用户
|
||
$user_info = User::get($user_id);
|
||
$user_data = [
|
||
"nickname"=>$user_info["nickname"],
|
||
"realname"=>$user_info["realname"],
|
||
"avatar"=>$user_info["avatar"],
|
||
"mobile"=>$user_info["mobile"],
|
||
"money" =>$user_info["money"],
|
||
"score" =>$user_info["score"],
|
||
];
|
||
//课程
|
||
$activity_info = Activity::get($classes_activity_id);
|
||
$activity_info = $activity_info->toArray();
|
||
$activity_info["classes_activity_id"] = $classes_activity_id;
|
||
$activity_info["classes_activity_order_id"] = 0;
|
||
// $activity_info['use_num'] = 0;//已使用课时
|
||
// $activity_info['sub_num'] = $activity_info['classes_num'];//剩余课时
|
||
// //单价 = 课程价格/总课时
|
||
// $activity_info["unit_price"] = bcdiv($activity_info['price'],$activity_info['classes_num'],2);
|
||
// $activity_info["used_price"] = 0;
|
||
|
||
|
||
//组装订单下单数据
|
||
$order_data = [];
|
||
$order_data["user_id"] = $user_id;
|
||
$order_data["manystore_id"] = $activity_info["manystore_id"];
|
||
$order_data["shop_id"] = $activity_info["shop_id"];
|
||
$order_data["classes_activity_id"] = $classes_activity_id;
|
||
$order_data["activity_order_detail_id"] = 0;
|
||
$order_data["classes_activity_item_id"] = $classes_activity_item_id;
|
||
$order_data["beforeprice"] = $activity_info["price"];
|
||
$order_data["totalprice"] = $activity_info["price"];
|
||
$order_data["payprice"] = 0;
|
||
$order_data["status"] = '0';
|
||
$order_type = "multiple";
|
||
//如果课程只存在一个规格,则订单类型为单课
|
||
$classes_spec_count = ActivityItem::where('classes_activity_id',$classes_activity_id)->count();
|
||
if($classes_spec_count==1){
|
||
$order_type = "single";
|
||
}
|
||
$classes_activity_item = null;
|
||
|
||
if($classes_activity_item_id){
|
||
$classes_activity_item = ActivityItem::get($classes_activity_item_id);
|
||
|
||
$order_data["beforeprice"] = $classes_activity_item["price"];
|
||
$order_data["totalprice"] = $classes_activity_item["price"];
|
||
}
|
||
|
||
|
||
return compact('order_data','activity_info','user_data','order_type',"classes_activity_item");
|
||
}
|
||
|
||
|
||
|
||
|
||
/** 订单确认(订单计算)
|
||
* @param $user_id 下单用户
|
||
* @param $order_no 订单号(缓存标识)
|
||
* @param $classes_activity_id 課程活动id
|
||
* @param $classes_activity_item_id 課程活动规格id
|
||
* @param $param 額外参数(扩展用)
|
||
* @param bool $is_compute 是否重新计算订单
|
||
* @return array
|
||
*/
|
||
public function confirm($user_id, $classes_activity_id,$classes_activity_item_id,$order_no,$param=[], $is_compute = false)
|
||
{
|
||
if ($order_no && !$is_compute) {
|
||
//得到缓存
|
||
$data = self::getOrderCache($user_id, $order_no);
|
||
if (!$data) throw new \Exception('请您完善参加信息!');
|
||
$price_info = $data['price_info'];
|
||
} else {
|
||
//订单信息计算
|
||
// if(!$param) throw new \Exception('缺少必要信息');
|
||
$this->orderVaild($user_id,$classes_activity_id,$classes_activity_item_id,$order_no, $param);
|
||
//订单支付信息
|
||
$price_info = $this->getCost($user_id,$classes_activity_id,$classes_activity_item_id,$param);
|
||
//生成订单号
|
||
if (!$order_no) $order_no = get_order_sn();
|
||
//生成缓存
|
||
$data = compact('user_id', 'classes_activity_id','classes_activity_item_id','param', 'order_no', 'price_info');
|
||
self::setOrderCache($user_id, $data);
|
||
}
|
||
|
||
\think\Hook::listen('classes_activity_order_create_before', $data);
|
||
|
||
//下单数据展示
|
||
return $this->showInfo($order_no, $price_info);
|
||
}
|
||
|
||
|
||
|
||
|
||
/**订单校验
|
||
* @param $user_id 用户id
|
||
* @param $classes_lib_id 课程id
|
||
* @param $order_no 订单号
|
||
* @param $param 表单扩展参数
|
||
* @return bool
|
||
*/
|
||
public function orderVaild($user_id,$classes_activity_id,$classes_activity_item_id, $order_no, $param,$check=false){
|
||
if(!$user_id||!$classes_activity_id )throw new \Exception("缺少必要参数");
|
||
|
||
//校验订单参数
|
||
//课程活动是否存在并上架
|
||
$classes_lib_info = Activity::where('id',$classes_activity_id)->find();
|
||
if(!$classes_lib_info || $classes_lib_info['status']!='1') throw new \Exception("该活动不存在或已下架!");
|
||
|
||
//往期课程活动无法下单
|
||
$now_time = time();
|
||
if($classes_lib_info['end_time'] <= $now_time) throw new \Exception("该活动已过期,是往期活动,无法购买!");
|
||
|
||
//当前时间不在改报名时间段sign_start_time 和 sign_end_time 内则无法购买
|
||
if($classes_lib_info['sign_start_time'] > $now_time || $classes_lib_info['sign_end_time'] < $now_time) throw new \Exception("不在活动报名时间范围内,无法购买!");
|
||
|
||
|
||
|
||
|
||
//默认校验订单是否已创建
|
||
if($check){
|
||
//判断订单是否已创建
|
||
$order_info = self::where(['order_no'=>$order_no])->find();
|
||
if($order_info) throw new \Exception("订单已生成,如需重新下单请退出页面重新进入!");
|
||
//下单必须传规格id
|
||
if(!$classes_activity_item_id) throw new \Exception("请选择活动规格!");
|
||
|
||
//判断数量是否超出库存
|
||
$classes_lib_info = Activity::update_classes($classes_activity_id);
|
||
$sale = Order::where("classes_activity_id",$classes_activity_id)->where("status","<>","-3")->count();
|
||
if($sale >= $classes_lib_info['stock']) throw new \Exception("该活动已满人,无法参与!");
|
||
}
|
||
|
||
|
||
|
||
//执行免费课黑名单判断
|
||
//免费课才进行判断
|
||
// if($classes_lib_info && $classes_lib_info['feel']=='1'){
|
||
// \app\common\model\school\classes\hourorder\Order::checkBlackList($user_id,true);
|
||
// }
|
||
// //免费课才进行判断(同個免費單只能买一次)
|
||
// if($classes_lib_info && $classes_lib_info['feel']=='1'){
|
||
// \app\common\model\school\classes\hourorder\Order::checkOnlyone($user_id,$classes_lib_info,true);
|
||
// }
|
||
|
||
|
||
//用户存不存在
|
||
$user_info = User::where('id',$user_id)->find();
|
||
if(!$user_info) throw new \Exception("用户不存在!");
|
||
|
||
|
||
|
||
if($classes_activity_item_id){
|
||
//没有订单id无法判断
|
||
// //记录代下单人信息
|
||
// $param = [
|
||
// "type" =>'2',
|
||
// "help_user_id" =>$user_id,
|
||
// "help_type" =>'admin',
|
||
// "classes_lib_id" =>$classes_lib_id
|
||
// ];
|
||
//
|
||
//
|
||
// //确认订单
|
||
// $res = (new \app\common\model\school\classes\hourorder\Order)->confirm($user_id,0,null, $classes_lib_spec_id,$param, true);
|
||
//只简单判断课程和课时 记得判断库存
|
||
self::checkLibSpec($user_id,$classes_activity_id ,$classes_activity_item_id,true,$order=null,$check);
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
/** 课时信息选择合法检测
|
||
* @param $user_id 下单用户
|
||
* @param $classes_activity_id 活动id
|
||
* @param $classes_activity_item_id 活动规格id
|
||
* @return void
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
* @throws \think\exception\DbException
|
||
*/
|
||
public static function checkLibSpec($user_id,$classes_activity_id ,$classes_activity_item_id,$add=false,$order=null,$check=false){
|
||
if(!$classes_activity_id || !$classes_activity_item_id)throw new \Exception("缺少必要信息!");
|
||
|
||
$classes_lib_spec_info = ActivityItem::where('id',$classes_activity_item_id)
|
||
->where('classes_activity_id',$classes_activity_id)
|
||
->find();
|
||
if(!$classes_lib_spec_info)throw new \Exception("规格信息不正确!");
|
||
//课时已下架
|
||
if($classes_lib_spec_info['status']!='1') throw new \Exception("该规格已下架,请选择其他规格!");
|
||
|
||
//存在同规格正在进行中的课时预约
|
||
$order_info = self::where('classes_activity_item_id',$classes_activity_item_id)
|
||
->where('status',"not in",["-3","6"])
|
||
->where('user_id',$user_id)
|
||
->find();
|
||
if($order_info) throw new \Exception("该活动规格已预约或已上过,请勿重复预约!");
|
||
|
||
//新增或更换课时时判断
|
||
//是否达成限制人数
|
||
//允许人数为0说明不限制
|
||
if($classes_lib_spec_info['limit_num'] > 0 && $check){
|
||
//得到当前课时已参与人数
|
||
$sign_num = self::where('classes_activity_item_id',$classes_activity_item_id)->where("status","not in",["-3","6"])->count();
|
||
|
||
if($sign_num >= $classes_lib_spec_info['limit_num']){
|
||
throw new \Exception("该活动已满,请选择其他活动!");
|
||
}
|
||
|
||
|
||
if($add){
|
||
|
||
}else{
|
||
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//判断是否是免费课
|
||
$lib = $classes_lib_spec_info->activity;
|
||
if(!$lib){
|
||
throw new \Exception("该课程活动信息缺失!");
|
||
}
|
||
|
||
if($classes_lib_spec_info["feel"] == '1'){
|
||
//免费课开始和结束时间有交叠无法下预约
|
||
if(!config("site.free_time_activity_check")){
|
||
//如果是免费课
|
||
//判断时间是否有交叠
|
||
$start_time = $lib['start_time'];
|
||
$end_time = $lib['end_time'];
|
||
|
||
$as = (new self)->getWithAlisaName();
|
||
//判断时间是否有交叠(只查所有的免费的预约记录)
|
||
$order_info = self::with("detail")->where("detail.price",0)
|
||
->where("{$as}.status","not in",["-3","6","9"])
|
||
->where(function ($query) use ($as,$start_time,$end_time) {
|
||
//兩個時間區間重合 存在任意交集 都不行
|
||
$query->where("detail.start_time BETWEEN {$start_time} AND {$end_time}");
|
||
$query->whereOr("detail.end_time BETWEEN {$start_time} AND {$end_time}");
|
||
$query->whereOr("detail.start_time <= {$start_time} AND detail.end_time >= {$end_time}");
|
||
$query->whereOr("detail.start_time >= {$start_time} AND detail.end_time <= {$end_time}");
|
||
})
|
||
->where("{$as}.user_id",$user_id)->find();
|
||
if($order_info) throw new \Exception("当前时间区间内,您已预约免费活动{$order_info['detail']['title']},无法再预约其他免费活动");
|
||
|
||
|
||
}
|
||
|
||
}
|
||
|
||
if(!config("site.all_time_activity_check")){
|
||
//判断时间是否有交叠
|
||
$start_time = $lib['start_time'];
|
||
$end_time = $lib['end_time'];
|
||
|
||
$as = (new self)->getWithAlisaName();
|
||
//判断时间是否有交叠(只查所有的免费的预约记录)
|
||
$order_info = self::with("detail")
|
||
->where("{$as}.status","not in",["-3","6","9"])
|
||
->where(function ($query) use ($as,$start_time,$end_time) {
|
||
//兩個時間區間重合 存在任意交集 都不行
|
||
$query->where("detail.start_time BETWEEN {$start_time} AND {$end_time}");
|
||
$query->whereOr("detail.end_time BETWEEN {$start_time} AND {$end_time}");
|
||
$query->whereOr("detail.start_time <= {$start_time} AND detail.end_time >= {$end_time}");
|
||
$query->whereOr("detail.start_time >= {$start_time} AND detail.end_time <= {$end_time}");
|
||
})
|
||
->where("{$as}.user_id",$user_id)->find();
|
||
if($order_info) throw new \Exception("当前时间区间内,您已预约活动{$order_info['detail']['title']},无法再预约其他活动");
|
||
}
|
||
|
||
//执行免费课黑名单判断
|
||
// //免费课才进行判断
|
||
// if($lib && $lib['feel']=='1'){
|
||
// self::checkBlackList($user_id,true);
|
||
// }
|
||
|
||
//过期课时无法下单(结束时间小于等于当前时间)
|
||
if($lib["end_time"] <= time()){
|
||
throw new \Exception("该活动已过期结束,无法预约!");
|
||
}
|
||
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/**
|
||
* 根据缓存创建订单
|
||
*/
|
||
public function cacheCreateOrder($order_no, $user_id,$remark="", $trans = false)
|
||
{
|
||
//得到缓存
|
||
$orderInfo = self::getOrderCache($user_id, $order_no); //得到下单信息
|
||
if (!$orderInfo) throw new \Exception('請您完善預約信息!');
|
||
|
||
if ($trans) {
|
||
self::beginTrans();
|
||
}
|
||
try {
|
||
//'classes_activity_id','classes_activity_item_id'
|
||
//1订单执行创建
|
||
$order = $this->createOrder($user_id,$orderInfo['classes_activity_id'],$orderInfo['classes_activity_item_id'],$order_no,$orderInfo['param'],$remark);
|
||
|
||
$orderitem = $order->orderitem;
|
||
//如果是免费订单,则直接调用支付完成
|
||
if ($orderitem['feel'] == '1' || $order['totalprice'] == 0) {
|
||
//调用订单支付成功事件
|
||
$this->paySuccess($order_no,['platform'=>"miniapp",'pay_type'=>'yue']);
|
||
}
|
||
|
||
|
||
|
||
//5删除缓存
|
||
self::deleteOrderCache($user_id, $order_no);
|
||
|
||
|
||
|
||
if ($trans) {
|
||
self::commitTrans();
|
||
}
|
||
} catch (\Exception $e) {
|
||
if ($trans) {
|
||
self::rollbackTrans();
|
||
}
|
||
throw new \Exception($e->getMessage().$e->getFile() . $e->getLine());
|
||
}
|
||
return self::showInfo($order_no);
|
||
}
|
||
|
||
|
||
|
||
|
||
public function createOrder($user_id,$classes_activity_id,$classes_activity_item_id,$order_no,$param,$remark='',$other_params=[]){
|
||
|
||
$this->orderVaild($user_id,$classes_activity_id,$classes_activity_item_id, $order_no, $param,true);
|
||
//订单支付信息
|
||
$order_info = self::getCost($user_id,$classes_activity_id,$classes_activity_item_id,$param,$other_params,true);
|
||
|
||
//组装订单数据
|
||
$order_data = $order_info['order_data'];
|
||
$order_data["order_no"] = $order_no;
|
||
|
||
$res1 = self::create($order_data);
|
||
if (!$res1) throw new \Exception('创建订单失败');
|
||
$classes_activity_item = $order_info["classes_activity_item"];
|
||
if(!$classes_activity_item)throw new \Exception('订单未选规格!');
|
||
|
||
//課程详情
|
||
$activity_info = $order_info['activity_info'];
|
||
|
||
$order_detail_data = [];
|
||
$order_detail_data = array_merge($order_detail_data,$activity_info);
|
||
$order_detail_data["classes_activity_id"] = $activity_info['id'];
|
||
$order_detail_data["classes_activity_order_id"] = $res1['id'];
|
||
|
||
unset($order_detail_data['id']);
|
||
unset($order_detail_data['createtime']);
|
||
|
||
$orderDetail = (new OrderDetail());
|
||
$orderDetail->allowField(true)->save($order_detail_data);
|
||
|
||
|
||
$order_item_data = [];
|
||
$order_item_data = array_merge($order_item_data,$classes_activity_item->toArray());
|
||
$order_item_data["classes_activity_item_id"] = $classes_activity_item['id'];
|
||
$order_item_data["classes_activity_order_id"] = $res1['id'];
|
||
|
||
unset($order_item_data['id']);
|
||
unset($order_item_data['createtime']);
|
||
$orderItem = (new OrderItem());
|
||
$orderItem->allowField(true)->save($order_item_data);
|
||
|
||
//更新订单详情id
|
||
$res1->activity_order_detail_id = $orderDetail->id;
|
||
$res1->activity_order_item_id = $orderItem->id;
|
||
$res1->save();
|
||
|
||
|
||
|
||
//记录订单日志
|
||
OrderLog::log($res1['id'],"活动订单创建成功,等待【学员】支付",'user',$user_id);
|
||
//7事件
|
||
$data = ['order' => $res1];
|
||
\think\Hook::listen('classes_activity_order_create_after', $data);
|
||
|
||
|
||
//更新订单数据
|
||
self::statisticsAndUpdateClassesNumber($res1);
|
||
|
||
|
||
return $res1;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/**余额支付
|
||
* @throws \Exception
|
||
*/
|
||
public function moneyPay($order_no,$method,$trans=false){
|
||
$order = self::getNopayOrder($order_no);
|
||
//支付前判断
|
||
// self::checkPay($order_no,'wallet');
|
||
//判断逻辑
|
||
if($trans){
|
||
self::beginTrans();
|
||
}
|
||
$res = true;
|
||
try{
|
||
//事务逻辑
|
||
if($order['totalprice']){
|
||
$memo = "活动订单[ID:{$order['id']}]下单,支付余额{$order['totalprice']}";
|
||
try{
|
||
//扣除用户余额
|
||
User::money(-$order['totalprice'], $order['user_id'], $memo,'class_order_pay' ,[
|
||
'order_id' => $order->id,
|
||
'order_sn' => $order->order_sn,
|
||
]);
|
||
}catch (\Exception $e){
|
||
throw new \Exception("余额不足!");
|
||
}
|
||
}
|
||
//调用订单支付成功事件
|
||
$this->paySuccess($order_no,['platform'=>$method,'pay_type'=>'yue']);
|
||
if($trans){
|
||
self::commitTrans();
|
||
}
|
||
}catch (\Exception $e){
|
||
if($trans){
|
||
self::rollbackTrans();
|
||
}
|
||
throw new \Exception($e->getMessage());
|
||
}
|
||
return $res;
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/**调用订单支付成功事件
|
||
* @param $order_no
|
||
* @param $pay_type
|
||
* @param $price
|
||
* @param $price_check
|
||
* @param bool $trans
|
||
* @return bool
|
||
* @throws \Exception
|
||
*/
|
||
public function paySuccess($order_no,$notify=[],$price=0,$price_check=false,$trans=false){
|
||
$order = self::getNopayOrder($order_no);
|
||
//金额校验 :第三方支付时回调入口判断
|
||
if($price_check){
|
||
if(bccomp($price,$order['totalprice'])==-1)throw new \Exception("支付金额与订单需要支付金额对应不上,回调失败!");
|
||
}
|
||
//判断逻辑
|
||
if($trans){
|
||
self::beginTrans();
|
||
}
|
||
$res = true;
|
||
try{
|
||
//事务逻辑
|
||
//不拆分订单,直接执行
|
||
self::paySetData($order,$notify);
|
||
|
||
// //如果需要快捷预约
|
||
// $classes_lib_spec_id = $order['classes_lib_spec_id'];
|
||
// if($classes_lib_spec_id){
|
||
// //记录代下单人信息
|
||
// $param = [
|
||
// "type" =>'2',
|
||
// "help_user_id" =>$order["user_id"] ,
|
||
// "help_type" => 'admin',
|
||
// ];
|
||
//
|
||
// //确认订单
|
||
// $res = (new \app\common\model\school\classes\hourorder\Order)->confirm($order["user_id"],$order['id'],null, $classes_lib_spec_id,$param, true);
|
||
// $remark = "订单支付完成同时快捷预约一个课时";
|
||
// //创建订单
|
||
// $result = (new \app\common\model\school\classes\hourorder\Order)->cacheCreateOrder($res['order_no'], $order["user_id"],$remark);
|
||
//
|
||
// }
|
||
|
||
|
||
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 paySetData($order,$notify=[]){
|
||
//订单支付更新
|
||
$order = self::updatePay($order,$notify);
|
||
//生成订单一维码和二维码
|
||
$order = self::buildCode($order);
|
||
//记录订单日志
|
||
OrderLog::log($order['id'],"活动订单支付成功,核销码生成,等待审核结果",'user',$order['user_id']);
|
||
//调用支付成功事件
|
||
$data = ['order' => $order];
|
||
\think\Hook::listen('classes_activity_order_payed_after', $data);
|
||
//更新订单数据
|
||
self::statisticsAndUpdateClassesNumber($order);
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
public static function updatePay($order,$notify=[]){
|
||
if(is_string($order)||is_numeric($order))$order = self::getNopayOrder($order);
|
||
$order->status ='2';
|
||
$order->paytime = time();
|
||
$order->pay_no = $notify['transaction_id'] ?? null;
|
||
$order->pay_json = $notify['payment_json'] ?? '{}';
|
||
$order->pay_type = $notify['pay_type'] ?? 'yue';
|
||
//如果订单创建时间大于预约时间,则等于预约时间
|
||
// if($order['createtime']>$order['starttime'])$order['createtime'] = $order['starttime'];
|
||
switch ($order->pay_type) {
|
||
case "offline": //线下付款,线上不需要支付
|
||
|
||
break;
|
||
|
||
default:
|
||
$order->payprice = $notify['pay_fee'] ?? $order->totalprice;
|
||
}
|
||
$order->platform = $notify['platform'] ?? 'miniapp';
|
||
$order->sub_refundprice = $order->payprice; //剩余未退 = 支付金额
|
||
|
||
$order->save();
|
||
return $order;
|
||
}
|
||
|
||
/**得到待支付订单
|
||
* @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 getNopayOrder($order_no){
|
||
$order = self::where('order_no|id|pay_no|code',$order_no)->where("status",'0')->find();
|
||
if(!$order)throw new \Exception("待支付订单不存在");
|
||
return $order;
|
||
}
|
||
|
||
|
||
public static function buildCode($order){
|
||
if(is_string($order)||is_numeric($order))$order = self::getNopayOrder($order);
|
||
//生成核销二维码和一维码
|
||
//生成code
|
||
$vcode = en_code($order['id']). Random::alnum();
|
||
$order['code'] = $vcode;
|
||
$params = [
|
||
"type"=>"activity_verification",
|
||
"vcode" =>$vcode,
|
||
"order_id"=>$order['id'],
|
||
];
|
||
//$params生成get参数
|
||
$params = http_build_query($params);
|
||
//生成二维码和一维码
|
||
//二维码
|
||
$order->codeimage = (Common::getQrcode([
|
||
'text' => $params,
|
||
'size' => 200,
|
||
]))['url'];
|
||
//一维码
|
||
$order->codeoneimage = (Common::getBarcode([
|
||
'text' => $params,
|
||
'size' => 200,
|
||
]))['url'];
|
||
$order->save();
|
||
return $order;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 检测支付开关(待扩展)
|
||
*/
|
||
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['classes_activity_id'],$order['classes_activity_item_id'],$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("您无权操作该订单!");
|
||
|
||
$Shop = \app\common\model\manystore\Shop::where("user_id",$oper_id)->find();
|
||
if($Shop){
|
||
if($Shop["id"] == $classesOrder["shop_id"]){
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
//说明是操作员
|
||
$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["classes_activity_id"],$classes_activity_ids)) throw new \Exception("该活动不在您的授权范围内,无法代操作!");
|
||
}else{
|
||
$classes_activity_ids = (new Activity())->getActivityAuthIds($oper_id);
|
||
//不是员工并且想操作只有机构能操作的单
|
||
if(!in_array($classesOrder["classes_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 = Activity::where("manystore_id",$oper_id)->column("id");
|
||
//判断当前订单课程是否在此课程授权范围内
|
||
if(!in_array($classesOrder["classes_activity_id"],$classes_activity_ids)) throw new \Exception("该活动不在您的授权范围内,无法代操作!");
|
||
|
||
break;
|
||
default:
|
||
throw new \Exception("请选择正确的代下单类型!");
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
/**得到可取消订单
|
||
* @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 getHaveCancelOrder($order_no){
|
||
// $where = [self::STATUS_NOPAY,self::STATUS_PAYED];
|
||
$order = self::where('order_no|id|pay_no|code',$order_no)->find();
|
||
$detail = $order->detail;
|
||
$orderitem = $order->orderitem;
|
||
if(!$detail) throw new \Exception("订单信息缺失!");
|
||
if(!$orderitem) throw new \Exception("订单信息缺失!");
|
||
if(!$order)throw new \Exception("只有待支付订单可取消,已支付请走售后申请,已取消请忽略!");
|
||
//非免费单进行中无法取消
|
||
if($orderitem["feel"] == "0" && $order['status'] != '0'){
|
||
throw new \Exception("只有待支付订单可取消,已支付请走售后申请,已取消请忽略!");
|
||
}
|
||
if(($orderitem["feel"] == "1" || $order['totalprice'] == 0)&& !in_array($order['status'],['0','2','3'])){
|
||
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 updateCancel($order){
|
||
if(is_string($order))$order = self::getHaveCancelOrder($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 cancel($order_no,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){
|
||
//得到可取消订单
|
||
$order = self::getHaveCancelOrder($order_no);
|
||
if($check){
|
||
//用户操作权限检测
|
||
self::checkOptionAuth($order['id'],$user_id ?: $oper_id,$oper_type);
|
||
|
||
//进行中,用户自己无法操作取消
|
||
if(($order['status'] == '2' || $order['status'] == '3' )&& $user_id == $order['user_id']){
|
||
throw new \Exception("您无权操作取消!请您联系机构操作!");
|
||
}
|
||
}
|
||
|
||
|
||
//判断逻辑
|
||
if($trans){
|
||
self::beginTrans();
|
||
}
|
||
$res = true;
|
||
try{
|
||
//事务逻辑
|
||
|
||
//更新订单取消状态
|
||
$order = self::updateCancel($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' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id];
|
||
\think\Hook::listen('classes_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;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/**得到可审核订单
|
||
* @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 getHaveExamineOrder($order_no){
|
||
// $where = [self::STATUS_NOPAY,self::STATUS_PAYED];
|
||
$order = self::where('order_no|id|pay_no|code',$order_no)->where("status","in",['2'])->find();
|
||
if(!$order)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 updateExamineSuccess($order,$oper_id = 0,$oper_type='user'){
|
||
if(is_string($order))$order = self::getHaveExamineOrder($order);
|
||
$order->status = "3";//refund_status
|
||
$order->auth_status = "1";//refund_status
|
||
$order->auth_time = time();
|
||
$order->auth_user_id = $oper_id;
|
||
$order->auth_type = $oper_type;
|
||
$order->save();
|
||
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 updateExamineFail($order,$reason,$oper_id = 0,$oper_type='user'){
|
||
if(is_string($order))$order = self::getHaveExamineOrder($order);
|
||
$order->auth_status = "2";
|
||
$order->auth_time = time();
|
||
$order->reason = $reason;
|
||
$order->auth_user_id = $oper_id;
|
||
$order->auth_type = $oper_type;
|
||
$order->save();
|
||
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 updateExamineFailSettlement($order,$reason,$oper_id = 0,$oper_type='user'){
|
||
if(is_string($order))$order = self::getHaveExamineOrder($order);
|
||
$order->status = "5";
|
||
$order->auth_status = "2";
|
||
$order->auth_time = time();
|
||
$order->refundsendtime = time();
|
||
$order->reason = $reason;
|
||
$order->auth_user_id = $oper_id;
|
||
$order->auth_type = $oper_type;
|
||
$order->save();
|
||
return $order;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/**活动订单审核
|
||
* @param $order_no
|
||
* @param int $user_id
|
||
* @param bool $check
|
||
* @param bool $trans
|
||
* @return bool
|
||
* @throws \Exception
|
||
*/
|
||
public function examine($order_no,$auth_status,$reason="",$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){
|
||
|
||
|
||
//得到可取消订单
|
||
$order = self::getHaveExamineOrder($order_no);
|
||
|
||
if($check){
|
||
//用户操作权限检测
|
||
self::checkOptionAuth($order['id'],$user_id ?: $oper_id,$oper_type);
|
||
|
||
|
||
}
|
||
//审核状态字段检测
|
||
$auth_status_arr = [1,2];//0=待审核,1=审核通过,2=审核失败
|
||
if( !in_array($auth_status,$auth_status_arr)) throw new \Exception("审核状态不正确!");
|
||
//审核失败需要传理由
|
||
if($auth_status==2 && empty($reason)) throw new \Exception("审核失败需要填写理由!");
|
||
|
||
|
||
//判断逻辑
|
||
if($trans){
|
||
self::beginTrans();
|
||
}
|
||
$res = true;
|
||
try{
|
||
//事务逻辑
|
||
|
||
//插入订单取消日志
|
||
if(!$user_id ||$order["user_id"] !=$user_id ){
|
||
$pron = "[员工操作]";
|
||
}else{
|
||
$pron = "";
|
||
}
|
||
//审核成功逻辑
|
||
if($auth_status == 1){
|
||
//更新订单状态
|
||
$order = self::updateExamineSuccess($order,$user_id ?: $oper_id,$oper_type);
|
||
|
||
OrderLog::log($order['id'],$pron."课程活动单审核成功,预约成功等待核销!",$oper_type ?: 'user', $oper_id ?: $order['user_id']);
|
||
//调用订单事件
|
||
$data = ['order' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id];
|
||
\think\Hook::listen('classes_activity_order_auth_success_after', $data);
|
||
|
||
}else{
|
||
$detail = $order->detail;
|
||
$orderitem = $order->orderitem;
|
||
|
||
//如果是免费的订单,直接取消订单
|
||
if($orderitem['feel'] == '1' || $order['payprice'] <= 0){
|
||
//更新订单状态
|
||
$order = self::updateExamineFail($order,$reason,$user_id ?: $oper_id,$oper_type);
|
||
|
||
//审核失败逻辑
|
||
OrderLog::log($order['id'],$pron."课程活动单审核不通过,原因;{$reason},该活动单将取消",$oper_type ?: 'user', $oper_id ?: $order['user_id']);
|
||
//调用订单事件
|
||
$data = ['order' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id];
|
||
\think\Hook::listen('classes_activity_order_auth_fail_after', $data);
|
||
//执行订单取消逻辑
|
||
$this->cancel($order_no,$user_id,false,$oper_type,$oper_id);
|
||
}else{
|
||
//调用退款发起
|
||
//更新订单状态
|
||
$order = self::updateExamineFailSettlement($order,$reason,$user_id ?: $oper_id,$oper_type);
|
||
|
||
//审核失败逻辑
|
||
OrderLog::log($order['id'],$pron."课程活动单审核不通过,原因;{$reason},该活动单将自动退款以便重新下单",$oper_type ?: 'user', $oper_id ?: $order['user_id']);
|
||
//调用订单事件
|
||
$data = ['order' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id];
|
||
\think\Hook::listen('classes_activity_order_auth_fail_after', $data);
|
||
|
||
|
||
self::orderRefund($order,$order['sub_refundprice'],$oper_type,$oper_id,$trans=false,$admin=false);
|
||
}
|
||
|
||
}
|
||
|
||
//执行课时数更新
|
||
// $res1 = \app\common\model\school\classes\order\Order::statisticsAndUpdateClassesNumber($order['classes_order_id']);
|
||
|
||
if($trans){
|
||
self::commitTrans();
|
||
}
|
||
}catch (\Exception $e){
|
||
if($trans){
|
||
self::rollbackTrans();
|
||
}
|
||
throw new \Exception($e->getMessage());
|
||
}
|
||
return $order;
|
||
}
|
||
|
||
|
||
|
||
/**预约订单退款(退全款)
|
||
* @param $order
|
||
* @param $refund_money
|
||
* @param $trans
|
||
*/
|
||
public static function orderRefund($order,$refund_money,$oper_type='user',$oper_id=0,$trans=false,$admin=false){
|
||
if(is_numeric($order))$order = self::getHaveRefundOrder($order);
|
||
if(!$order)throw new \Exception("找不到订单");
|
||
//判断逻辑
|
||
if($trans){
|
||
self::beginTrans();
|
||
}
|
||
$res = true;
|
||
try{
|
||
//生成退款单号
|
||
if(!$order['refund_no']){
|
||
$order['refund_no'] = get_order_sn();
|
||
$order->save();
|
||
}
|
||
if(!$refund_money)$refund_money = $order['sub_refundprice'];
|
||
if($refund_money<=0)$refund_money = 0;
|
||
if(!$refund_money)throw new \Exception("退款金额异常!");
|
||
//事务逻辑
|
||
switch ($order['pay_type']) {
|
||
case "wechat": //微信退款
|
||
self::wechatRefund($order,$refund_money,$oper_type,$oper_id);
|
||
break;
|
||
// case "alipay": //支付宝退款
|
||
// self::alipayRefund($order,$refund_money,$oper_type,$oper_id);
|
||
// break;
|
||
// case "wallet": //钱包支付退款
|
||
// self::walletRefund($order,$refund_money,$oper_type,$oper_id);
|
||
// break;
|
||
// case "offline": //线下支付退款
|
||
//
|
||
// break;
|
||
default:
|
||
throw new \Exception("订单币种异常!");
|
||
}
|
||
|
||
if($trans){
|
||
self::commitTrans();
|
||
}
|
||
}catch (\Exception $e){
|
||
if($trans){
|
||
self::rollbackTrans();
|
||
}
|
||
throw new \Exception($e->getMessage());
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/**微信退款
|
||
* @param $order
|
||
* @param $refund_money
|
||
*/
|
||
public static function wechatRefund($order,$refund_money,$refund_desc="",$oper_type='user',$oper_id=0,$trans=false){
|
||
//判断逻辑
|
||
if($trans){
|
||
self::beginTrans();
|
||
}
|
||
$res = true;
|
||
try{
|
||
//事务逻辑
|
||
//创建订单退款订单
|
||
|
||
|
||
$classesorder = $order;
|
||
$detail = $order->detail;
|
||
|
||
//执行微信退款sdk
|
||
$order_data = [
|
||
'out_trade_no' => $classesorder->order_no
|
||
];
|
||
$total_fee = $classesorder->payprice * 100;
|
||
$refund_fee = $refund_money * 100;
|
||
|
||
$order_data = array_merge($order_data, [
|
||
'out_refund_no' => $order->refund_no,
|
||
'total_fee' => $total_fee,
|
||
'refund_fee' => $refund_fee,
|
||
'refund_desc' => $refund_desc ?: "活动[{$detail["title"]}]订单[ID:{$classesorder['id']}]退款{$refund_money}已到账户",
|
||
]);
|
||
|
||
$config = Service::getConfig('wechat',[],$classesorder->platform);
|
||
|
||
|
||
|
||
$notify_url = request()->domain() . '/api/school.activity.pay/notifyr/payment/' . $classesorder->pay_type . '/platform/' . $classesorder->platform;
|
||
|
||
$config['notify_url'] = $notify_url;
|
||
$pay = Pay::wechat($config);
|
||
|
||
|
||
$result = $pay->refund($order_data);
|
||
|
||
\think\Log::write('refund-result' . json_encode($result));
|
||
|
||
|
||
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
|
||
$res = true;
|
||
} else {
|
||
throw new \Exception($result['return_msg']);
|
||
}
|
||
|
||
if($trans){
|
||
self::commitTrans();
|
||
}
|
||
}catch (\Exception $e){
|
||
if($trans){
|
||
self::rollbackTrans();
|
||
}
|
||
throw new \Exception($e->getMessage().$e->getFile().$e->getLine());
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
|
||
/**得到可直接退款订单(正常取消退全款非售后)
|
||
* @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 getHaveRefundOrder($refund_sn){
|
||
// $where = [self::STATUS_NOPAY,self::STATUS_PAYED];
|
||
$order = self::where('refund_no|order_no|id',$refund_sn)->where('status','5')->where("sub_refundprice",">",0)->find();
|
||
if(!$order)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 updateRefundOrder($order,$pay_json=[]){
|
||
if(is_string($order))$order = self::getHaveRefundOrder($order);
|
||
$order->before_status = $order->status;//refund_status
|
||
$order->status = "6";
|
||
$order->service_stauts = "6";
|
||
$order->real_refundprice = bcadd($order->real_refundprice ?:'0',$order->sub_refundprice ,2);
|
||
$order->sub_refundprice = 0;
|
||
$order->refundtime = time();
|
||
$order->refund_json = json_encode($pay_json);
|
||
$order->save();
|
||
return $order;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/**退款成功处理逻辑(需修改)
|
||
* @param $refund_sn
|
||
* @param bool $trans
|
||
* @return bool
|
||
* @throws \Exception
|
||
*/
|
||
public static function refundSuccess($refund_sn,$refund_json=[],$trans=false){
|
||
//得到机构售后提交确认订单
|
||
$order = self::getHaveRefundOrder($refund_sn);
|
||
|
||
//判断逻辑
|
||
if($trans){
|
||
self::beginTrans();
|
||
}
|
||
$res = true;
|
||
try{
|
||
//事务逻辑
|
||
|
||
//更新订单状态为同意
|
||
$order = self::updateRefundOrder($refund_sn,$refund_json);
|
||
|
||
//插入订单日志
|
||
OrderLog::log($order['id'],"活动订单退全款已原路退回", 'admin', 0);
|
||
|
||
//执行课时数更新
|
||
$res1 = self::statisticsAndUpdateClassesNumber($order['id']);
|
||
|
||
//调用订单取消事件
|
||
$data = ['order' => $order,"user_id"=>$order['user_id'],"oper_type"=>'admin',"oper_id"=>0];
|
||
\think\Hook::listen('classes_activity_order_refund_success_after', $data);
|
||
|
||
|
||
|
||
if($trans){
|
||
self::commitTrans();
|
||
}
|
||
}catch (\Exception $e){
|
||
if($trans){
|
||
self::rollbackTrans();
|
||
}
|
||
throw new \Exception($e->getMessage());
|
||
}
|
||
return $res;
|
||
|
||
}
|
||
|
||
|
||
|
||
/**订单退款失败记录
|
||
* @param $order
|
||
* @param $refund_money
|
||
* @param $trans
|
||
*/
|
||
public static function orderRefundFail($order,$msg,$oper_type='user',$oper_id=0,$trans=false,$admin=false){
|
||
if(is_numeric($order))$order = self::getOrder($order);
|
||
if(!$order)throw new \Exception("找不到订单");
|
||
//判断逻辑
|
||
if($trans){
|
||
self::beginTrans();
|
||
}
|
||
$res = true;
|
||
try{
|
||
|
||
//事务逻辑
|
||
$order->refund_error = $msg;
|
||
$order->save();
|
||
//插入订单日志
|
||
OrderLog::log($order['id'],"活动订单退款失败:".$msg, $oper_type, $oper_id);
|
||
|
||
//调用订单取消事件
|
||
$data = ['order' => $order,"user_id"=>$order['user_id'],"oper_type"=>$oper_type,"oper_id"=>$oper_id];
|
||
\think\Hook::listen('classes_activity_order_refund_fail_after', $data);
|
||
|
||
if($trans){
|
||
self::commitTrans();
|
||
}
|
||
}catch (\Exception $e){
|
||
if($trans){
|
||
self::rollbackTrans();
|
||
}
|
||
throw new \Exception($e->getMessage());
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/**更新订单核销状态
|
||
* @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($order,$oper_id = 0,$oper_type='user'){
|
||
if(is_string($order))$order = self::getHaveVerificationOrder($order);
|
||
$order->status = "9";//refund_status
|
||
$order->verification_user_id = $oper_id;
|
||
$order->verification_type = $oper_type;
|
||
$order->finishtime = time();
|
||
$order->save();
|
||
return $order;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/**得到可核销订单
|
||
* @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 getHaveVerificationOrder($order_no){
|
||
// $where = [self::STATUS_NOPAY,self::STATUS_PAYED];
|
||
$order = self::where('order_no|id|code',$order_no)->where("status","in",["3"])->find();
|
||
if(!$order)throw new \Exception("不是待核销的订单!");
|
||
|
||
return $order;
|
||
}
|
||
|
||
|
||
|
||
|
||
/**订单核销
|
||
* @param $order_no
|
||
* @param int $user_id
|
||
* @param bool $check
|
||
* @param bool $trans
|
||
* @return bool
|
||
* @throws \Exception
|
||
*/
|
||
public function verification($order_no,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){
|
||
//得到可取消订单
|
||
$order = self::getHaveVerificationOrder($order_no);
|
||
if($check){
|
||
//用户操作权限检测
|
||
self::checkOptionAuth($order['id'],$user_id ?: $oper_id,$oper_type);
|
||
|
||
// self::serverCheck($order['classes_order_id']);
|
||
|
||
}
|
||
|
||
//判断逻辑
|
||
if($trans){
|
||
self::beginTrans();
|
||
}
|
||
$res = true;
|
||
try{
|
||
//事务逻辑
|
||
//更新订单状态
|
||
//如果没有审核,先审核成功再核销
|
||
// if($order["status"] == '2'){
|
||
// $order = $this->examine($order_no,'1',"",$user_id,$check,$oper_type,$oper_id);
|
||
// }
|
||
$order = self::updateVerification($order,$user_id ?: $oper_id,$oper_type);
|
||
//插入订单取消日志
|
||
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' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id];
|
||
\think\Hook::listen('classes_activity_order_finish_after', $data);
|
||
//执行课时数更新
|
||
self::statisticsAndUpdateClassesNumber($order['id']);
|
||
|
||
|
||
if($trans){
|
||
self::commitTrans();
|
||
}
|
||
}catch (\Exception $e){
|
||
if($trans){
|
||
self::rollbackTrans();
|
||
}
|
||
throw new \Exception($e->getMessage());
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
|
||
|
||
}
|