| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- <?php
- namespace plugin\saiadmin\app\service;
- /**
- * 读取既有代理、商户分成,不在设备运营中维护另一份比例。
- * 代理档案存占总交易额的比例;商户存相对直属代理的比例。
- */
- class DeviceOperationShares
- {
- private array $agents = [];
- private array $agentsByDepartment = [];
- public function __construct(array $agents)
- {
- foreach ($agents as $agent) {
- $rates = json_decode($agent['profit_rates'] ?? '{}', true);
- $agent['rates'] = is_array($rates) ? $rates : [];
- $this->agents[(int) $agent['id']] = $agent;
- $this->agentsByDepartment[(int) $agent['dept_id']][] = (int) $agent['id'];
- }
- }
- public function calculate(array $device, string $product): array
- {
- if (empty($device['merchant_id'])) {
- return ['merchant_rate' => 0.0, 'manager_rate' => 0.0];
- }
- $merchantAgent = (int) $device['merchant_agent_id'];
- $manager = (int) $device['manage_agent_id'];
- $parentRate = $this->agentRate($merchantAgent, $product);
- $relativeRate = $this->validRate($device['merchant_relative_rate']);
- // 不分成和入驻费没有按订单比例分成;明确的 0 不依赖上级档案。
- if (in_array($device['profit_method'], ['不分成', '入驻费'], true) || $relativeRate === 0.0) {
- $merchantRate = 0.0;
- } else {
- $merchantRate = $parentRate !== null && $relativeRate !== null
- ? round($parentRate * $relativeRate / 100, 4) : null;
- }
- $managerRate = $this->agentRate($manager, $product);
- if ($manager === $merchantAgent) {
- $childRate = $merchantRate;
- } else {
- $childId = $this->findBranchChild($manager, $merchantAgent);
- // 0 表示管理人不在这条分成链上;NULL 表示关系有歧义,不能猜测。
- if ($childId === 0) {
- return ['merchant_rate' => $merchantRate, 'manager_rate' => 0.0];
- }
- $childRate = $childId === null ? null : $this->agentRate($childId, $product);
- }
- $netManagerRate = $managerRate !== null && $childRate !== null && $managerRate >= $childRate
- ? round($managerRate - $childRate, 4) : null;
- return ['merchant_rate' => $merchantRate, 'manager_rate' => $netManagerRate];
- }
- private function agentRate(int $id, string $product): ?float
- {
- return $this->validRate($this->agents[$id]['rates'][$product] ?? null);
- }
- private function validRate(mixed $value): ?float
- {
- return is_numeric($value) && $value >= 0 && $value <= 100 ? (float) $value : null;
- }
- /** 沿商户代理的部门祖先路径,查找管理人下面参与该笔分成的第一个代理。 */
- private function findBranchChild(int $managerId, int $merchantAgentId): ?int
- {
- $manager = $this->agents[$managerId] ?? null;
- $merchantAgent = $this->agents[$merchantAgentId] ?? null;
- if (!$manager || !$merchantAgent) {
- return null;
- }
- $path = array_map('intval', array_filter(explode(',', $merchantAgent['dept_level'] ?? ''), 'strlen'));
- $path[] = (int) $merchantAgent['dept_id'];
- $position = array_search((int) $manager['dept_id'], $path, true);
- if ($position === false) {
- return 0;
- }
- if ((int) $manager['dept_id'] === (int) $merchantAgent['dept_id']) {
- return null;
- }
- foreach (array_slice($path, $position + 1) as $departmentId) {
- if ($departmentId === (int) $merchantAgent['dept_id']) {
- return $merchantAgentId;
- }
- $candidates = $this->agentsByDepartment[$departmentId] ?? [];
- if (count($candidates) > 1) {
- return null;
- }
- if (count($candidates) === 1) {
- return $candidates[0];
- }
- }
- return null;
- }
- }
|