REAPI/app/merchant/service/OrderService.php
mzeros b8c34de8c8 refactor(merchant): 优化账户数据处理和订单逻辑
- 添加 endsWithDoubleZero 函数,用于处理数值字符串末尾的两个零
- 修改 Core.php 中的 queue 方法,增加对卡库提单的特殊处理逻辑
-调整 Feedov.php 中的订单查询和充值逻辑,提高系统稳定性
- 优化数据库配置,连接测试数据库以确保数据安全
2025-02-15 19:00:17 +08:00

828 lines
27 KiB
PHP

<?php
namespace app\merchant\service;
use app\channel\service\ChannelService;
use app\core\Service;
use app\merchant\service\MerchantService;
use think\admin\extend\CodeExtend;
use app\merchant\service\MerchantLogService;
use app\merchant\service\DayService;
use app\channel\service\ProductService;
use app\order\service\OrderService as OrderServiceBase;
/**
* 商户订单服务
* Class MerchantService
* @package app\merchant\service
*/
class OrderService extends Service
{
/**
* 设置默认操作表
* @var string
*/
public $table = 'merchant_order';
# 获取今天的余额
public function getYue($mid, $num, $type = 1, $date = false)
{
# 获取所有成功的订单
$where['mid'] = $mid;
$num += $this->db()->where($where)->whereRaw('status != 3')->sum('actual_cash');
$day = DayService::instance()->get($mid, $date);
$account = 0;
if ($type == 1) {
$key = 'account_surplus';
} else {
$key = 'credit_surplus';
}
if ($day && isset($day[$key])) {
$account = $day[$key];
}
$account -= $num;
$account = round($account, 2);
return $account;
}
# 提交订单
public function up($mid, $cid, $pid, $product_key, $order_id, $channel_order_id, $merchant_order_id, $cash, $url, $request, $response, $status = 1, $account = '', $parent_order_id = '', $project_id = false, $card_id = false, $param = false, $kou = false)
{
$info = $this->get($order_id);
$data = array();
$data['mid'] = $mid;
$data['cid'] = $cid;
$data['pid'] = $pid;
$data['product_key'] = $product_key;
$data['order_id'] = $order_id;
if ($parent_order_id) {
$data['parent_order_id'] = $parent_order_id;
}
if ($project_id) {
$data['project_id'] = $project_id;
}
if ($card_id) {
$data['card_id'] = $card_id;
}
if ($param && is_array($param)) {
if (isset($param['num']) && $param['num']) {
$cash = $cash * $param['num'];
}
$data['param'] = json_encode($param, JSON_UNESCAPED_UNICODE);
}
$data['channel_order_id'] = $channel_order_id;
$data['merchant_order_id'] = $merchant_order_id;
$data['cash'] = $cash;
$data['url'] = $url;
if ($request && is_array($request)) {
$request = json_encode($request, JSON_UNESCAPED_UNICODE);
}
if ($response && is_array($response)) {
$response = json_encode($response, JSON_UNESCAPED_UNICODE);
}
if ($request) {
$data['request'] = $request;
}
if ($response) {
$data['response'] = $response;
}
$data['status'] = $status;
$data['merchant_callback_num'] = 0;
$data['isp'] = -1;
if ($account) {
$data['account'] = $account;
if ($data['product_key'] == 'dhcz') {
if (isset($param['isp']) && $param['isp']) {
$data['isp'] = $param['isp'];
} else {
$data['isp'] = $this->isp($account);
}
}
}
if (!$info) {
$data['error_account_oper'] = 1;
$data['id'] = $this->db()->insertGetId($data);
$state = MerchantService::instance()->setFrozenAccount($data['id'], $data['order_id'], $data['mid'], $data['pid'], $data['product_key'], $data['cash'], $project_id, $account, $data['isp']);
$update = array();
if (!$state) {
$update['status'] = 3;
$update['merchant_callback_error'] = 2;
$data['error_account_oper'] = $update['error_account_oper'] = 2;
} else {
$update['actual_cash'] = $state[0];
$update['product_cash'] = $state[1];
if (isset($state[2])) {
$update['account_type'] = $state[2];
}
}
if ($update) {
$this->db()->where(array('id' => $data['id']))->update($update);
}
/*
if ($kou && $data['status'] == 4) {
$state = MerchantService::instance()->setFrozenAccount($data['id'], $data['order_id'], $data['mid'], $data['pid'], $data['product_key'], $data['cash'], $project_id, $account, $data['isp']);
$update = array();
if (!$state) {
$update['status'] = 3;
$update['merchant_callback_error'] = 2;
} else {
$update['actual_cash'] = $state[0];
$update['product_cash'] = $state[1];
}
if ($update) {
$this->db()->where(array('id' => $data['id']))->update($update);
}
}
*/
/*
if (!$state) {
$this->db()->where(array('id' => $data['id']))->delete();
return false;
} elseif (($data['product_key'] == 'dxdc' || $data['product_key'] == 'xtdc') && $state) {
$this->db()->where(array('id' => $data['id']))->update(array('cash' => $state[0], 'actual_cash' => $state[0], 'product_cash' => $state[1]));
} elseif ($state) {
$this->db()->where(array('id' => $data['id']))->update(array('actual_cash' => $state[0], 'product_cash' => $state[1]));
/*
$merchant = MerchantService::instance()->getInfo($data['mid']);
if ($merchant['account_surplus'] < $state && $merchant['credit_surplus'] < $state) {
$this->db()->where(array('id' => $data['id']))->update(array('status' => 3));
MerchantService::instance()->resFrozenAccount($data['id'], $data['order_id'], $data['mid'], $data['pid'], $data['product_key'], $data['cash'], $project_id);
return false;
}
}
*/
} else {
if ($info['cid'] == $cid && ($info['status'] == 2 || $info['status'] == 3 || $info['status'] == 5)) {
return false;
}
$where['id'] = $data['id'] = $info['id'];
$update['pid'] = $pid;
$update['product_key'] = $product_key;
$update['cid'] = $cid;
$update['channel_order_id'] = $data['channel_order_id'];
$update['merchant_order_id'] = $data['merchant_order_id'];
//$update['cash'] = $data['cash'];
$update['url'] = $data['url'];
if ($request) {
$update['request'] = $data['request'];
}
if ($response) {
$update['response'] = $data['response'];
}
$update['status'] = $data['status'];
if ($info['status'] < 0) {
$update['create_at'] = date('Y-m-d H:i:s');
}
if ($info['num'] > 0) {
$update['num'] = $info['num'];
}
if ($info['pid'] != $pid) {
$product = ProductService::instance()->get($data['mid'], $data['pid']);
if ($product) {
if ($product['rule']) {
$product['percent'] = MerchantService::instance()->getPercent($product['percent'], $account, $data['product_key'], $data['cash'], $product['rule'], $data['isp']);
}
$product_percent_type = 1;
if (isset($product['percent_type']) && $product['percent_type']) {
$product_percent_type = $product['percent_type'];
}
if ($product_percent_type == 2) {
$update['product_cash'] = $product['percent'];
} else {
$update['product_cash'] = $product['percent']*$data['cash'];
}
}
}
if($info['product_key'] != $product_key ){
// var_dump($info['actual_cash']);die;
// var_dump($data);die;
// $states = MerchantService::instance()->resFrozenAccount($info['id'], $info['order_id'], $mid, $pid, $product_key, $info['cash'], false, $info['account'], $info['isp']);
$upPrice = [
'old_price'=>$info['actual_cash'],
// 'new_price'=>$data['actual_cash'],
'old_product_cash'=>$info['product_cash'],
];
#重新扣费
$state = MerchantService::instance()->setFrozenAccount($data['id'], $data['order_id'], $data['mid'], $data['pid'], $data['product_key'], $data['cash'], $project_id, $account, $data['isp'],false,false,$upPrice);
// var_dump($state);
if (!$state) {
$update['merchant_callback_error'] = 2;
$data['error_account_oper'] = $update['error_account_oper'] = 2;
} else {
$update['actual_cash'] = $state[0];
if (isset($state[2])) {
$update['account_type'] = $state[2];
}
}
}
// if($account == '18296228692'){
// var_dump($info);
// var_dump($product_key);
// var_dump(123);die;
// }
$this->db()->where($where)->update($update);
/*
if ($kou && $data['status'] == 4 && $info['actual_cash'] <= 0) {
$state = MerchantService::instance()->setFrozenAccount($data['id'], $data['order_id'], $data['mid'], $data['pid'], $data['product_key'], $data['cash'], $project_id, $account, $data['isp']);
if ($state) {
$update = array();
$update['actual_cash'] = $state[0];
$update['product_cash'] = $state[1];
$this->db()->where($where)->update($update);
}
}
*/
}
return $data;
}
# 修改订单失败的返还状态
public function upError($id, $status = false)
{
$where['id'] = $id;
$data['error_account_oper'] = 2;
if ($status) {
$data['status'] = $status;
}
$this->db()->where($where)->update($data);
}
# 修改订单状态
public function upStatus($order_id, $status = 2, $request = '', $yctime = false, $num = false)
{
$data['status'] = $status;
$where = array();
$n = $this->getOrderId($order_id, $where);
if ($request) {
if (is_array($request)) {
$request = json_encode($request, JSON_UNESCAPED_UNICODE);
}
$data['request'] = $request;
}
if ($yctime) {
$data['yctime'] = time() + $yctime;
}
if ($num) {
$data['num'] = $num;
}
$this->db()->where($where)->update($data);
}
# 修改商户回调信息
public function upMerchantMsg($order_id, $num, $msg, $error = 0, $status = false)
{
$data['merchant_callback_msg'] = $msg;
$data['merchant_callback_at'] = date('Y-m-d H:i:s');
$data['merchant_callback_num'] = $num + 1;
if ($error > 0) {
$data['merchant_callback_error'] = $error;
}
if ($status) {
$data['status'] = $status;
}
$where = array();
$num = $this->getOrderId($order_id, $where);
return $this->db()->where($where)->update($data);
}
# 修改渠道回调信息
public function upChannelMsg($order_id, $status, $msg)
{
$data['status'] = $status;
$data['channel_callback_msg'] = json_encode($msg, JSON_UNESCAPED_UNICODE);
if ($data['status'] != 4) {
$data['channel_callback_at'] = date('Y-m-d H:i:s');
}
$where = array();
$num = $this->getOrderId($order_id, $where);
$this->db()->where($where)->update($data);
}
# 获取某一个商户的订单总额
public function getTotal($mid, $status = 1)
{
$where['mid'] = $mid;
if ($status > 0) {
$where['status'] = $status;
}
return $this->db()->where($where)->sum('cash');
}
# 查找订单
public function get($order_id, $merchant_order_id = false, $mid = false, $status = false)
{
$num = 0;
$where = array();
if ($merchant_order_id) {
$where['merchant_order_id'] = $merchant_order_id;
} else {
$num = $this->getOrderId($order_id, $where);
}
if ($mid) {
$where['mid'] = $mid;
}
if ($status) {
$where['status'] = $status;
}
$info = $this->db()->where($where)->find();
if ($info) {
$info['num'] = $num;
}
return $info;
}
#获取订单状态
public function getOrderStatus($merchant_order_id,$mid = false)
{
$num = 0;
$where = array();
$where['merchant_order_id'] = $merchant_order_id;
if ($mid) {
$where['mid'] = $mid;
}
$info = $this->db()->where($where)->field('status,merchant_order_id,create_at,account,mid')->find();
if ($info) {
$info['num'] = $num;
}
return $info;
}
public function getOrderId($order_id, &$where)
{
$num = 0;
if (is_numeric($order_id)) {
$where['id'] = $order_id;
} else {
if (str_contains($order_id, '_')) {
$temp = explode('_', $order_id);
$order_id = $temp[0];
$num = $temp[1];
}
$where['order_id'] = $order_id;
}
return $num;
}
# 获取当前最新的下单订单
public function getData()
{
/*
$cur = time();
$time = 24 * 3600;
$whereRaw = $cur . '-unix_timestamp(create_at) <=' . $time;
return $this->db()->whereRaw('status = 1 and ' . $whereRaw)->order('id asc')->select();
*/
return $this->db()->where(array('status' => 1))->order('id asc')->select();
}
# 获取超过5分钟的下单订单
public function getOldData()
{
$cur = time();
$time = 300;
$whereRaw = $cur . '-unix_timestamp(create_at) >=' . $time;
return $this->db()->whereRaw('status = 1 and ' . $whereRaw)->order('id asc')->select();
}
# 获取超过5分钟的下单订单
public function getOldDataDiy($DIYtime)
{
$cur = time();
$time = 60*$DIYtime;
$whereRaw = $cur . '-unix_timestamp(create_at) >=' . $time;
return $this->db()->whereRaw('status = 1 and ' . $whereRaw)->order('id asc')->select();
}
# 获取临时订单
public function getTempOrder()
{
return $this->db()->where(array('status' => -1))->order('id asc')->limit('30')->select()->toArray();
}
# 获取下单失败的订单
public function getErrorOrder()
{
return $this->db()->where(array('status' => -2))->order('id asc')->limit('30')->select()->toArray();
}
# 获取需要复冲的的订单
public function getFcOrder()
{
return $this->db()->where(array('status' => -4))->whereRaw(' yctime < ' . time())->order('id asc')->limit('100')->select()->toArray();
}
# 获取暂停的的订单
public function getStopOrder()
{
return $this->db()->where(array('status' => -5))->order('id asc')->select()->toArray();
}
# 获取暂停的的订单
public function getStopOrderQueue()
{
return $this->db()->where(array('status' => -8))->order('id asc')->select()->toArray();
}
# 获取需要队列延迟的订单
public function getTimeOrder($cid, $pid, $cash = false, $num = 10)
{
$where = array();
$where['cid'] = $cid;
$where['status'] = -3;
if ($pid) {
$where['pid'] = $pid;
}
if ($cash) {
$where['cash'] = $cash;
}
return $this->db()->where($where)->order('id asc')->limit($num)->select()->toArray();
}
# 查找回调错误的订单
public function getErrorData()
{
return $this->db()->whereRaw('merchant_callback_error = 2 and merchant_callback_num < 5 and status in(2,3)')->order('id asc')->select();
}
# 获取某一个商户的订单数量
public function getOrderTotal($mid, $status = 1)
{
$where['mid'] = $mid;
if ($status > 0) {
$where['status'] = $status;
}
return $this->db()->where($where)->count();
}
# 获取5分钟之内的订单
public function getByAccount($account, $cash = false)
{
$cur = time();
$time = 300;
$where = '';
if ($cash) {
$where = ' cash = "'.$cash.'" and ';
}
$where .= 'now()-create_at <=' . $time;
return $this->db()->whereRaw('account ="'.$account.'" and ' . $where)->find();
}
# 获取所有完成的订单
public function getFinishData($day, $page = 1)
{
if (!$day) {
$start = date('Y-m-d', strtotime('-360 day'));
$day = date('Y-m-d', strtotime('-1 day'));
} else {
$start = $day;
}
$begin = $start . ' 00:00:00';
$after = $day . ' 23:59:59';
$time = [$begin, $after];
$db = $this->db()->whereRaw('status in(2,3) ');
$db = $db->whereBetween('create_at', $time)->order('id asc');
if ($page) {
$limit = 10000;
$page = $page - 1;
$page = $page*$limit;
$db->limit($page, $limit);
}
return $db->select()->toArray();
}
# 删除订单
public function del($id)
{
$where['id'] = $id;
return $this->db()->where($where)->delete();
}
# 获取所有子订单
public function getChildOrder($order)
{
$where['parent_order_id'] = $order;
return $this->db()->where($where)->order('id asc')->select();
}
# 检测某个账号的下单次数
public function countByAccount($account)
{
return true;
$where['account'] = $account;
$total = $this->db()->where($where)->count();
if ($total >= 3) {
return false;
} else {
return true;
}
}
# 获取相应类型的数量
public function getNum($pid, $status = 4, $cid = false)
{
if ($pid > 0) {
$where['pid'] = $pid;
}
if ($cid > 0) {
$where['cid'] = $cid;
}
$where['status'] = $status;
return $this->db()->where($where)->count();
}
# 计算实际消费金额
public function actual()
{
$data = $this->db()->where(array('actual_cash' => '0'))->select();
if ($data) {
$service = MerchantLogService::instance();
foreach ($data as $k => $v) {
$where['mid'] = $v['mid'];
$where['order_id'] = $v['order_id'];
$info = $service->db()->where($where)->find();
if ($info) {
$this->db()->where(array('id' => $v['id']))->update(array('actual_cash' => $info['num']));
}
}
}
$data = $this->db()->where(array('product_cash' => '0'))->select();
if ($data) {
$service = MerchantLogService::instance();
foreach ($data as $k => $v) {
$where['mid'] = $v['mid'];
$where['order_id'] = $v['order_id'];
$info = $service->db()->where($where)->find();
if ($info) {
$this->db()->where(array('id' => $v['id']))->update(array('product_cash' => $info['product_cash']));
}
}
}
}
# 计算当前冻结额度
public function getDong($mid, $time, $time_col = 'create_at', $col = 'actual_cash', $where = array())
{
$db = $this->db();
if ($mid) {
$where['mid'] = $mid;
}
if ($where) {
$db->where($where);
}
$db->whereRaw('status not in(2,3,5)');
if ($time) {
$db->whereBetween($time_col, $time);
}
if ($col == '*') {
return round($db->count($col), 2);
}
return round($db->sum($col), 2);
}
public function cancelOrder($v){
$v['order']=$v['order_id'];
$result= MerchantService::instance()->qxdd($v);
if($result['code']==1){
}
}
public function callSend($v, $type, $limit = true)
{
if ($v['status'] == 2 || $v['status'] == 3) {
if (!$v['channel_callback_msg']) {
$v['channel_callback_msg'] = '{}';
}
$request = json_decode($v['channel_callback_msg'], true);
$update['project_id'] = false;
if (isset($v['project_id'])) {
$update['project_id'] = $v['project_id'];
}
if (isset($v['card_id'])) {
$update['card_id'] = $v['card_id'];
}
$update['account'] = $v['account'];
$update['status'] = $v['status'];
$update['data'] = $request;
$update['cash'] = $v['cash'];
$update['merchant_order_id'] = $v['merchant_order_id'];
$update['order_id'] = $v['order_id'];
$update['notify_num'] = $v['merchant_callback_num'];
$number = '';
if (isset($request['s_nubmer']) && $request['s_nubmer']) {
$number = $request['s_nubmer'];
} elseif (isset($request['s_number']) && $request['s_number']) {
$number = $request['s_number'];
}
$order_name = 's_nubmer';
if ($number && $order_name) {
$update[$order_name] = $number;
} elseif ($number) {
$update['s_nubmer'] = $number;
}
if (isset($request['code']) && $request['code']) {
$update['code'] = $request['code'];
}
if (isset($request['msg']) && $request['msg']) {
$update['msg'] = $request['msg'];
}
if (isset($v['isp']) && $v['isp']) {
$update['isp'] = $v['isp'];
}
if (isset($v['param']) && $v['param']) {
$v['param'] = json_decode($v['param'], true);
} else {
$v['param'] = false;
}
if ($v['param'] && isset($v['param']['notify']) && $v['param']['notify']) {
$update['notify'] = $v['param']['notify'];
}
// var_dump($update);die;
# 商户后续操作
//if (!$v['merchant_callback_msg'] && !$v['merchant_callback_at']) {
if (isset($v['error_account_oper']) && $v['error_account_oper'] == 1 && $type == 1) {
# 需要进行扣费
MerchantService::instance()->up($v['id'], $v['mid'], $v['pid'], $v['product_key'], $update);
} else {
# 直接发送
MerchantService::instance()->notify($v['id'], $v['mid'], $v['pid'], $v['product_key'], $update, $type, $limit);
}
}
}
#申请退单
public function apply_refund($v, $type =1)
{
if ($v['status'] == 4) {
// 1'=>'下单','2'=>'成功', '3'=> '失败', '4' => '处理中', '5' => '存疑', '7' => '提卡成功待处理','-1' => '队列中', '-2' => '失败待处理', '-3' => '排队中', '-4' => '复充排队中', '-5' => '已暂停', '-6' => '已冻结'
if($type == 1){
$update['apply_refund'] = 1;
$order = OrderServiceBase::instance();
$order->db()->where(array('order_id' => $v['order_id']))->update($update);
}
$channelService = ChannelService::instance();
$result = $channelService->call('cancel', $v['cid'], $v);
if($result == 'success') {
return 'success';
}
if($result == 'fail') {
return 'fail';
}
return $result;
}
}
# 修正未扣款的订单
public function kou($day = false)
{
$page = 1;
while($this->kouOne($day, $page)) {
$page++;
}
}
# 修正未扣款的订单
public function kouOne($day = false, $page = 1)
{
if (!$day) {
$day = date('Y-m-d', strtotime('-1 day'));
}
$begin = $day . ' 00:00:00';
$after = $day . ' 23:59:59';
$time = [$begin, $after];
$db = $this->db()->whereRaw('status in(2,3) ');
$db = $db->whereBetween('create_at', $time)->order('id asc');
if ($page) {
$limit = 1000;
$page = $page - 1;
$page = $page*$limit;
$db->limit($page, $limit);
}
$data = $db->select()->toArray();
if ($data) {
$service = MerchantLogService::instance();
foreach ($data as $k => $v) {
$where = array();
$where['mid'] = $v['mid'];
if (strstr($v['order_id'], '_')) {
$temp = explode('_', $v['order_id']);
$v['order_id'] = $temp[0];
}
$where['order_id'] = $v['order_id'];
$log = $service->db()->where($where)->select()->toArray();
$num = count($log);
if ($v['status'] == 3) {
# 只有一条,要补充一下
if ($num == 1) {
if ($log[0]['type'] == 3) {
MerchantService::instance()->resFrozenAccount($v, $v['order_id'], $v['mid'], $v['pid'], $v['product_key'], $v['cash'], $v['project_id'], $v['account'], $v['isp']);
} elseif ($log[0]['type'] == 4) {
MerchantService::instance()->setFrozenAccount($v, $v['order_id'], $v['mid'], $v['pid'], $v['product_key'], $v['cash'], $v['project_id'], $v['account'], $v['isp'], $v['create_at']);
}
} elseif ($num == 2) {
foreach ($log as $k1 => $v1) {
$service->db()->where(array('id' => $v1['id']))->update(array('order_date' => $v['create_at'], 'create_at' => $v['create_at']));
}
} elseif ($num <= 0) {
}
} elseif ($v['status'] == 2) {
if ($num <= 0) {
MerchantService::instance()->setFrozenAccount($v, $v['order_id'], $v['mid'], $v['pid'], $v['product_key'], $v['cash'], $v['project_id'], $v['account'], $v['isp'], $v['create_at']);
}
}
}
return true;
} else {
return false;
}
}
# 获取超过几分钟的下单订单
public function getKamiOldDataDiy($DIYtime)
{
$cur = time();
$time = 60*$DIYtime;
$whereRaw = $cur . '-unix_timestamp(create_at) >=' . $time;
return $this->db()->whereRaw('status = 7 and ' . $whereRaw)->order('id asc')->select();
}
}