find(); if ($latest && (float) $latest->rate > 0) { return (float) $latest->rate; } $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, 300); return $rate; } 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; } }