quanwei
2025-12-31 48d31672b4d88900080093cd1632f9d2eb978d4d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php
 
namespace app\api\service\points;
 
use app\common\library\helper;
use app\api\model\settings\Setting as SettingModel;
 
/**
 * 积分抵扣类
 */
class PointsDeductService
{
    private $productList;
 
    public function __construct($productList)
    {
        $this->productList = $productList;
    }
 
    public function setProductPoints($maxPointsNumCount, $actualPointsNum)
    {
        // 计算实际积分抵扣数量
        $this->setproductListPointsNum($maxPointsNumCount, $actualPointsNum);
        // 总抵扣数量
        $totalPointsNum = helper::getArrayColumnSum($this->productList, 'points_num');
        // 填充余数
        $this->setproductListPointsNumFill($actualPointsNum, $totalPointsNum);
        $this->setproductListPointsNumDiff($actualPointsNum, $totalPointsNum);
        // 计算实际积分抵扣金额
        $this->setproductListPointsMoney();
        return true;
    }
 
    /**
     * 计算实际积分抵扣数量
     */
    private function setproductListPointsNum($maxPointsNumCount, $actualPointsNum)
    {
        foreach ($this->productList as &$product) {
            if (!$product['is_points_discount']) continue;
            $product['points_num'] = floor($product['max_points_num'] / $maxPointsNumCount * $actualPointsNum);
        }
    }
 
    /**
     * 计算实际积分抵扣金额
     */
    private function setproductListPointsMoney()
    {
        $setting = SettingModel::getItem('points');
        foreach ($this->productList as &$product) {
            if (!$product['is_points_discount']) continue;
            $product['points_money'] = helper::bcmul($product['points_num'], $setting['discount']['discount_ratio']);
        }
    }
 
    private function setproductListPointsNumFill($actualPointsNum, $totalPointsNum)
    {
        if ($totalPointsNum === 0) {
            $temReducedMoney = $actualPointsNum;
            foreach ($this->productList as &$product) {
                if (!$product['is_points_discount']) continue;
                if ($temReducedMoney === 0) break;
                $product['points_num'] = 1;
                $temReducedMoney--;
            }
        }
        return true;
    }
 
    private function setproductListPointsNumDiff($actualPointsNum, $totalPointsNum)
    {
        $tempDiff = $actualPointsNum - $totalPointsNum;
        foreach ($this->productList as &$product) {
            if (!$product['is_points_discount']) continue;
            if ($tempDiff < 1) break;
            $product['points_num'] = $product['points_num'] + 1;
            $tempDiff--;
        }
        return true;
    }
 
}