文件
Henglianshutong/addons/shopro/service/partner/RateService.php

140 行
5.0 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

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