15090180611 a9a4ebe154 退款流程: 后台最终处理挂起订单流程,
售后单超时自动挂起
售后同意结算单收益释放(余留未退金额情况下
后台帮商户售后功能
后台帮用户取消和申请售后功能
后台用户维度查看提现,结算,订单记录
结算单,活动单,活动,提现记录增加 万以上数据导出excel
2025-04-16 18:02:31 +08:00

518 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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);
}
}