售后单超时自动挂起 售后同意结算单收益释放(余留未退金额情况下 后台帮商户售后功能 后台帮用户取消和申请售后功能 后台用户维度查看提现,结算,订单记录 结算单,活动单,活动,提现记录增加 万以上数据导出excel
518 lines
16 KiB
PHP
518 lines
16 KiB
PHP
<?php
|
||
|
||
namespace app\common\model\school\activity\order;
|
||
|
||
use app\common\model\BaseModel;
|
||
use app\common\model\school\activity\Activity;
|
||
use app\common\model\user\withdrawal\UserwithdrawalLog;
|
||
use think\Model;
|
||
use traits\model\SoftDelete;
|
||
|
||
class SettleLog extends BaseModel
|
||
{
|
||
|
||
use SoftDelete;
|
||
|
||
|
||
|
||
// 表名
|
||
protected $name = 'school_activity_settle_log';
|
||
|
||
// 自动写入时间戳字段
|
||
protected $autoWriteTimestamp = 'integer';
|
||
|
||
// 定义时间戳字段名
|
||
protected $createTime = 'createtime';
|
||
protected $updateTime = false;
|
||
protected $deleteTime = 'deletetime';
|
||
|
||
// 追加属性
|
||
protected $append = [
|
||
'status_text',
|
||
'settletime_text',
|
||
'canceltime_text',
|
||
'unfreezetime_text'
|
||
];
|
||
|
||
|
||
|
||
public function getStatusList()
|
||
{
|
||
return ['1' => __('Status 1'), '2' => __('Status 2'), '3' => __('Status 3'), '-1' => __('Status -1')];
|
||
}
|
||
|
||
|
||
public function getStatusTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
|
||
$list = $this->getStatusList();
|
||
return isset($list[$value]) ? $list[$value] : '';
|
||
}
|
||
|
||
|
||
public function getSettletimeTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['settletime']) ? $data['settletime'] : '');
|
||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $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 getUnfreezetimeTextAttr($value, $data)
|
||
{
|
||
$value = $value ? $value : (isset($data['unfreezetime']) ? $data['unfreezetime'] : '');
|
||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||
}
|
||
|
||
protected function setSettletimeAttr($value)
|
||
{
|
||
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
|
||
}
|
||
|
||
protected function setCanceltimeAttr($value)
|
||
{
|
||
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
|
||
}
|
||
|
||
protected function setUnfreezetimeAttr($value)
|
||
{
|
||
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
|
||
}
|
||
|
||
|
||
public function order()
|
||
{
|
||
return $this->belongsTo(Order::class, 'activity_order_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
|
||
public function log()
|
||
{
|
||
return $this->belongsTo(UserwithdrawalLog::class, 'withdrawal_log_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
|
||
public function touser()
|
||
{
|
||
return $this->belongsTo('app\common\model\User', 'to_user_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
|
||
public function payuser()
|
||
{
|
||
return $this->belongsTo('app\common\model\User', 'pay_user_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
|
||
|
||
public function activity()
|
||
{
|
||
return $this->belongsTo(Activity::class, 'activity_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
public function detail()
|
||
{
|
||
return $this->belongsTo(OrderDetail::class, 'activity_order_detail_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||
}
|
||
|
||
|
||
|
||
|
||
/**
|
||
* 检测订单结算
|
||
*/
|
||
public static function timeoutSettleActivityCheck($activity_id,$trans = false){
|
||
$count = 0;
|
||
if ($trans) {
|
||
self::beginTrans();
|
||
}
|
||
try {
|
||
|
||
$orders = Order::where("payprice",">",0) //支付单
|
||
->where("pay_type",'wechat') //微信支付
|
||
->where("sub_refundprice",">",0) //剩余未退大于0
|
||
->where("activity_id",$activity_id) //当前活动
|
||
->where("status","in",["-3","9","6"])
|
||
->select();
|
||
foreach ($orders as $order){
|
||
//剩余金额大于手续费的订单,并且未插入此结算单的
|
||
$sub_refundprice = bcsub($order["sub_refundprice"],$order["fee_price"],2);
|
||
if($sub_refundprice >= 0.01){
|
||
$log = self::where("activity_order_id",$order["id"])->where("status","not in",["-1"])->find();
|
||
if(!$log){
|
||
(new self)->generatorLog($order["id"]);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
if ($trans) {
|
||
self::commitTrans();
|
||
}
|
||
} catch (\Exception $e) {
|
||
if ($trans) {
|
||
self::rollbackTrans();
|
||
}
|
||
throw new \Exception($e->getMessage());
|
||
}
|
||
return $count;
|
||
}
|
||
|
||
|
||
|
||
|
||
/**
|
||
* 检测订单结算
|
||
*/
|
||
public function timeoutSettleCheck($trans = false){
|
||
$count = 0;
|
||
|
||
if ($trans) {
|
||
self::beginTrans();
|
||
}
|
||
try {
|
||
//查询更新所有活动状态
|
||
Activity::timeoutCheck();
|
||
|
||
//执行售后单挂起操作
|
||
(new order)->timeoutSuspension();
|
||
|
||
//延后时间(秒)
|
||
$delay = config("site.activity_end_settle") ?: 0;
|
||
$time = time();
|
||
//查询处于可结算状态的订单(活动结束时间戳 , 延后时间 =超时可以结算的活动)
|
||
$time = $time - $delay;
|
||
$activityList = Activity::where("status",'5')->where("end_time",'<',$time)->select();
|
||
foreach ($activityList as $activity){
|
||
//对活动订单进行结算记录插入
|
||
$this->timeoutSettleActivityCheck($activity["id"]);
|
||
}
|
||
|
||
|
||
//检测更新所有结算订状态
|
||
SettleLog::timeoutCheck(null,null);
|
||
if ($trans) {
|
||
self::commitTrans();
|
||
}
|
||
} catch (\Exception $e) {
|
||
if ($trans) {
|
||
self::rollbackTrans();
|
||
}
|
||
throw new \Exception($e->getMessage());
|
||
}
|
||
return $count;
|
||
}
|
||
|
||
|
||
|
||
|
||
/** 生成结算记录
|
||
* @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),
|
||
"activity_id" => $order->activity_id,
|
||
"activity_order_detail_id" => $detail->id,
|
||
];
|
||
if($data["settle_price"] < 0.01) return false;
|
||
//判断逻辑
|
||
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;
|
||
}
|
||
|
||
|
||
|
||
|
||
/** 获取用户结算信息
|
||
* @param $user_id
|
||
*/
|
||
public static function getUserSettleInfo($user_id = 0)
|
||
{
|
||
//统计未入账未提现金额
|
||
$expected_incoming_amount = 0.00;
|
||
|
||
$orders = Order::where("payprice",">",0) //支付单
|
||
->where("pay_type",'wechat') //微信支付
|
||
->where("sub_refundprice",">",0) //剩余未退大于0
|
||
->where("user_id",$user_id) //当前活动
|
||
->where("status","in",["-3","2","3","9","6"])
|
||
->field("sub_refundprice,fee_price")
|
||
->select();
|
||
foreach ($orders as $order){
|
||
//剩余金额大于手续费的订单,并且未插入此结算单的
|
||
$sub_refundprice = bcsub($order["sub_refundprice"],$order["fee_price"],2);
|
||
if($sub_refundprice > 0){
|
||
$expected_incoming_amount += $sub_refundprice;
|
||
}
|
||
|
||
}
|
||
//统计已入账待提现金额
|
||
$settled_amount = self::where("to_user_id",$user_id)->where("status",'2')->sum("settle_price");
|
||
//统计累计真实收益金额
|
||
$accumulated_incoming_amount = self::where("to_user_id",$user_id)->where("status","in",['2',"3"])->sum("settle_price");
|
||
|
||
return [
|
||
"expected_incoming_amount" => $expected_incoming_amount,
|
||
"settled_amount" => $settled_amount,
|
||
"accumulated_incoming_amount" => $accumulated_incoming_amount,
|
||
];
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/**得到基础条件
|
||
* @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','activity_id','user_id','activity_order_detail_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['keywords'])&&$whereData['keywords']){
|
||
$model = $model->where("{$alisa}order_no|{$alisa}pay_no|user.nickname|user.realname|user.mobile|detail.title|detail.address|detail.address_detail", 'LIKE', "%{$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}to_user_id", '=', $whereData['user_id']);
|
||
|
||
if (isset($whereData['activity_ids']) && $whereData['activity_ids']) $model = $model->where("{$alisa}activity_id", 'in', $whereData['activity_ids']);
|
||
if (isset($whereData['activity_id']) && $whereData['activity_id']) $model = $model->where("{$alisa}activity_id", 'in', $whereData['activity_id']);
|
||
|
||
|
||
if (isset($whereData['activity_order_detail_id']) && $whereData['activity_order_detail_id']) $model = $model->where("{$alisa}activity_order_detail_id", 'in', $whereData['activity_order_detail_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,$activity_id=[],$params=[]){
|
||
$with_field = [
|
||
'touser'=>['nickname','mobile','avatar','realname'],
|
||
'payuser'=>['nickname','mobile','avatar','realname'],
|
||
'base'=>['*'],
|
||
'detail'=>['*'],
|
||
];
|
||
$alisa = (new self)->getWithAlisaName();
|
||
$sort = "{$alisa}.id desc";
|
||
$serch_where = ['status'=>$status,'user_id'=>$user_id,'keywords'=>$keywords,"activity_id"=>$activity_id];
|
||
// if($type)$serch_where['type'] = $type;
|
||
return (new self)->getBaseList(array_merge($serch_where,$params), $page, $limit,$sort,$with_field);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
}
|