140 行
5.0 KiB
PHP
140 行
5.0 KiB
PHP
<?php
|
||
|
||
namespace addons\shopro\service\partner;
|
||
|
||
use app\admin\model\shopro\partner\RateLog;
|
||
use app\admin\model\shopro\order\Order as OrderModel;
|
||
use app\admin\model\shopro\commission\CommissionGoods;
|
||
|
||
/**
|
||
* 马豆汇率:rate = base * floor(N / n)
|
||
*/
|
||
class RateService
|
||
{
|
||
/**
|
||
* 获取大盘当前即时生效汇率(基于全网合格订单 N 实时动态计算,短缓存 120 秒保障高并发读性能)
|
||
*
|
||
* @param bool $forceRefresh 是否强制穿透缓存实时重算
|
||
* @return float
|
||
*/
|
||
public function currentRate($forceRefresh = false)
|
||
{
|
||
if (!$forceRefresh) {
|
||
$cached = cache('partner_madow_current_rate');
|
||
if ($cached !== null && $cached !== false && (float) $cached > 0) {
|
||
return (float) $cached;
|
||
}
|
||
}
|
||
$rate = $this->calcRate($this->countN());
|
||
cache('partner_madow_current_rate', $rate, 120);
|
||
return $rate;
|
||
}
|
||
|
||
/**
|
||
* 主动清除当前马豆汇率缓存(订单支付、退款或后台调整时调用)
|
||
*/
|
||
public static function clearCache()
|
||
{
|
||
cache('partner_madow_current_rate', null);
|
||
}
|
||
|
||
public function calcRate($n = null)
|
||
{
|
||
$n = $n === null ? $this->countN() : intval($n);
|
||
$base = (float) PartnerConfig::get('partner_madow_base_rate', 0.00000075);
|
||
$step = intval(PartnerConfig::get('partner_madow_step_orders', 1));
|
||
$step = $step > 0 ? $step : 1;
|
||
$multiple = max(1, floor($n / $step));
|
||
return function_exists('bcmul') ? (float) bcmul((string) $base, (string) $multiple, 10) : (float) ($base * $multiple);
|
||
}
|
||
|
||
public function countN()
|
||
{
|
||
return $this->qualifiedOrderQuery()->count();
|
||
}
|
||
|
||
public function snapshot($settleDate, $gmv = 0, $extra = [])
|
||
{
|
||
$n = $this->countN();
|
||
$rate = $this->calcRate($n);
|
||
$row = RateLog::where('settle_date', $settleDate)->find();
|
||
$data = array_merge([
|
||
'settle_date' => $settleDate,
|
||
'order_count_n' => $n,
|
||
'rate' => $rate,
|
||
'gmv' => $gmv,
|
||
'createtime' => time(),
|
||
], $extra);
|
||
if ($row) {
|
||
$row->save($data);
|
||
cache('partner_madow_current_rate', (float) $rate, 300);
|
||
return $row;
|
||
}
|
||
$created = RateLog::create($data);
|
||
cache('partner_madow_current_rate', (float) $rate, 300);
|
||
return $created;
|
||
}
|
||
|
||
public function qualifiedOrderQuery($start = null, $end = null)
|
||
{
|
||
$goodsTable = (new CommissionGoods())->getQuery()->getTable();
|
||
$orderTable = (new OrderModel())->getQuery()->getTable();
|
||
$itemTable = \think\Db::name('shopro_order_item')->getTable();
|
||
|
||
$query = OrderModel::alias('o')
|
||
->where('o.type', '<>', 'score')
|
||
->where('o.pay_fee', '>', 0)
|
||
->whereIn('o.status', [OrderModel::STATUS_PAID, OrderModel::STATUS_COMPLETED])
|
||
->whereExists(function ($q) use ($orderTable, $itemTable, $goodsTable) {
|
||
$q->table($itemTable)->alias('oi')
|
||
->join($goodsTable . ' cg', 'cg.goods_id = oi.goods_id')
|
||
->whereRaw('oi.order_id = o.id')
|
||
->where('cg.status', CommissionGoods::GOODS_COMMISSION_STATUS_ON);
|
||
});
|
||
|
||
if ($start !== null) {
|
||
$query->where('o.paid_time', '>=', $start);
|
||
}
|
||
if ($end !== null) {
|
||
$query->where('o.paid_time', '<=', $end);
|
||
}
|
||
return $query;
|
||
}
|
||
|
||
/**
|
||
* 汇总指定时间区间内所有合格订单中“计奖商品”的实付总额(排除非计奖商品及活动不参与项)
|
||
*/
|
||
public function qualifiedGmv($start = null, $end = null)
|
||
{
|
||
$goodsTable = (new CommissionGoods())->getQuery()->getTable();
|
||
$orderTable = (new OrderModel())->getQuery()->getTable();
|
||
$itemTable = \think\Db::name('shopro_order_item')->getTable();
|
||
|
||
$query = \think\Db::table($itemTable)->alias('oi')
|
||
->join($orderTable . ' o', 'o.id = oi.order_id')
|
||
->join($goodsTable . ' cg', 'cg.goods_id = oi.goods_id')
|
||
->where('o.type', '<>', 'score')
|
||
->where('o.pay_fee', '>', 0)
|
||
->whereIn('o.status', [OrderModel::STATUS_PAID, OrderModel::STATUS_COMPLETED])
|
||
->where('cg.status', CommissionGoods::GOODS_COMMISSION_STATUS_ON)
|
||
->where(function ($q) {
|
||
$q->whereNull('oi.ext')
|
||
->whereOr('oi.ext', '')
|
||
->whereOr(function ($sq) {
|
||
$sq->where('oi.ext', 'not like', '%"is_commission":false%')
|
||
->where('oi.ext', 'not like', '%"is_commission":0%');
|
||
});
|
||
});
|
||
|
||
if ($start !== null) {
|
||
$query->where('o.paid_time', '>=', $start);
|
||
}
|
||
if ($end !== null) {
|
||
$query->where('o.paid_time', '<=', $end);
|
||
}
|
||
|
||
$gmv = $query->sum('oi.pay_fee');
|
||
return round((float) $gmv, 2);
|
||
}
|
||
}
|