<?php

namespace app\crontab\controller;

use app\common\api\RedisApi;
use app\common\model\Honor as mHonor;
use app\common\model\ManagerHonor as mManagerHonor;
use app\common\model\Recharge;
use app\common\model\Register;

/**
 * Class Put
 *
 * 数据入库
 *
 * @package app\crontab\controller
 */
class Put extends Base
{

    private $redis;

    public function __construct()
    {
        parent ::__construct();
        $this -> redis = new RedisApi();
    }


    /**
     * @注册数据入库
     *
     * @author: zsl
     * @since: 2021/3/4 20:05
     */
    public function register()
    {
        set_time_limit(0);
        $lockKey = 'register_put_lock';
        if ($this -> redis -> get($lockKey)) {
            return json(['code' => 0, 'msg' => '正在入库,请稍后再试', 'data' => []]);
        }
        //加锁
        $this -> redis -> set($lockKey, '1');
        //从redis中取出数据
        $listKey = 'register_data';
        $saveData = [];
        for ($i = 0; $i < 10000; $i ++) {
            $data = json_decode($this -> redis -> lPop($listKey), true);
            if ($data) {
                $saveData[] = $data;
            }
        }
        if (empty($saveData)) {
            //解锁
            $this -> redis -> del($lockKey);
            return json(['code' => 0, 'msg' => '暂无待入库数据', 'data' => []]);
        }
        //数据入库
        try {
            $mRegister = new Register();
            $result = $mRegister -> saveAll($saveData);
            if (false === $result) {
                // 写入失败记录
                foreach ($saveData as $v) {
                    $this -> redis -> rPush('register_data_error', json_encode($v));
                }
                //解锁
                $this -> redis -> del($lockKey);
                return json(['code' => 0, 'msg' => '入库失败', 'data' => []]);
            }
            //解锁
            $this -> redis -> del($lockKey);
            return json(['code' => 1, 'msg' => '入库完成', 'data' => []]);
        } catch (\Exception $e) {
            // 写入失败记录
            foreach ($saveData as $v) {
                $this -> redis -> rPush('register_data_error', json_encode($v));
            }
            //解锁
            $this -> redis -> del($lockKey);
            return json(['code' => 0, 'msg' => $e -> getMessage(), 'data' => []]);
        }


    }


    /**
     * @充值数据入库
     *
     * @author: zsl
     * @since: 2021/3/5 10:54
     */
    public function recharge()
    {
        set_time_limit(0);
        $lockKey = 'recharge_put_lock';
        if ($this -> redis -> get($lockKey)) {
            return json(['code' => 0, 'msg' => '正在入库,请稍后再试', 'data' => []]);
        }
        //从redis中取出数据
        $listKey = 'recharge_data';
        $saveData = [];
        for ($i = 0; $i < 10000; $i ++) {
            $data = json_decode($this -> redis -> lPop($listKey), true);
            if ($data) {
                $saveData[] = $data;
            }
        }
        if (empty($saveData)) {
            //解锁
            $this -> redis -> del($lockKey);
            return json(['code' => 0, 'msg' => '暂无待入库数据', 'data' => []]);
        }
        //数据入库
        try {
            $mRecharge = new Recharge();
            $result = $mRecharge -> saveAll($saveData);
            if (false === $result) {
                // 写入失败记录
                foreach ($saveData as $v) {
                    $this -> redis -> rPush('recharge_data_error', json_encode($v));
                }
                //解锁
                $this -> redis -> del($lockKey);
                return json(['code' => 0, 'msg' => '入库失败', 'data' => []]);
            }
            //更新员工荣誉等级
            $this -> setHonor($saveData);
            //解锁
            $this -> redis -> del($lockKey);
            return json(['code' => 1, 'msg' => '入库完成', 'data' => []]);
        } catch (\Exception $e) {
            // 写入失败记录
            foreach ($saveData as $v) {
                $this -> redis -> rPush('recharge_data_error', json_encode($v));
            }
            //解锁
            $this -> redis -> del($lockKey);
            return json(['code' => 0, 'msg' => $e -> getMessage(), 'data' => []]);
        }
    }


    /**
     * @更新员工荣誉值
     *
     * @author: zsl
     * @since: 2021/3/16 9:35
     */
    private function setHonor($saveData)
    {
        $honor_ratio = get_option('honor_ratio');
        //获取员工充值数据
        $data = [];
        foreach ($saveData as $v) {
            $data[$v['manager_id']][] = $v['cost_amount'];
        }
        //更新员工荣誉值
        foreach ($data as $k => $v) {
            $sum = array_sum($v);
            $honor_num = round($honor_ratio['price_ratio'] * $sum / 100);
            $mManagerHonor = new mManagerHonor();
            $honorDataObj = $mManagerHonor -> where(['manager_id' => $k]) -> find();
            if (empty($honorDataObj)) {
                //新建员工荣誉等级数据
                $honorDataObj = $mManagerHonor;
                $honorDataObj -> manager_id = $k;
                $honorDataObj -> honor_id = $this -> getHonorId($honor_num);
                $honorDataObj -> use_honor_num = 0;
                $honorDataObj -> current_honor_num = $honor_num;
                $honorDataObj -> total_honor_num = $honor_num;
            } else {
                //更新员工荣誉等级数据
                $honorDataObj -> manager_id = $k;
                $honorDataObj -> current_honor_num = $honorDataObj -> current_honor_num + $honor_num;
                $honorDataObj -> total_honor_num = $honorDataObj -> total_honor_num + $honor_num;
                $honorDataObj -> honor_id = $this -> getHonorId($honorDataObj -> total_honor_num);
            }
            $honorDataObj -> save();
        }
        return true;
    }


    /**
     * @获取当前所属荣誉等级id
     *
     * @author: zsl
     * @since: 2021/3/16 10:46
     */
    private function getHonorId($honor_num)
    {
        //获取荣誉等级规则
        $mHonor = new mHonor();
        $honorRule = $mHonor -> field('id,name,honor_num,status') -> where(['status' => 1]) -> select();
        $honorId = 0;
        foreach ($honorRule as $v) {
            if ($honor_num >= $v['honor_num']) {
                $honorId = $v['id'];
            }
        }
        return $honorId;
    }

}