• 积分商城:积分有过期情况下动态计算剩余积分


    一个大致思路:拉出将所有积分变动数据 进行计算

    <?php
    namespace AppService;
    
    use AppModelsTbaIntegralLog;
    use AppModelsUser;
    
    /**
     * 计算剩余积分:
     *
     * 1.将有 有效期的积分 按顺序排列
     * 2.将 扣积分的数据 按照时间顺序排列
     * 3.遍历扣积分的数据,依次从有效期顺序的积分中扣除
     * 4.不够扣的到下一个有效期积分中扣,扣没了就直接累计负数
     */
    class CalculateBalance
    {
        /**
         * $income_score = [
         *   '2022-01-31' => 150,
         *   '2022-02-26' => 150,
         *   '2022-03-31' => 150,
         * ];
         * $used_score = [
         *   '2021-10-01' => 100,
         *   '2021-10-03' => 150,
         * ];
         */
        // 收入的积分
        public $income_score;
        // 消耗的积分
        public $used_score;
        // 字段用于income_score不够扣了,将不够扣的金额累计到borrow中
        public $borrow = 0;
        // 初始化积分数据 和消费数据
        public function __construct(User $user)
        {
            $income_score = [];
            $used_score = [];
            TbaIntegralLog::select(["user_id", "expire_at", "amount"])
                ->where("user_id", $user->id)
                ->whereIn("type", [TbaIntegralLog::TYPE_HISTORY_IN, TbaIntegralLog::TYPE_MONTHLY_IN, TbaIntegralLog::TYPE_FORMAL_AWARD])
                ->orderBy("expire_at", "asc")
                ->get()
                ->each(function ($item) use (&$income_score) {
                    if (empty($income_score[$item->expire_at])) {
                        $income_score[$item->expire_at] = 0;
                    }
                    $income_score[$item->expire_at] = bcadd($income_score[$item->expire_at], $item->amount, 2);
                });
            TbaIntegralLog::select(["user_id", "amount", "at"])
                ->where("user_id", $user->id)
                ->whereIn("type", [TbaIntegralLog::TYPE_EXPEND_OUT])
                ->orderBy("at", "asc")
                ->get()
                ->each(function ($item) use (&$used_score) {
                    if (empty($used_score[$item->at])) {
                        $used_score[$item->at] = 0;
                    }
                    $used_score[$item->at] = bcsub($used_score[$item->at], $item->amount, 2);
                });
            $this->income_score = $income_score;
            $this->used_score = $used_score;
        }
        /**
         * 输入消费日期和消费积分
         * 按积分过期顺序实时抵消(消费时还未过期的)收入积分
         *
         * @return void
         */
        protected function hedgeFund($date, $score)
        {
            $income_arr = &$this->income_score;
            $current = $score;
            foreach ($income_arr as $expire_at => $income) {
                if ($income > 0 && $current > 0 && $expire_at > $date) {
                    if ($income >= $current) {
                        $income_arr[$expire_at] = bcsub($income, $current, 2);
                        $current = '0.00';
                    } else {
                        $income_arr[$expire_at] = '0.00';
                        $current = bcsub($current, $income, 2);
                    }
                }
                if ($current === '0.00') {
                    break;
                }
            }
            // 积分不够的时候就要借了
            if ($current > 0) {
                $this->borrow = bcadd($this->borrow, $current, 2);
            }
        }
        public function run()
        {
            foreach ($this->used_score as $used_at => $used) {
                $this->hedgeFund($used_at, $used);
            }
            // 获取最终积分余额
            if ($this->borrow > 0) {
                return bcsub(0, $this->borrow, 2);
            }
            $now = date("Y-m-d");
            $sum = 0;
            foreach ($this->income_score as $expire_at => $score) {
                if ($now < $expire_at) {
                    $sum = bcadd($sum, $score, 2);
                }
            }
            return $sum;
        }
    }
    
  • 相关阅读:
    hadoop yarn日志分离
    hadoop优化
    hive UDF
    hadoophttpfs
    spark编译
    spark feature
    python
    python 装饰器
    HTML特殊转义字符列表
    博客园数据统计
  • 原文地址:https://www.cnblogs.com/zjhblogs/p/15492373.html
Copyright © 2020-2023  润新知