_periodNum; } /** * 加入错误错误 * @param string $attr * @param string $error */ public function addError(string $attr, string $error) { $this->_errors[$attr][] = $error; } /** * 获取错误信息 * @return array */ public function getErrors() { return $this->_errors; } /** * 计算步骤 * @param $periodNum * @param null $handleUserId * @return bool */ public function calcStep($periodNum = null, $handleUserId = null) { try { // 先计算是否是结算月,并且是否到了周日0点 // 需要将线上的数据perf_order,perf_period两个表的数据同步过来 // Period表数据同步过来,只要是结算月的数据 $checkPrepare = $this->checkCanCalcPref($periodNum); if ($checkPrepare !== true) { return true; } $this->_errors = []; $this->_handleUserId = $handleUserId; if (empty($periodNum)) { echo('定时器执行预业绩计算 ,内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL); } $this->_updatePercent(5); $t1 = microtime(true); // 初始化结算任务 $this->initCalcTask($periodNum); $this->_updatePercent(10); // 设置结算状态 $this->setCalcStatus('start', $periodNum); // 清空所有本期结算用到的缓存 PrepareCalcCache::clearAll($this->_periodNum); // 清空会员推荐和接点关系缓存 PrepareCalcCache::clearNetCache(); // 清空相关表数据 $this->clearTableData(); $this->_updatePercent(15); $t2 = microtime(true); echo(date('Y-m-d H:i:s',time()).'初始化、清空缓存及相关数据表完成,耗时:' . round($t2 - $t1, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL); // 计算月奖,才需要向缓存中加入按推荐深度的所有用户 //修改每一期都缓存所有用户 PrepareCalcCache::addUsers($this->_periodNum); $t3 = microtime(true); echo('预计算业绩向缓存中加入用户完成,耗时:' . round($t3 - $t2, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL); $this->_updatePercent(20); // 周结,循环向上级计入业绩并加入业绩单 $this->loopCalcPeriodPerfByDecOrder(); $this->loopCalcPeriodPerfByOrderDec(); $t4 = microtime(true); echo('预计算业绩计算周业绩表中的数据完成,耗时:' . round($t4 - $t1, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL); $this->_updatePercent(40); // 从会员的复销订单会员计算复销业绩并加入业绩单 $this->loopCalcPerfByFXOrder(); $this->loopCalcPerfByShopFXOrder(); $t5 = microtime(true); echo('预计算业绩计算复销业绩并写入业绩单完成,耗时:' . round($t5 - $t4, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL); $this->_updatePercent(60); //本期业绩入库 $this->loopWriteNowPerf(); $t6 = microtime(true); echo('预计算业绩本期业绩入库完成,耗时:' . round($t6 - $t5, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL); $this->_updatePercent(70); //计算月业绩表中的数据 $this->loopCalcMonthPerfTableData(); $t7 = microtime(true); echo('预计算业绩计算月业绩表中的数据完成,耗时:' . round($t7 - $t6, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL); $this->_updatePercent(80); $t8 = microtime(true); // 计算预计月业绩表的数据,这些数据用户不在前三期非月节点的数据.需要将此期新用户业绩统计一下 $this->loopCalcMonthPerfTableDataPrepare(); //本月业绩入库 $this->loopWriteMonthPerf(); $t7 = microtime(true); echo('预计算业绩本月业绩入库完成,耗时:' . round($t7 - $t6, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL); $this->_updatePercent(90); $t9 = microtime(true); $this->_updatePercent(100); $t10 = microtime(true); echo('预计算业绩业绩结算全部完成,共耗时:' . round($t10 - $t9, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL); } catch (\Exception $e) { $this->errorCalcTask(); file_put_contents('error_test.txt', var_export([ 'err' => $e->getMessage() ],true),FILE_APPEND); $this->addError('calc', $e->getMessage()); return false; } $this->endCalcTask(); return true; } /** * 结算完成 * @return bool */ public function endCalcTask() { // 更新结算状态 $this->setCalcStatus('end'); } /** * 结算错误 */ public function errorCalcTask() { // 清空所有本期结算用到的缓存 PrepareCalcCache::clearAll($this->_periodNum); // 更新结算状态 $this->setCalcStatus('fail'); } /** * 设置生成业绩单状态 * @param $type * start|end|fail */ public function setCalcStatus($type, $periodNum = null) { if ($type == 'start') { $this->_lastTime = !empty($periodNum) ? Date::nowTime() : $this->_lastTime; PeriodPrepare::updateAll(['IS_PERFING' => 1, 'IS_PERFED' => Period::PERF_NONE, 'PERF_STARTED_AT' => $this->_lastTime], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]); } elseif ($type == 'end') { PeriodPrepare::updateAll(['IS_PERFING' => 0, 'IS_PERFED' => Period::PERF_FINISH, 'PERFED_AT' => Date::nowTime()], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]); } elseif ($type == 'fail') { PeriodPrepare::updateAll(['IS_PERFING' => 0, 'IS_PERFED' => Period::PERF_FAIL, 'PERFED_AT' => 0], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]); } } public function checkCanCalcPref($periodNum = null) { // 先判断时间,现在是周几,如果不是周日,则直接结束 // 如果是手动触发,即有业绩期$periodNum变量值,则不校验必须周日0点 $w = $h = ''; if (empty($periodNum)) { $w = date('w',time()); if ($w != '0') { return false; } // 判断是否是周日0点 $h = date('H',time()); if ($h !=0 ) { return false; } } // 判断此结算周期是否是月结算节点 // 这里 如果定时任务业绩期是nul $periodObj = Period::instance(); $periodDataArr = $periodObj->setPeriodNum($periodNum); if ($periodDataArr['IS_MONTH'] != 1) { return false; } // 如果是手动进行计算得月业绩,则不需要判断结算当前状态 // 判断此结算周期是否已经进行业绩计算,如果已进行或者进行过,则不能继续执行 if (empty($periodNum)) { $prepare = PeriodPrepare::find() ->select('IS_MONTH, IS_PERFING,IS_PERFED') ->where( 'PERIOD_NUM=:PERIOD_NUM', [ 'PERIOD_NUM'=>$periodDataArr['PERIOD_NUM'] ]) ->asArray() ->one(); // 如果正在结算或者已计算完,则不进行计算,因为预计计算是定时任务每5秒扫一次,所以不能再触发预计算业绩 if ($prepare['IS_PERFING'] == 1 || $prepare['IS_PERFED'] == 1) { return false; } } return true; } /** * 初始化结算任务 * @throws \yii\db\Exception */ public function initCalcTask($periodNum = null) { $periodObj = Period::instance(); $periodDataArr = $periodObj->setPeriodNum($periodNum); // 限制订单的时间:如果是定时器,则固定为每周日的0点. 如果是手动执行,则是进行异步代码的时间 // 这里直接使用后台生成业绩单的时间 $this->_lastTime = empty($periodNum)? $periodDataArr['END_TIME'] - 86399: $periodDataArr['END_TIME']; $this->_periodNum = $periodDataArr['PERIOD_NUM']; $this->_sysConfig = Cache::getSystemConfig(); $this->_decLevelConfig = Cache::getDecLevelConfig(); $this->_empLevelConfig = Cache::getEmpLevelConfig(); $this->_decRoleConfig = PrepareCalcCache::getDecRoleConfig($this->_periodNum); $periodNum = $this->_periodNum; $this->_periodId = $periodDataArr['ID']; $this->_isCalcMonth = $periodObj->isCalcMonth($periodNum); $this->_calcYear = $periodObj->getYear($periodNum); $this->_calcMonth = $periodObj->getMonth($periodNum); $this->_calcYearMonth = $periodObj->getYearMonth($periodNum); $lastYearMonthArr = $periodObj->getLastMonth($periodNum); $this->_lastCalcYear = $lastYearMonthArr['year']; $this->_lastCalcMonth = $lastYearMonthArr['month']; $this->_lastCalcYearMonth = $lastYearMonthArr['yearMonth']; $this->_lastPeriodNum = $periodNum - 1; if (Period::isExistsPeriodNum($this->_lastPeriodNum)) { $this->_lastPeriodYear = $periodObj->getYear($this->_lastPeriodNum); $this->_lastPeriodMonth = $periodObj->getMonth($this->_lastPeriodNum); $this->_lastPeriodYearMonth = $periodObj->getYearMonth($this->_lastPeriodNum); } else { $this->_lastPeriodYear = 0; $this->_lastPeriodMonth = 0; $this->_lastPeriodYearMonth = 0; } $this->_pvRatio = $this->_sysConfig['pvRatio']['VALUE']; } /** * 清空相关表数据 */ public function clearTableData() { // 周业绩 PerfPeriodPrepare::pageDeleteAll('PERIOD_NUM='.$this->_periodNum); // 业绩单 PerfOrderPrepare::pageDeleteAll('PERIOD_NUM='.$this->_periodNum); // 月结时要清空的数据 if ($this->_isCalcMonth) { // 月业绩表 PerfMonthPrepare::pageDeleteAll("CALC_MONTH='{$this->_calcYearMonth}'"); } } /** * 周结,向上级算业绩,并计入业绩单 * @param int $offset * @return bool * @throws \yii\db\Exception */ public function loopCalcPeriodPerfByDecOrder($offset = 0) { // 循环获取全部报单 $allData = DecOrder::findUseDbCalc() ->select('ID,DEC_SN,ORDER_SN,USER_ID,TYPE,TO_USER_ID,IS_ADMIN,DEC_AMOUNT,DEC_PV,PERIOD_NUM, CALC_MONTH,IS_DEL,P_CALC_MONTH,CREATED_AT,DEC_ID') ->where( "PERIOD_NUM=:PERIOD_NUM AND IS_DEL=0 AND TYPE='ZC' AND CREATED_AT<=:CREATED_AT", [':PERIOD_NUM' => $this->_periodNum, ':CREATED_AT' => $this->_lastTime] ) ->orderBy('CREATED_AT DESC,ID DESC') ->offset($offset) ->limit($this->_limit) ->asArray() ->all(); if ($allData) { $insertPerfOrderData = []; foreach ($allData as $data) { // 是否关停等状态不能拿业绩 if (!$this->isHasPerf($data['TO_USER_ID'])) { continue; } // 给自己增加PCS(个人消费) PrepareCalcCache::nowPeriodPerf($data['TO_USER_ID'], $this->_periodNum, [ 'PV_PCS' => $data['DEC_PV'], 'PV_PCS_ZC' => $data['DEC_PV'], ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($data['TO_USER_ID'], $this->_periodNum); //加入到报单会员中 $toInfo = PrepareCalcCache::getUserInfo($data['TO_USER_ID'], $this->_periodNum); PrepareCalcCache::addHasBDUsers($data['TO_USER_ID'], $this->_periodNum, [ 'TO_USER_ID' => $data['TO_USER_ID'], 'USER_ID' => $data['USER_ID'], 'DEC_ID' => $data['DEC_ID'], //考虑可能会移网的情况 'REC_USER_ID' => $toInfo['REC_UID'] ?? '', 'CON_USER_ID' => $toInfo['CON_UID'] ?? '', 'DEC_AMOUNT' => $data['DEC_AMOUNT'], 'DEC_PV' => $data['DEC_PV'], ]); // 给上追加业绩 $this->loopNetworkParentDo($data['TO_USER_ID'], function ($parent) use (&$data) { // 给上级会员追加本期业绩到缓存中 PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [ 'PV_' . $parent['LOCATION'] . 'L' => $data['DEC_PV'], 'PV_' . $parent['LOCATION'] . 'L_TOUCH' => $data['DEC_PV'], 'PV_' . $parent['LOCATION'] . 'L_' . $data['TYPE'] => $data['DEC_PV'], ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum); unset($parent); }); //给推荐关系累计增加业绩 $this->loopRelationParentDo($data['TO_USER_ID'], function ($parent) use (&$data) { // 给上级会员追加本期业绩到缓存中 PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [ 'PV_PSS' => $data['DEC_PV'], ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum); unset($parent); }); // 写入业绩单表 $decInfo = PrepareCalcCache::getUserInfo($data['USER_ID'], $this->_periodNum); $sn = PerfOrderPrepare::generateSN(); $insertPerfOrderData[] = [ 'ID' => SnowFake::instance()->generateId(), 'SN' => $sn, 'DEC_SN' => $data['DEC_SN'], 'DEC_TYPE' => strtoupper($data['TYPE']), 'DEC_STATUS' => PerfOrder::STATUS_NORMAL, 'USER_ID' => $data['TO_USER_ID'], 'LAST_REC_USER_NAME' => $toInfo['REC_USER_NAME'], 'LAST_REC_REAL_NAME' => $toInfo['REC_REAL_NAME'], 'LAST_DEC_LV' => $toInfo['DEC_LV'], 'LAST_EMP_LV' => $toInfo['EMP_LV'], 'LAST_STATUS' => $toInfo['STATUS'], 'PV' => $data['DEC_PV'], 'DEC_AMOUNT' => $data['DEC_AMOUNT'], 'LAST_SUB_COM_ID' => $toInfo['SUB_COM_ID'], 'LAST_PROVINCE' => $toInfo['PROVINCE'], 'LAST_CITY' => $toInfo['CITY'], 'LAST_COUNTY' => $toInfo['COUNTY'], 'DEC_USER_ID' => $data['USER_ID'], 'LAST_DEC_DEC_LV' => $decInfo['DEC_LV'], 'LAST_DEC_SUB_COM_ID' => $decInfo['SUB_COM_ID'], 'LAST_DEC_PROVINCE' => $decInfo['DEC_PROVINCE'], 'LAST_DEC_CITY' => $decInfo['DEC_CITY'], 'LAST_DEC_COUNTY' => $decInfo['DEC_COUNTY'], 'PERIOD_NUM' => $this->_periodNum, 'CALC_MONTH' => $this->_calcYearMonth, 'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH), 'CREATED_AT' => Date::nowTime(), 'CLOSED_AT' => 0, 'ORDER_CREATED_AT' => $data['CREATED_AT'], ]; unset($data, $decInfo, $sn, $toInfo); } PerfOrderPrepare::batchInsert($insertPerfOrderData); unset($insertPerfOrderData, $allData, $snArr); return $this->loopCalcPeriodPerfByDecOrder($offset + $this->_limit); } unset($allData); return true; } /** * 周结,向上级算业绩,并计入业绩单 * @param int $offset * @return bool * @throws \yii\db\Exception */ public function loopCalcPeriodPerfByOrderDec($offset = 0) { // 循环获取全部报单 $allData = OrderDec::findUseDbCalc() ->select('CREATED_AT,ID,SN,USER_ID,ORDER_TYPE,ORDER_AMOUNT,PV,PAY_AMOUNT,PAY_PV,PERIOD_NUM,PAY_TYPE') ->where( "PERIOD_NUM=:PERIOD_NUM AND IS_DELETE=0 AND ORDER_TYPE=:ORDER_TYPE AND CREATED_AT<=:CREATED_AT", [':PERIOD_NUM' => $this->_periodNum, ':ORDER_TYPE'=>'ZC', ':CREATED_AT' => $this->_lastTime]) ->orderBy('ID DESC') ->offset($offset) ->limit($this->_limit) ->asArray() ->all(); if ($allData) { $insertPerfOrderData = []; foreach ($allData as $data) { // 是否关停等状态不能拿业绩 if (!$this->isHasPerf($data['USER_ID'])) { continue; } // 给自己增加PCS(个人消费) PrepareCalcCache::nowPeriodPerf($data['USER_ID'], $this->_periodNum, [ 'PV_PCS' => $data['PAY_PV'], 'PV_PCS_ZC' => $data['PAY_PV'], ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($data['USER_ID'], $this->_periodNum); //加入到报单会员中 $toInfo = PrepareCalcCache::getUserInfo($data['USER_ID'], $this->_periodNum); PrepareCalcCache::addHasBDUsers($data['USER_ID'], $this->_periodNum, [ 'TO_USER_ID' => $data['USER_ID'], 'USER_ID' => $toInfo['DEC_ID'], 'DEC_ID' => $toInfo['DEC_ID'], //考虑可能会移网的情况 'REC_USER_ID' => $toInfo['REC_UID'] ?? '', 'CON_USER_ID' => $toInfo['CON_UID'] ?? '', 'DEC_AMOUNT' => $data['ORDER_AMOUNT'], 'DEC_PV' => $data['PAY_PV'], ]); // 给上追加业绩 $this->loopNetworkParentDo($data['USER_ID'], function ($parent) use (&$data) { // 给上级会员追加本期业绩到缓存中 PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [ 'PV_' . $parent['LOCATION'] . 'L' => $data['PAY_PV'], 'PV_' . $parent['LOCATION'] . 'L_TOUCH' => $data['PAY_PV'], 'PV_' . $parent['LOCATION'] . 'L_' . $data['ORDER_TYPE'] => $data['PAY_PV'], ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum); unset($parent); }); //给推荐关系累计增加业绩 $this->loopRelationParentDo($data['USER_ID'], function ($parent) use (&$data) { // 给上级会员追加本期业绩到缓存中 PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [ 'PV_PSS' => $data['PAY_PV'], ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum); unset($parent); }); // 写入业绩单表 $decInfo = PrepareCalcCache::getUserInfo($toInfo['DEC_ID'], $this->_periodNum); $sn = PerfOrderPrepare::generateSN(); $insertPerfOrderData[] = [ 'ID' => SnowFake::instance()->generateId(), 'SN' => $sn, 'DEC_SN' => $data['SN'], 'DEC_TYPE' => strtoupper($data['ORDER_TYPE']), 'DEC_STATUS' => PerfOrder::STATUS_NORMAL, 'USER_ID' => $data['USER_ID'], 'LAST_REC_USER_NAME' => $toInfo['REC_USER_NAME'], 'LAST_REC_REAL_NAME' => $toInfo['REC_REAL_NAME'], 'LAST_DEC_LV' => $toInfo['DEC_LV'], 'LAST_EMP_LV' => $toInfo['EMP_LV'], 'LAST_STATUS' => $toInfo['STATUS'], 'PV' => $data['PAY_PV'], 'DEC_AMOUNT' => $data['ORDER_AMOUNT'], 'LAST_SUB_COM_ID' => $toInfo['SUB_COM_ID'], 'LAST_PROVINCE' => $toInfo['PROVINCE'], 'LAST_CITY' => $toInfo['CITY'], 'LAST_COUNTY' => $toInfo['COUNTY'], 'DEC_USER_ID' => $toInfo['DEC_ID'], 'LAST_DEC_DEC_LV' => $decInfo['DEC_LV'], 'LAST_DEC_SUB_COM_ID' => $decInfo['SUB_COM_ID'], 'LAST_DEC_PROVINCE' => $decInfo['DEC_PROVINCE'], 'LAST_DEC_CITY' => $decInfo['DEC_CITY'], 'LAST_DEC_COUNTY' => $decInfo['DEC_COUNTY'], 'PERIOD_NUM' => $this->_periodNum, 'CALC_MONTH' => $this->_calcYearMonth, 'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH), 'CREATED_AT' => Date::nowTime(), 'CLOSED_AT' => 0, 'ORDER_CREATED_AT' => $data['CREATED_AT'] ]; unset($data, $decInfo, $sn, $toInfo); } PerfOrderPrepare::batchInsert($insertPerfOrderData); unset($insertPerfOrderData, $allData, $snArr); return $this->loopCalcPeriodPerfByOrderDec($offset + $this->_limit); } unset($allData); return true; } /** * 从会员的复销订单会员计算复销业绩并加入业绩单 * @param int $offset * @return bool * @throws \yii\db\Exception */ public function loopCalcPerfByFXOrder(int $offset = 0) { // 循环获取全部报单 $allData = Order::findUseDbCalc() ->select('ID,SN,DEC_SN,USER_ID,ORDER_TYPE,ORDER_AMOUNT,PAY_AMOUNT,PAY_PV,PAY_TYPE,PERIOD_NUM,STATUS,IS_DELETE, P_CALC_MONTH,CREATED_AT') ->where( "PERIOD_NUM=:PERIOD_NUM AND IS_DELETE=0 AND ORDER_TYPE=:ORDER_TYPE AND CREATED_AT<=:CREATED_AT", [':PERIOD_NUM' => $this->_periodNum, ':ORDER_TYPE'=>DeclarationForm::TYPE_FX,':CREATED_AT' => $this->_lastTime] ) ->orderBy('CREATED_AT DESC,ID DESC') ->offset($offset) ->limit($this->_limit) ->asArray() ->all(); if ($allData) { $insertPerfOrderData = []; foreach ($allData as $data) { // 是否关停等状态不能拿业绩 if (!$this->isHasPerf($data['USER_ID'])) { continue; } //如果支付方式是现金,那么实际业绩是支付PV的50% if( $data['PAY_TYPE'] === self::ORDER_PAY_TYPE_CASH ) { $orderCashAmount = $data['ORDER_AMOUNT']; //111期开始由50%改为60%-by 2020-04-30修改 $payPv = $data['PAY_PV'] * $this->_sysConfig['cashReconsumeBonusPercent']['VALUE'] / 100; $cacheDataKey = 'PV_PCS_FX_CASH'; }else { $orderCashAmount = 0; $payPv = $data['PAY_PV']; $cacheDataKey = 'PV_PCS_FX_POINT'; } if( $payPv <= 0 ) continue; // 给自己增加PCS(个人消费) PrepareCalcCache::nowPeriodPerf($data['USER_ID'], $this->_periodNum, [ 'FX_AMOUNT_CASH' => $orderCashAmount, 'PV_PCS' => $payPv, 'PV_PCS_FX' => $payPv, $cacheDataKey => $payPv, ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($data['USER_ID'], $this->_periodNum); // 给上追加业绩 try { $this->loopNetworkParentDo($data['USER_ID'], function ($parent) use (&$data, $payPv) { // 给上级会员追加本期业绩到缓存中 PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [ 'PV_' . $parent['LOCATION'] . 'L' => $payPv, 'PV_' . $parent['LOCATION'] . 'L_TOUCH' => $payPv, 'PV_' . $parent['LOCATION'] . 'L_FX' => $payPv, ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum); }); } catch(\Exception $e) { file_put_contents('loopNetworkParentDo_error.txt', var_export([ 'USER_ID' => $data['USER_ID'], '_periodNum' => $this->_periodNum, 'error' => $e->getMessage() ],true)); } //给推荐关系累计增加业绩 $this->loopRelationParentDo($data['USER_ID'], function ($parent) use ($data, $payPv) { // 给上级会员追加本期业绩到缓存中 PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [ 'PV_PSS' => $payPv, ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum); }); // } // 写入业绩单表 $baseInfo = PrepareCalcCache::getUserInfo($data['USER_ID'], $this->_periodNum); $sn = PerfOrderPrepare::generateSN(); $insertPerfOrderData[] = [ 'ID' => SnowFake::instance()->generateId(), 'SN' => $sn, 'DEC_SN' => null, 'DEC_TYPE' => 'FX', 'DEC_STATUS' => PerfOrder::STATUS_NORMAL, 'USER_ID' => $data['USER_ID'], 'LAST_REC_USER_NAME' => $baseInfo['REC_USER_NAME'], 'LAST_REC_REAL_NAME' => $baseInfo['REC_REAL_NAME'], 'LAST_DEC_LV' => $baseInfo['DEC_LV'], 'LAST_EMP_LV' => $baseInfo['EMP_LV'], 'LAST_STATUS' => $baseInfo['STATUS'], 'PV' => $payPv, 'DEC_AMOUNT' => $data['PAY_AMOUNT'], 'LAST_SUB_COM_ID' => $baseInfo['SUB_COM_ID'], 'LAST_PROVINCE' => $baseInfo['PROVINCE'], 'LAST_CITY' => $baseInfo['CITY'], 'LAST_COUNTY' => $baseInfo['COUNTY'], 'DEC_USER_ID' => $data['USER_ID'], 'LAST_DEC_DEC_LV' => $baseInfo['DEC_LV'], 'LAST_DEC_SUB_COM_ID' => $baseInfo['SUB_COM_ID'], 'LAST_DEC_PROVINCE' => $baseInfo['PROVINCE'], 'LAST_DEC_CITY' => $baseInfo['CITY'], 'LAST_DEC_COUNTY' => $baseInfo['COUNTY'], 'PERIOD_NUM' => $this->_periodNum, 'CALC_MONTH' => $this->_calcYearMonth, 'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH), 'CREATED_AT' => Date::nowTime(), 'CLOSED_AT' => 0, 'ORDER_CREATED_AT' => $data['CREATED_AT'] ]; unset($data, $baseInfo, $sn, $orderCashAmount, $payPv, $cacheDataKey); } PerfOrderPrepare::batchInsert($insertPerfOrderData); unset($insertPerfOrderData, $allData, $snArr); return $this->loopCalcPerfByFXOrder($offset + $this->_limit); } unset($allData); return true; } /** * 从会员的商城复销订单会员计算复销业绩并加入业绩单 * @param int $offset * @return bool * @throws \yii\db\Exception */ public function loopCalcPerfByShopFXOrder(int $offset = 0) { // 循环获取全部报单 $allData = OrderShop::findUseDbCalc() ->select( 'ID,SN,DEC_SN,USER_ID,ORDER_TYPE,ORDER_AMOUNT,PAY_AMOUNT,PAY_PV,PAY_TYPE,PERIOD_NUM,STATUS,IS_DELETE, P_CALC_MONTH,CREATED_AT') ->where( "PERIOD_NUM=:PERIOD_NUM AND IS_DELETE=0 AND ORDER_TYPE=:ORDER_TYPE AND CREATED_AT<=:CREATED_AT", [':PERIOD_NUM' => $this->_periodNum, ':ORDER_TYPE'=>DeclarationForm::TYPE_FX,':CREATED_AT' => $this->_lastTime] ) ->orderBy('CREATED_AT DESC,ID DESC') ->offset($offset) ->limit($this->_limit) ->asArray() ->all(); if ($allData) { $insertPerfOrderData = []; foreach ($allData as $data) { // 是否关停等状态不能拿业绩 if (!$this->isHasPerf($data['USER_ID'])) { continue; } //如果支付方式是现金,那么实际业绩是支付PV的50% if( $data['PAY_TYPE'] === self::ORDER_PAY_TYPE_CASH ) { $orderCashAmount = $data['ORDER_AMOUNT']; //111期开始由50%改为60%-by 2020-04-30修改 $payPv = $data['PAY_PV'] * $this->_sysConfig['cashReconsumeBonusPercent']['VALUE'] / 100; $cacheDataKey = 'PV_PCS_FX_CASH'; }else { $orderCashAmount = 0; $payPv = $data['PAY_PV']; $cacheDataKey = 'PV_PCS_FX_POINT'; } if( $payPv <= 0 ) continue; // 给自己增加PCS(个人消费) PrepareCalcCache::nowPeriodPerf($data['USER_ID'], $this->_periodNum, [ 'FX_AMOUNT_CASH' => $orderCashAmount, 'PV_PCS' => $payPv, 'PV_PCS_FX' => $payPv, $cacheDataKey => $payPv, ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($data['USER_ID'], $this->_periodNum); // 给上追加业绩 $this->loopNetworkParentDo($data['USER_ID'], function ($parent) use (&$data, $payPv) { // 给上级会员追加本期业绩到缓存中 PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [ 'PV_' . $parent['LOCATION'] . 'L' => $payPv, 'PV_' . $parent['LOCATION'] . 'L_TOUCH' => $payPv, 'PV_' . $parent['LOCATION'] . 'L_FX' => $payPv, ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum); }); //给推荐关系累计增加业绩 $this->loopRelationParentDo($data['USER_ID'], function ($parent) use ($data, $payPv) { // 给上级会员追加本期业绩到缓存中 PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [ 'PV_PSS' => $payPv, ]); // 把该会员加入到能拿到业绩的会员缓存中 PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum); }); // } // 写入业绩单表 $baseInfo = PrepareCalcCache::getUserInfo($data['USER_ID'], $this->_periodNum); $sn = PerfOrderPrepare::generateSN(); $insertPerfOrderData[] = [ 'ID' => SnowFake::instance()->generateId(), 'SN' => $sn, 'DEC_SN' => null, 'DEC_TYPE' => 'FX', 'DEC_STATUS' => PerfOrder::STATUS_NORMAL, 'USER_ID' => $data['USER_ID'], 'LAST_REC_USER_NAME' => $baseInfo['REC_USER_NAME'], 'LAST_REC_REAL_NAME' => $baseInfo['REC_REAL_NAME'], 'LAST_DEC_LV' => $baseInfo['DEC_LV'], 'LAST_EMP_LV' => $baseInfo['EMP_LV'], 'LAST_STATUS' => $baseInfo['STATUS'], 'PV' => $payPv, 'DEC_AMOUNT' => $data['PAY_AMOUNT'], 'LAST_SUB_COM_ID' => $baseInfo['SUB_COM_ID'], 'LAST_PROVINCE' => $baseInfo['PROVINCE'], 'LAST_CITY' => $baseInfo['CITY'], 'LAST_COUNTY' => $baseInfo['COUNTY'], 'DEC_USER_ID' => $data['USER_ID'], 'LAST_DEC_DEC_LV' => $baseInfo['DEC_LV'], 'LAST_DEC_SUB_COM_ID' => $baseInfo['SUB_COM_ID'], 'LAST_DEC_PROVINCE' => $baseInfo['PROVINCE'], 'LAST_DEC_CITY' => $baseInfo['CITY'], 'LAST_DEC_COUNTY' => $baseInfo['COUNTY'], 'PERIOD_NUM' => $this->_periodNum, 'CALC_MONTH' => $this->_calcYearMonth, 'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH), 'CREATED_AT' => Date::nowTime(), 'CLOSED_AT' => 0, 'ORDER_CREATED_AT' => $data['CREATED_AT'] ]; unset($data, $baseInfo, $sn, $orderCashAmount, $payPv, $cacheDataKey); } PerfOrderPrepare::batchInsert($insertPerfOrderData); unset($insertPerfOrderData, $allData, $snArr); return $this->loopCalcPerfByShopFXOrder($offset + $this->_limit); } unset($allData); return true; } /** * 计算月业绩表相关的数据并写入数据库 * @param int $offset * @return bool * @throws Exception * @throws \yii\db\Exception */ public function loopCalcMonthPerfTableData(int $offset = 0) { if (!$this->_isCalcMonth) { return true; } // AR_PERF_ORDER_PREPARE\AR_PERF_PERIOD_PREPARE\AR_PERIOD_PREPARE\AR_PERF_MONTH_PREPARE // AR_PERIOD_PREPARE 表只需要是结算月的数据 // AR_PERF_PERIOD_PREPARE 表特殊,需要增加一个字段,是否存在于前三期中 已被第一次算月业绩使用过了 // `IS_HAS_USER` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否有此用户,默认为0没有此用户1为有 // 如果依旧是0则再次循环此月业绩的时候,需要再次处理' 相当于前三期没有数据,需要单独再添加一次 // // 月业绩由perfperiod表加上perfperiodprepare表之和,其中perfperiod表数据为此月非计算月的期业绩数据 // 先查询perfperiod表的数据,再查询perfperiodprepare这个表的数据. // 如果查询到了perfperiodprepare的数据,则将此perfperiodprepare表的新增的是否已经在计算第一次统计到的字段标识为1. // 最后再循环 perfperiodprepare 表中标识依旧为0的数据,再次循环.相当于这些数据是此结算月业绩期的新增用户 echo sprintf("时间:[%s]月业绩,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset); // 从缓存列表里面从底层往上倒序获取会员 $allData = PerfPeriod::findUseDbCalc() ->select('USER_ID, SUM(FX_AMOUNT_CASH) AS FX_AMOUNT_CASH_SUM,SUM(PV_PCS) AS PV_PCS_SUM, SUM(PV_PCS_FX) AS PV_PCS_FX_SUM,SUM(PV_PSS) AS PV_PSS_SUM, SUM(PV_1L) AS PV_1L_SUM,SUM(PV_2L) AS PV_2L_SUM, SUM(PV_3L) AS PV_3L_SUM,SUM(PV_4L) AS PV_4L_SUM, SUM(PV_5L) AS PV_5L_SUM,SUM(PV_1L_ZC) AS PV_1L_ZC_SUM, SUM(PV_2L_ZC) AS PV_2L_ZC_SUM,SUM(PV_3L_ZC) AS PV_3L_ZC_SUM, SUM(PV_4L_ZC) AS PV_4L_ZC_SUM,SUM(PV_5L_ZC) AS PV_5L_ZC_SUM') ->where('CALC_MONTH=:CALC_MONTH AND PERIOD_NUM!=:PERIOD_NUM', [':CALC_MONTH' => $this->_calcYearMonth,':PERIOD_NUM'=>$this->_periodNum]) ->groupBy('USER_ID') ->orderBy('USER_ID DESC') ->offset($offset) ->limit($this->_limit) ->asArray() ->all(); if ($allData) { // 月度业绩表 foreach ($allData as $everyData) { $userId = $everyData['USER_ID']; //往期业绩 $userLastPerf = PrepareCalcCache::userPerf($userId, $this->_periodNum); //本期业绩 $periodPerf = PrepareCalcCache::nowPeriodPerf($userId, $this->_periodNum); $userBaseInfo = PrepareCalcCache::getUserInfo($userId, $this->_periodNum); // 查询月节点此期业绩,是否包含此用户 // 查询perfperiodprepare表中数据,是否有此用户信息.因为是月提前结算,所以此结算期是只有一个数据 $monthPrepare = PerfPeriodPrepare::findUseDbCalc() ->select('USER_ID, SUM(FX_AMOUNT_CASH) AS FX_AMOUNT_CASH_SUM,SUM(PV_PCS) AS PV_PCS_SUM, SUM(PV_PCS_FX) AS PV_PCS_FX_SUM,SUM(PV_PSS) AS PV_PSS_SUM, SUM(PV_1L) AS PV_1L_SUM,SUM(PV_2L) AS PV_2L_SUM, SUM(PV_3L) AS PV_3L_SUM,SUM(PV_4L) AS PV_4L_SUM, SUM(PV_5L) AS PV_5L_SUM,SUM(PV_1L_ZC) AS PV_1L_ZC_SUM, SUM(PV_2L_ZC) AS PV_2L_ZC_SUM,SUM(PV_3L_ZC) AS PV_3L_ZC_SUM, SUM(PV_4L_ZC) AS PV_4L_ZC_SUM,SUM(PV_5L_ZC) AS PV_5L_ZC_SUM') ->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM ', [':USER_ID' => $userId, ':PERIOD_NUM' => $this->_periodNum]) ->asArray() ->one(); if (!empty($monthPrepare)) { // 如果前三期中,在此提前计算业绩期中有数据,则需要加上此用户信息 $everyData['FX_AMOUNT_CASH_SUM'] = $everyData['FX_AMOUNT_CASH_SUM'] + $monthPrepare['FX_AMOUNT_CASH_SUM']; $everyData['PV_PCS_SUM'] = $everyData['PV_PCS_SUM'] + $monthPrepare['PV_PCS_SUM']; $everyData['PV_PCS_FX_SUM'] = $everyData['PV_PCS_FX_SUM'] + $monthPrepare['PV_PCS_FX_SUM']; $everyData['PV_PSS_SUM'] = $everyData['PV_PSS_SUM'] + $monthPrepare['PV_PSS_SUM']; $everyData['PV_1L_SUM'] = $everyData['PV_1L_SUM'] + $monthPrepare['PV_1L_SUM']; $everyData['PV_2L_SUM'] = $everyData['PV_2L_SUM'] + $monthPrepare['PV_2L_SUM']; $everyData['PV_3L_SUM'] = $everyData['PV_3L_SUM'] + $monthPrepare['PV_3L_SUM']; $everyData['PV_4L_SUM'] = $everyData['PV_4L_SUM'] + $monthPrepare['PV_4L_SUM']; $everyData['PV_5L_SUM'] = $everyData['PV_5L_SUM'] + $monthPrepare['PV_5L_SUM']; $everyData['PV_1L_ZC_SUM'] = $everyData['PV_1L_ZC_SUM'] + $monthPrepare['PV_1L_ZC_SUM']; $everyData['PV_2L_ZC_SUM'] = $everyData['PV_2L_ZC_SUM'] + $monthPrepare['PV_2L_ZC_SUM']; $everyData['PV_3L_ZC_SUM'] = $everyData['PV_3L_ZC_SUM'] + $monthPrepare['PV_3L_ZC_SUM']; $everyData['PV_4L_ZC_SUM'] = $everyData['PV_4L_ZC_SUM'] + $monthPrepare['PV_4L_ZC_SUM']; $everyData['PV_5L_ZC_SUM'] = $everyData['PV_5L_ZC_SUM'] + $monthPrepare['PV_5L_ZC_SUM']; // 将用户的状态改成1,为存在此用户.当之后再次循环PerfPeriodPrepare的时候,不再循环此用户了. PerfPeriodPrepare::updateAll( [ 'IS_HAS_USER' => 1 ], 'PERIOD_NUM=:PERIOD_NUM AND USER_ID=:USER_ID', [':PERIOD_NUM' => $this->_periodNum, ':USER_ID' => $userId] ); } $nowMonthPerf = [ 'USER_ID' => $userId, 'FX_AMOUNT_CASH' => $everyData['FX_AMOUNT_CASH_SUM'], 'PV_PCS' => $everyData['PV_PCS_SUM'], 'PV_PCS_FX' => $everyData['PV_PCS_FX_SUM'], 'PV_PSS' => $everyData['PV_PSS_SUM'], 'PV_1L' => $everyData['PV_1L_SUM'], 'PV_2L' => $everyData['PV_2L_SUM'], 'PV_3L' => $everyData['PV_3L_SUM'], 'PV_4L' => $everyData['PV_4L_SUM'], 'PV_5L' => $everyData['PV_5L_SUM'], //总数据,历史+本期。不能用上月加本月,因为上月可能没业绩,上上个月有业绩。 'PV_1L_TOTAL' => $periodPerf['PV_1L'] + $userLastPerf['PV_1L'], 'PV_2L_TOTAL' => $periodPerf['PV_2L'] + $userLastPerf['PV_2L'], 'PV_3L_TOTAL' => $periodPerf['PV_3L'] + $userLastPerf['PV_3L'], 'PV_4L_TOTAL' => $periodPerf['PV_4L'] + $userLastPerf['PV_4L'], 'PV_5L_TOTAL' => $periodPerf['PV_5L'] + $userLastPerf['PV_5L'], 'PV_PSS_TOTAL' => $periodPerf['PV_PSS'] + $userLastPerf['PV_PSS_TOTAL'], ]; // 把会员的月业绩写入缓存中,以便下面的奖金计算从缓冲中获取数据效率高 PrepareCalcCache::addHasMonthPerfUsers($userId, $this->_periodNum); PrepareCalcCache::nowMonthPerf($userId, $this->_periodNum, $nowMonthPerf); unset($userId, $everyData, $nowMonthPerf, $lastMonthData, $userBaseInfo); } unset($allData); return $this->loopCalcMonthPerfTableData($offset + $this->_limit); } unset($allData); return true; } /** * 预计计算月业绩,当前三期没有此最新业绩单的用户 * 再次添加进去 * @param int $offset * @return bool * @throws Exception * @throws \yii\db\Exception */ public function loopCalcMonthPerfTableDataPrepare(int $offset = 0) { if (!$this->_isCalcMonth) { return true; } // 上面的计算月业绩,计算了前三期有的用户,此次只计算此结算周期未含有前三期业绩的用户 echo sprintf("时间:[%s]预计月业绩,结算月新添加的用户,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset); // 从缓存列表里面从底层往上倒序获取会员 IS_HAS_USER 0 代表是此结算周期新增的业绩 $allData = PerfPeriodPrepare::findUseDbCalc() ->select('IS_HAS_USER,USER_ID, SUM(FX_AMOUNT_CASH) AS FX_AMOUNT_CASH_SUM,SUM(PV_PCS) AS PV_PCS_SUM, SUM(PV_PCS_FX) AS PV_PCS_FX_SUM,SUM(PV_PSS) AS PV_PSS_SUM, SUM(PV_1L) AS PV_1L_SUM,SUM(PV_2L) AS PV_2L_SUM, SUM(PV_3L) AS PV_3L_SUM,SUM(PV_4L) AS PV_4L_SUM, SUM(PV_5L) AS PV_5L_SUM,SUM(PV_1L_ZC) AS PV_1L_ZC_SUM, SUM(PV_2L_ZC) AS PV_2L_ZC_SUM,SUM(PV_3L_ZC) AS PV_3L_ZC_SUM, SUM(PV_4L_ZC) AS PV_4L_ZC_SUM,SUM(PV_5L_ZC) AS PV_5L_ZC_SUM') ->where('CALC_MONTH=:CALC_MONTH', [':CALC_MONTH' => $this->_calcYearMonth]) ->groupBy('USER_ID') ->orderBy('USER_ID DESC') ->offset($offset) ->limit($this->_limit) ->asArray() ->all(); if ($allData) { // 月度业绩表 foreach ($allData as $everyData) { if ($everyData['IS_HAS_USER'] != 0) { continue; } $userId = $everyData['USER_ID']; //往期业绩 $userLastPerf = PrepareCalcCache::userPerf($userId, $this->_periodNum); //本期业绩 $periodPerf = PrepareCalcCache::nowPeriodPerf($userId, $this->_periodNum); $userBaseInfo = PrepareCalcCache::getUserInfo($userId, $this->_periodNum); $nowMonthPerf = [ 'USER_ID' => $userId, 'FX_AMOUNT_CASH' => $everyData['FX_AMOUNT_CASH_SUM'], 'PV_PCS' => $everyData['PV_PCS_SUM'], 'PV_PCS_FX' => $everyData['PV_PCS_FX_SUM'], 'PV_PSS' => $everyData['PV_PSS_SUM'], 'PV_1L' => $everyData['PV_1L_SUM'], 'PV_2L' => $everyData['PV_2L_SUM'], 'PV_3L' => $everyData['PV_3L_SUM'], 'PV_4L' => $everyData['PV_4L_SUM'], 'PV_5L' => $everyData['PV_5L_SUM'], //总数据,历史+本期。不能用上月加本月,因为上月可能没业绩,上上个月有业绩。 'PV_1L_TOTAL' => $periodPerf['PV_1L'] + $userLastPerf['PV_1L'], 'PV_2L_TOTAL' => $periodPerf['PV_2L'] + $userLastPerf['PV_2L'], 'PV_3L_TOTAL' => $periodPerf['PV_3L'] + $userLastPerf['PV_3L'], 'PV_4L_TOTAL' => $periodPerf['PV_4L'] + $userLastPerf['PV_4L'], 'PV_5L_TOTAL' => $periodPerf['PV_5L'] + $userLastPerf['PV_5L'], 'PV_PSS_TOTAL' => $periodPerf['PV_PSS'] + $userLastPerf['PV_PSS_TOTAL'], ]; // 把会员的月业绩写入缓存中,以便下面的奖金计算从缓冲中获取数据效率高 PrepareCalcCache::addHasMonthPerfUsers($userId, $this->_periodNum); PrepareCalcCache::nowMonthPerf($userId, $this->_periodNum, $nowMonthPerf); // 将用户的状态改成1,为存在此用户.当之后再次循环PerfPeriodPrepare的时候,不再循环此用户了. PerfPeriodPrepare::updateAll( [ 'IS_HAS_USER' => 1 ], 'PERIOD_NUM=:PERIOD_NUM AND USER_ID=:USER_ID', [':PERIOD_NUM' => $this->_periodNum, ':USER_ID' => $userId] ); unset($userId, $everyData, $nowMonthPerf, $lastMonthData, $userBaseInfo); } unset($allData); return $this->loopCalcMonthPerfTableDataPrepare($offset + $this->_limit); } unset($allData); return true; } /** * 循环有业绩会员,并入库 * @param int $offset * @return bool * @throws \yii\db\Exception */ public function loopWriteNowPerf($offset = 0) { echo sprintf("时间:[%s]缓存本期业绩数据入库,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset); // 从缓存列表里面从底层往上倒序获取会员 $allData = PrepareCalcCache::getHasPerfUsers($this->_periodNum, $offset, $this->_limit); if($allData){ $insertDataPeriodPerf = []; foreach($allData as $userId){ $insertDataPeriodPerf[] = $this->nowPeriodPerfData($userId); unset($userId); } PerfPeriodPrepare::batchInsert($insertDataPeriodPerf); unset($insertDataPeriodPerf, $allData); return $this->loopWriteNowPerf($offset + $this->_limit); } unset($allData); return true; } /** * 循环有月业绩会员,并入库 * @param int $offset * @return bool * @throws \yii\db\Exception */ public function loopWriteMonthPerf($offset = 0) { if(!$this->_isCalcMonth){ return true; } echo sprintf("时间:[%s]缓存本月业绩数据入库,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset); // 从缓存列表里面从底层往上倒序获取会员 $allData = PrepareCalcCache::getHasMonthPerfUsers($this->_periodNum, $offset, $this->_limit); if($allData){ $insertDataMonthPerf = []; foreach($allData as $userId){ $insertDataMonthPerf[] = $this->nowMonthPerfData($userId); unset($userId); } // 月预计计算业绩插入数据 PerfMonthPrepare::batchInsert($insertDataMonthPerf); unset($insertDataMonthPerf, $allData); return $this->loopWriteMonthPerf($offset + $this->_limit); } unset($allData); return true; } /** * 本期业绩数据 * @param $userId * @return array */ public function nowPeriodPerfData($userId){ $data = PrepareCalcCache::nowPeriodPerf($userId, $this->_periodNum); $baseInfo = PrepareCalcCache::getUserInfo($userId, $this->_periodNum); $result = [ 'ID' => SnowFake::instance()->generateId(), 'USER_ID' => $userId, 'LAST_DEC_LV' => $baseInfo['DEC_LV'], 'LAST_EMP_LV' => $baseInfo['EMP_LV'], 'LAST_STATUS' => $baseInfo['STATUS'], 'FX_AMOUNT_CASH' => $data['FX_AMOUNT_CASH'], 'PV_PCS' => $data['PV_PCS'], 'PV_PSS' => $data['PV_PSS'], 'PV_PCS_ZC' => $data['PV_PCS_ZC'], 'PV_PCS_YH' => $data['PV_PCS_YH'], 'PV_PCS_ZG' => $data['PV_PCS_ZG'], 'PV_PCS_LS' => $data['PV_PCS_LS'], 'PV_PCS_FX' => $data['PV_PCS_FX'], 'PV_PCS_FX_CASH' => $data['PV_PCS_FX_CASH'], 'PV_PCS_FX_POINT' => $data['PV_PCS_FX_POINT'], 'PV_1L' => $data['PV_1L'], 'PV_1L_TOUCH' => $data['PV_1L_TOUCH'], 'PV_1L_ZC' => $data['PV_1L_ZC'], 'PV_1L_YH' => $data['PV_1L_YH'], 'PV_1L_ZG' => $data['PV_1L_ZG'], 'PV_1L_LS' => $data['PV_1L_LS'], 'PV_1L_FX' => $data['PV_1L_FX'], 'PV_2L' => $data['PV_2L'], 'PV_2L_TOUCH' => $data['PV_2L_TOUCH'], 'PV_2L_ZC' => $data['PV_2L_ZC'], 'PV_2L_YH' => $data['PV_2L_YH'], 'PV_2L_ZG' => $data['PV_2L_ZG'], 'PV_2L_LS' => $data['PV_2L_LS'], 'PV_2L_FX' => $data['PV_2L_FX'], 'PV_3L' => $data['PV_3L'], 'PV_3L_TOUCH' => $data['PV_3L_TOUCH'], 'PV_3L_ZC' => $data['PV_3L_ZC'], 'PV_3L_YH' => $data['PV_3L_YH'], 'PV_3L_ZG' => $data['PV_3L_ZG'], 'PV_3L_LS' => $data['PV_3L_LS'], 'PV_3L_FX' => $data['PV_3L_FX'], 'PV_4L' => $data['PV_4L'], 'PV_4L_TOUCH' => $data['PV_4L_TOUCH'], 'PV_4L_ZC' => $data['PV_4L_ZC'], 'PV_4L_YH' => $data['PV_4L_YH'], 'PV_4L_ZG' => $data['PV_4L_ZG'], 'PV_4L_LS' => $data['PV_4L_LS'], 'PV_4L_FX' => $data['PV_4L_FX'], 'PV_5L' => $data['PV_5L'], 'PV_5L_TOUCH' => $data['PV_5L_TOUCH'], 'PV_5L_ZC' => $data['PV_5L_ZC'], 'PV_5L_YH' => $data['PV_5L_YH'], 'PV_5L_ZG' => $data['PV_5L_ZG'], 'PV_5L_LS' => $data['PV_5L_LS'], 'PV_5L_FX' => $data['PV_5L_FX'], 'PV_LS_TOUCH' => $data['PV_LS_TOUCH'], 'SURPLUS_1L' => $data['SURPLUS_1L'], 'SURPLUS_2L' => $data['SURPLUS_2L'], 'SURPLUS_3L' => $data['SURPLUS_3L'], 'SURPLUS_4L' => $data['SURPLUS_4L'], 'SURPLUS_5L' => $data['SURPLUS_5L'], 'SURPLUS_LS' => $data['SURPLUS_LS'], 'PERIOD_NUM' => $this->_periodNum, 'CALC_MONTH' => $this->_calcYearMonth, 'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH), 'CREATED_AT' => Date::nowTime(), ]; unset($data); return $result; } /** * 本月业绩 * @param $userId * @return array */ public function nowMonthPerfData($userId){ $data = PrepareCalcCache::nowMonthPerf($userId, $this->_periodNum); $baseInfo = PrepareCalcCache::getUserInfo($userId, $this->_periodNum); $result = [ 'ID' => SnowFake::instance()->generateId(), 'USER_ID' => $userId, 'LAST_DEC_LV' => $baseInfo['DEC_LV'], 'LAST_EMP_LV' => $data['EMP_LEVEL'], 'LAST_STATUS' => $baseInfo['STATUS'], 'FX_AMOUNT_CASH' => $data['FX_AMOUNT_CASH'], 'PV_PCS' => $data['PV_PCS'], 'PV_PCS_FX' => $data['PV_PCS_FX'], 'PV_PSS' => $data['PV_PSS'], 'PV_1L' => $data['PV_1L'], 'PV_2L' => $data['PV_2L'], 'PV_3L' => $data['PV_3L'], 'PV_4L' => $data['PV_4L'], 'PV_5L' => $data['PV_5L'], 'VIP_PV_1L_ZC' => $data['VIP_PV_1L_ZC'], 'VIP_PV_2L_ZC' => $data['VIP_PV_2L_ZC'], 'VIP_PV_3L_ZC' => $data['VIP_PV_3L_ZC'], 'VIP_PV_4L_ZC' => $data['VIP_PV_4L_ZC'], 'VIP_PV_5L_ZC' => $data['VIP_PV_5L_ZC'], 'PV_1L_TOTAL' => $data['PV_1L_TOTAL'], 'PV_2L_TOTAL' => $data['PV_2L_TOTAL'], 'PV_3L_TOTAL' => $data['PV_3L_TOTAL'], 'PV_4L_TOTAL' => $data['PV_4L_TOTAL'], 'PV_5L_TOTAL' => $data['PV_5L_TOTAL'], 'PV_PSS_TOTAL' => $data['PV_PSS_TOTAL'], 'CF_PERCENT' => $data['CF_PERCENT'], 'LX_PERCENT' => $data['LX_PERCENT'], 'FX_STATUS' => $data['FX_STATUS'], 'CALC_MONTH' => $this->_calcYearMonth, 'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH), 'CREATED_AT' => Date::nowTime(), ]; unset($data); return $result; } /** * 循环父级并执行回调函数 * @param $userId * @param callable $callbackFunc * @param int $offset * @return bool */ public function loopNetworkParentDo($userId, callable $callbackFunc, int $offset = 0) { $allParents = Cache::getAllNetworkParents($userId, true); $allData = array_slice($allParents, $offset, $this->_limit); unset($allParents); if ($allData) { foreach ($allData as $data) { $funcResult = $callbackFunc($data); if ($funcResult === self::LOOP_FINISH) { return true; } elseif ($funcResult === self::LOOP_CONTINUE) { continue; } unset($data, $funcResult); } unset($allData); return $this->loopNetworkParentDo($userId, $callbackFunc, $offset + $this->_limit); } return true; } /** * 循环推荐网络的父级 * @param $userId * @param callable $callbackFunc * @param int $offset * @return bool */ public function loopRelationParentDo($userId, callable $callbackFunc, int $offset = 0) { $allParents = Cache::getAllRelationParents($userId,true); $allData = array_slice($allParents, $offset, $this->_limit); unset($allParents); if ($allData) { foreach ($allData as $data) { $funcResult = $callbackFunc($data); if ($funcResult === self::LOOP_FINISH) { return true; } elseif ($funcResult === self::LOOP_CONTINUE) { continue; } unset($data, $funcResult); } unset($allData); return $this->loopRelationParentDo($userId, $callbackFunc, $offset + $this->_limit); } return true; } /** * 是否可拿业绩(即注销、关停、停发状态) * @param $userId * @return bool */ public function isHasPerf($userId) { //@todo 所有人都有业绩 return true; } /** * 更新百分比并发送 * @param $percent */ private function _updatePercent($percent) { // 把数据写入数据库中 PeriodPrepare::updateAll(['PERF_PERCENT' => $percent], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]); } }