CalcServePerfCalc.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. <?php
  2. /**
  3. */
  4. namespace common\helpers\bonus;
  5. use common\helpers\Cache;
  6. use common\helpers\Date;
  7. use common\helpers\snowflake\SnowFake;
  8. use common\models\PerfOrder;
  9. use common\models\PerfPeriod;
  10. use common\models\Period;
  11. use common\models\PerfMonth;
  12. use common\models\ServeProcess;
  13. use common\models\UserNetwork;
  14. use yii\base\Exception;
  15. use yii\base\StaticInstanceTrait;
  16. class CalcServePerfCalc {
  17. use StaticInstanceTrait;
  18. private $_limit = 3000;
  19. private $_companyMonthPerf = 0;
  20. private $_cfTotalPercent = 0;
  21. private $_lxTotalPercent = 0;
  22. private $_sysConfig = [];
  23. private $_decLevelConfig = [];
  24. private $_empLevelConfig = [];
  25. private $_decRoleConfig = [];
  26. private $_periodNum = 0;
  27. private $_isCalcMonth = 0;
  28. private $_calcYear;
  29. private $_calcMonth;
  30. private $_calcYearMonth;
  31. private $_lastCalcYear;
  32. private $_lastCalcMonth;
  33. private $_lastCalcYearMonth;
  34. private $_lastPeriodNum;
  35. private $_periodObj;
  36. const LOOP_FINISH = 1;
  37. const LOOP_CONTINUE = 2;
  38. const ORDER_PAY_TYPE_CASH = 'cash';
  39. const ORDER_PAY_TYPE_STACK = 'pay_stack'; // pay_stack支付方式
  40. /**
  41. * 获取期数
  42. * @return int
  43. */
  44. public function getPeriodNum() {
  45. return $this->_periodNum;
  46. }
  47. // 校验是否可进行计算
  48. public function isCalcIng($periodNum) {
  49. $periodObj = Period::instance();
  50. $periodDataArr = $periodObj->setPeriodNum($periodNum);
  51. if (empty($periodDataArr)) {
  52. return false;
  53. }
  54. if ($periodDataArr['IS_PREPARE'] != 1) {
  55. return false;
  56. }
  57. $this->_periodNum = $periodDataArr['PERIOD_NUM'];
  58. $this->_periodObj = $periodObj;
  59. return true;
  60. }
  61. /**
  62. * 累计业绩数据
  63. * @param $periodNum
  64. * @return bool
  65. */
  66. public function calcStep($periodNum = null) {
  67. try {
  68. $requestTime = time();
  69. // if (empty($periodNum)) {
  70. // echo('触发时间:【'.$requestTime.'】'.'定时器执行累计业绩计算 ,内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
  71. // } else {
  72. // echo('触发时间:【'.$requestTime.'】'.'手动触发累计业绩计算 ,内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
  73. // }
  74. //一、查询此业绩状态,是否能进行计算
  75. $calcIng = $this->isCalcIng($periodNum);
  76. ServeProcess::recordRequest($requestTime, $this->_periodNum, '', true);
  77. if ($calcIng !== true) {
  78. //echo('触发时间:【'.date('Y-m-d H:i:s', time()).'】'.'业绩期表中,此期状态不正确');
  79. //ServeProcess::recordRequest($requestTime, $this->_periodNum, '业绩期表中,此期状态不正确');
  80. return false;
  81. } else {
  82. // 将IS_PREPARE改成2,计算中
  83. Period::updateCalcProcess(2, $this->_periodNum);
  84. ServeProcess::recordRequest($requestTime, $this->_periodNum, '调整IS_PREPARE值为2,计算开始');
  85. }
  86. // 记录初始化数据,用户总数,业绩单业绩总pv值.
  87. ServeProcess::recordDataInfo(time(), $this->_periodNum);
  88. $t1 = microtime(true);
  89. //二、初始化
  90. $this->initCalcTask();
  91. echo '业绩期为:'.$this->_periodNum;
  92. Period::updatePercent(10, $this->_periodNum);
  93. ServeProcess::recordProcess($t1, time(), $this->_periodNum, '初始化---初始化配置');
  94. $initT2 = microtime(true);
  95. //三、 设置结算状态
  96. $this->setCalcStatus('start', $this->_periodNum);
  97. ServeProcess::recordProcess($initT2, time(), $this->_periodNum, '初始化---设置结算状态');
  98. $initT3 = microtime(true);
  99. //四、 清空所有本期结算用到的缓存
  100. CalcCache::clearAll($this->_periodNum);
  101. ServeProcess::recordProcess($initT3, time(), $this->_periodNum, '初始化---清空业绩缓存');
  102. $initT4 = microtime(true);
  103. //五、 清空会员推荐和接点关系缓存
  104. CalcCache::clearNetCache();
  105. ServeProcess::recordProcess($initT4, time(), $this->_periodNum, '初始化---清空会员推荐和接点关系缓存');
  106. $initT5 = microtime(true);
  107. //六、 清空相关表数据
  108. $this->clearTableData();
  109. $this->_updatePercent(15);
  110. ServeProcess::recordProcess($initT5, time(), $this->_periodNum, '初始化---清空相关表数据');
  111. $t2 = microtime(true);
  112. echo(date('Y-m-d H:i:s',time()).'初始化、清空缓存及相关数据表完成,耗时:' . round($t2 - $t1, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
  113. ServeProcess::recordProcess($t1, $t2, $this->_periodNum, '初始化---初始化、清空缓存及相关数据表完成');
  114. //七、 添加缓存中用户数据
  115. CalcCache::addUsers($this->_periodNum);
  116. $t3 = microtime(true);
  117. echo(date('Y-m-d H:i:s',time()).'计算业绩向缓存中加入用户完成,耗时:' . round($t3 - $t2, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
  118. ServeProcess::recordProcess($t2, $t3, $this->_periodNum, '计算业绩向缓存中加入用户完成');
  119. $this->_updatePercent(20);
  120. // 八、循环累计用户各项业绩数据
  121. $this->loopGrandPerf();
  122. $t4 = microtime(true);
  123. echo(date('Y-m-d H:i:s',time()).'累计用户业绩完成' . round($t4 - $t3, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
  124. ServeProcess::recordProcess($t3, $t4, $this->_periodNum, '累计用户业绩完成');
  125. $this->_updatePercent(60);
  126. // 九、本期业绩入库
  127. $this->loopWriteNowPerf();
  128. $t6 = microtime(true);
  129. echo(date('Y-m-d H:i:s',time()).'本期业绩入库完成,耗时:' . round($t6 - $t4, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
  130. ServeProcess::recordProcess($t4, $t6, $this->_periodNum, '本期业绩入库完成');
  131. $this->_updatePercent(70);
  132. //十、计算月业绩表中的数据
  133. $this->loopCalcMonthPerfTableData();
  134. $t7 = microtime(true);
  135. echo(date('Y-m-d H:i:s',time()).'计算月业绩表中的数据完成,耗时:' . round($t7 - $t6, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
  136. if($this->_isCalcMonth) {
  137. ServeProcess::recordProcess($t6, $t7, $this->_periodNum, '计算月业绩表中的数据完成');
  138. }
  139. $this->_updatePercent(80);
  140. //十一、本月业绩入库
  141. $this->loopWriteMonthPerf();
  142. $t8 = microtime(true);
  143. echo(date('Y-m-d H:i:s',time()).'本月业绩入库完成,耗时:' . round($t8 - $t7, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
  144. if($this->_isCalcMonth) {
  145. ServeProcess::recordProcess($t7, $t8, $this->_periodNum, '本月业绩入库完成');
  146. }
  147. $this->_updatePercent(100);
  148. $t9 = microtime(true);
  149. ServeProcess::recordProcess($t6, $t7, $this->_periodNum, '计算业绩业绩结算全部完成');
  150. echo(date('Y-m-d H:i:s',time()).'计算业绩业绩结算全部完成,共耗时:' . round($t9 - $t1, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
  151. } catch (\Exception $e) {
  152. $this->errorCalcTask();
  153. var_dump($e->getMessage());
  154. return false;
  155. }
  156. $this->endCalcTask();
  157. return true;
  158. }
  159. /**
  160. * 结算完成
  161. * @return bool
  162. */
  163. public function endCalcTask() {
  164. // 更新结算状态
  165. $this->setCalcStatus('end');
  166. }
  167. /**
  168. * 结算错误
  169. */
  170. public function errorCalcTask() {
  171. // 清空所有本期结算用到的缓存
  172. CalcCache::clearAll($this->_periodNum);
  173. // 更新结算状态
  174. $this->setCalcStatus('fail');
  175. }
  176. /**
  177. * 设置生成业绩单状态
  178. * @param $type
  179. * start|end|fail
  180. */
  181. public function setCalcStatus($type, $periodNum = null) {
  182. if ($type == 'start') {
  183. Period::updateAll(['IS_PERFING' => 1, 'IS_PERFED' => Period::PERF_NONE, 'PERF_STARTED_AT' => Date::nowTime()], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
  184. } elseif ($type == 'end') {
  185. Period::updateAll(['IS_PERFING' => 0, 'IS_PERFED' => Period::PERF_FINISH, 'PERFED_AT' => Date::nowTime()], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
  186. } elseif ($type == 'fail') {
  187. Period::updateAll(['IS_PERFING' => 0, 'IS_PERFED' => Period::PERF_FAIL, 'PERFED_AT' => 0], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
  188. }
  189. }
  190. /**
  191. * 初始化结算任务
  192. * @throws \yii\db\Exception
  193. */
  194. public function initCalcTask() {
  195. try {
  196. $periodObj = Period::instance();
  197. $this->_sysConfig = Cache::getSystemConfig();
  198. $this->_decLevelConfig = Cache::getDecLevelConfig();
  199. $this->_empLevelConfig = Cache::getEmpLevelConfig();
  200. $this->_decRoleConfig = CalcCache::getDecRoleConfig($this->_periodNum);
  201. $this->_isCalcMonth = $periodObj->isCalcMonth($this->_periodNum);
  202. $this->_calcYear = $periodObj->getYear($this->_periodNum);
  203. $this->_calcMonth = $periodObj->getMonth($this->_periodNum);
  204. $this->_calcYearMonth = $periodObj->getYearMonth($this->_periodNum);
  205. } catch(Exception $e) {
  206. var_dump($e->getMessage());
  207. }
  208. }
  209. /**
  210. * 清空相关表数据
  211. */
  212. public function clearTableData() {
  213. PerfPeriod::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);// 周业绩
  214. if ($this->_isCalcMonth) {
  215. PerfMonth::pageDeleteAll("CALC_MONTH='{$this->_calcYearMonth}'");// 月业绩表
  216. }
  217. }
  218. /**
  219. * 累计用户业绩
  220. * @param int $offset
  221. * @return bool
  222. * @throws \yii\db\Exception
  223. */
  224. public function loopGrandPerf($offset = 0) {
  225. $allData = PerfOrder::findUseDbCalc()
  226. ->select('ORDER_AMOUNT,DEC_TYPE,USER_ID,PV,PERIOD_NUM,DEC_USER_ID,PAY_TYPE')
  227. ->where(
  228. "PERIOD_NUM=:PERIOD_NUM",
  229. [':PERIOD_NUM' => $this->_periodNum]
  230. )
  231. ->orderBy('CREATED_AT DESC,ID DESC')
  232. ->offset($offset)
  233. ->limit($this->_limit)
  234. ->asArray()
  235. ->all();
  236. if (!empty($allData)) {
  237. foreach ($allData as $data) {
  238. // 循环累计报单业绩
  239. try{
  240. echo "开始累计用户业绩,用户ID为:".$data['USER_ID'].PHP_EOL;
  241. if ($data['DEC_TYPE'] == PerfOrder::ZC_TYPE) {
  242. // 给自己增加PCS(个人消费)
  243. CalcCache::nowPeriodPerf($data['USER_ID'], $this->_periodNum, [
  244. 'PV_PCS' => $data['PV'],
  245. 'PV_PCS_ZC' => $data['PV'],
  246. ]);
  247. // 把该会员加入到能拿到业绩的会员缓存中
  248. CalcCache::addHasPerfUsers($data['USER_ID'], $this->_periodNum);
  249. //加入到报单会员中
  250. $toInfo = CalcCache::getUserInfo($data['USER_ID'], $this->_periodNum);
  251. CalcCache::addHasBDUsers($data['USER_ID'], $this->_periodNum, [
  252. 'TO_USER_ID' => $data['USER_ID'],
  253. 'USER_ID' => $toInfo['DEC_ID'],
  254. 'DEC_ID' => $toInfo['DEC_ID'],
  255. //考虑可能会移网的情况
  256. 'REC_USER_ID' => $toInfo['REC_UID'] ?? '',
  257. 'CON_USER_ID' => $toInfo['CON_UID'] ?? '',
  258. 'DEC_AMOUNT' => $data['ORDER_AMOUNT'],
  259. 'DEC_PV' => $data['PV'],
  260. ]);
  261. // 给上追加业绩
  262. $this->loopNetworkParentDo($data['USER_ID'], function ($parent) use (&$data) {
  263. // 给上级会员追加本期业绩到缓存中
  264. CalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
  265. 'PV_' . $parent['LOCATION'] . 'L' => $data['PV'],
  266. 'PV_' . $parent['LOCATION'] . 'L_TOUCH' => $data['PV'],
  267. 'PV_' . $parent['LOCATION'] . 'L_' . $data['DEC_TYPE'] => $data['PV'],
  268. ]);
  269. // 把该会员加入到能拿到业绩的会员缓存中
  270. CalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
  271. unset($parent);
  272. });
  273. //给推荐关系累计增加业绩
  274. $this->loopRelationParentDo($data['USER_ID'], function ($parent) use (&$data) {
  275. // 给上级会员追加本期业绩到缓存中
  276. CalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
  277. 'PV_PSS' => $data['PV'],
  278. ]);
  279. // 把该会员加入到能拿到业绩的会员缓存中
  280. CalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
  281. unset($parent);
  282. });
  283. }
  284. } catch(Exception $e) {
  285. var_dump(__LINE__,__FILE__,$e->getMessage(), $data);
  286. }
  287. // 循环累计复消业绩
  288. try{
  289. if ($data['DEC_TYPE'] == PerfOrder::FX_TYPE) {
  290. if( $data['PAY_TYPE'] === self::ORDER_PAY_TYPE_CASH || $data['PAY_TYPE'] === self::ORDER_PAY_TYPE_STACK) {
  291. $orderCashAmount = $data['ORDER_AMOUNT'];
  292. $payPv = $data['PV'] * $this->_sysConfig['cashReconsumeBonusPercent']['VALUE'] / 100;
  293. $cacheDataKey = 'PV_PCS_FX_CASH';
  294. } else {
  295. $orderCashAmount = 0;
  296. $payPv = $data['PV'];
  297. $cacheDataKey = 'PV_PCS_FX_POINT';
  298. }
  299. if( $payPv <= 0 ) continue;
  300. // 给自己增加PCS(个人消费)
  301. CalcCache::nowPeriodPerf($data['USER_ID'], $this->_periodNum, [
  302. 'FX_AMOUNT_CASH' => $orderCashAmount,
  303. 'PV_PCS' => $payPv,
  304. 'PV_PCS_FX' => $payPv,
  305. $cacheDataKey => $payPv,
  306. ]);
  307. // 把该会员加入到能拿到业绩的会员缓存中
  308. CalcCache::addHasPerfUsers($data['USER_ID'], $this->_periodNum);
  309. // 给上追加业绩
  310. $this->loopNetworkParentDo($data['USER_ID'], function ($parent) use (&$data, $payPv) {
  311. // 给上级会员追加本期业绩到缓存中
  312. CalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
  313. 'PV_' . $parent['LOCATION'] . 'L' => $payPv,
  314. 'PV_' . $parent['LOCATION'] . 'L_TOUCH' => $payPv,
  315. 'PV_' . $parent['LOCATION'] . 'L_FX' => $payPv,
  316. ]);
  317. // 把该会员加入到能拿到业绩的会员缓存中
  318. CalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
  319. });
  320. //给推荐关系累计增加业绩
  321. $this->loopRelationParentDo($data['USER_ID'], function ($parent) use ($data, $payPv) {
  322. // 给上级会员追加本期业绩到缓存中
  323. CalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
  324. 'PV_PSS' => $payPv,
  325. ]);
  326. // 把该会员加入到能拿到业绩的会员缓存中
  327. CalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
  328. });
  329. }
  330. }catch(Exception $e) {
  331. var_dump(__LINE__,__FILE__,$e->getMessage(), $data);
  332. }
  333. }
  334. return $this->loopGrandPerf($offset + $this->_limit);
  335. }
  336. unset($allData);
  337. return true;
  338. }
  339. /**
  340. * 计算月业绩表相关的数据并写入数据库
  341. * @param int $offset
  342. * @return bool
  343. * @throws Exception
  344. * @throws \yii\db\Exception
  345. */
  346. public function loopCalcMonthPerfTableData(int $offset = 0) {
  347. if (!$this->_isCalcMonth) {
  348. return true;
  349. }
  350. echo sprintf("时间:[%s]月业绩,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
  351. $allData = PerfPeriod::findUseDbCalc()
  352. ->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,
  353. 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,
  354. 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,
  355. 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')
  356. ->where('CALC_MONTH=:CALC_MONTH', [':CALC_MONTH' => $this->_calcYearMonth])
  357. ->groupBy('USER_ID')
  358. ->orderBy('USER_ID DESC')
  359. ->offset($offset)
  360. ->limit($this->_limit)
  361. ->asArray()
  362. ->all();
  363. if ($allData) {
  364. // 月度业绩表
  365. foreach ($allData as $everyData) {
  366. $userId = $everyData['USER_ID'];
  367. //往期业绩
  368. $userLastPerf = CalcCache::userPerf($userId, $this->_periodNum);
  369. //本期业绩
  370. $periodPerf = CalcCache::nowPeriodPerf($userId, $this->_periodNum);
  371. $userBaseInfo = CalcCache::getUserInfo($userId, $this->_periodNum);
  372. $nowMonthPerf = [
  373. 'USER_ID' => $userId,
  374. 'FX_AMOUNT_CASH' => $everyData['FX_AMOUNT_CASH_SUM'],
  375. 'PV_PCS' => $everyData['PV_PCS_SUM'],
  376. 'PV_PCS_FX' => $everyData['PV_PCS_FX_SUM'],
  377. 'PV_PSS' => $everyData['PV_PSS_SUM'],
  378. 'PV_1L' => $everyData['PV_1L_SUM'],
  379. 'PV_2L' => $everyData['PV_2L_SUM'],
  380. 'PV_3L' => $everyData['PV_3L_SUM'],
  381. 'PV_4L' => $everyData['PV_4L_SUM'],
  382. 'PV_5L' => $everyData['PV_5L_SUM'],
  383. //总数据,历史+本期。不能用上月加本月,因为上月可能没业绩,上上个月有业绩。
  384. 'PV_1L_TOTAL' => $periodPerf['PV_1L'] + $userLastPerf['PV_1L'],
  385. 'PV_2L_TOTAL' => $periodPerf['PV_2L'] + $userLastPerf['PV_2L'],
  386. 'PV_3L_TOTAL' => $periodPerf['PV_3L'] + $userLastPerf['PV_3L'],
  387. 'PV_4L_TOTAL' => $periodPerf['PV_4L'] + $userLastPerf['PV_4L'],
  388. 'PV_5L_TOTAL' => $periodPerf['PV_5L'] + $userLastPerf['PV_5L'],
  389. 'PV_PSS_TOTAL' => $periodPerf['PV_PSS'] + $userLastPerf['PV_PSS_TOTAL'],
  390. ];
  391. // 把会员的月业绩写入缓存中,以便下面的奖金计算从缓冲中获取数据效率高
  392. CalcCache::addHasMonthPerfUsers($userId, $this->_periodNum);
  393. CalcCache::nowMonthPerf($userId, $this->_periodNum, $nowMonthPerf);
  394. unset($userId, $everyData, $nowMonthPerf, $lastMonthData, $userBaseInfo, $isVip);
  395. }
  396. unset($allData);
  397. $this->loopCalcMonthPerfTableData($offset + $this->_limit);
  398. }
  399. unset($allData);
  400. return true;
  401. }
  402. /**
  403. * 循环有业绩会员,并入库
  404. * @param int $offset
  405. * @return bool
  406. * @throws \yii\db\Exception
  407. */
  408. public function loopWriteNowPerf($offset = 0) {
  409. echo sprintf("时间:[%s]缓存本期业绩数据入库,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
  410. // 从缓存列表里面从底层往上倒序获取会员
  411. $allData = CalcCache::getHasPerfUsers($this->_periodNum, $offset, $this->_limit);
  412. if($allData){
  413. $insertDataPeriodPerf = [];
  414. foreach($allData as $userId){
  415. $insertDataPeriodPerf[] = $this->nowPeriodPerfData($userId);
  416. unset($userId);
  417. }
  418. PerfPeriod::batchInsert($insertDataPeriodPerf);
  419. unset($insertDataPeriodPerf, $allData);
  420. return $this->loopWriteNowPerf($offset + $this->_limit);
  421. }
  422. unset($allData);
  423. return true;
  424. }
  425. /**
  426. * 循环有月业绩会员,并入库
  427. * @param int $offset
  428. * @return bool
  429. * @throws \yii\db\Exception
  430. */
  431. public function loopWriteMonthPerf($offset = 0) {
  432. if(!$this->_isCalcMonth){
  433. return true;
  434. }
  435. echo sprintf("时间:[%s]缓存本月业绩数据入库,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
  436. // 从缓存列表里面从底层往上倒序获取会员
  437. $allData = CalcCache::getHasMonthPerfUsers($this->_periodNum, $offset, $this->_limit);
  438. if($allData){
  439. $insertDataMonthPerf = [];
  440. foreach($allData as $userId){
  441. $insertDataMonthPerf[] = $this->nowMonthPerfData($userId);
  442. unset($userId);
  443. }
  444. PerfMonth::batchInsert($insertDataMonthPerf);
  445. unset($insertDataMonthPerf, $allData);
  446. return $this->loopWriteMonthPerf($offset + $this->_limit);
  447. }
  448. unset($allData);
  449. return true;
  450. }
  451. /**
  452. * 本期业绩数据
  453. * @param $userId
  454. * @return array
  455. */
  456. public function nowPeriodPerfData($userId){
  457. $data = CalcCache::nowPeriodPerf($userId, $this->_periodNum);
  458. $userInfo = CalcCache::getUserInfo($userId, $this->_periodNum);
  459. $result = [
  460. 'ID' => SnowFake::instance()->generateId(),
  461. 'USER_ID' => $userId,
  462. 'FX_AMOUNT_CASH' => $data['FX_AMOUNT_CASH'],
  463. 'PV_PCS' => $data['PV_PCS'],
  464. 'PV_PSS' => $data['PV_PSS'],
  465. 'PV_PCS_ZC' => $data['PV_PCS_ZC'],
  466. 'PV_PCS_FX' => $data['PV_PCS_FX'],
  467. 'PV_PCS_FX_CASH' => $data['PV_PCS_FX_CASH'],
  468. 'PV_PCS_FX_POINT' => $data['PV_PCS_FX_POINT'],
  469. 'PV_1L' => $data['PV_1L'],
  470. 'PV_1L_TOUCH' => $data['PV_1L_TOUCH'],
  471. 'PV_1L_ZC' => $data['PV_1L_ZC'],
  472. 'PV_1L_FX' => $data['PV_1L_FX'],
  473. 'PV_2L' => $data['PV_2L'],
  474. 'PV_2L_TOUCH' => $data['PV_2L_TOUCH'],
  475. 'PV_2L_ZC' => $data['PV_2L_ZC'],
  476. 'PV_2L_FX' => $data['PV_2L_FX'],
  477. 'PV_3L' => $data['PV_3L'],
  478. 'PV_3L_TOUCH' => $data['PV_3L_TOUCH'],
  479. 'PV_3L_ZC' => $data['PV_3L_ZC'],
  480. 'PV_3L_FX' => $data['PV_3L_FX'],
  481. 'PV_4L' => $data['PV_4L'],
  482. 'PV_4L_TOUCH' => $data['PV_4L_TOUCH'],
  483. 'PV_4L_ZC' => $data['PV_4L_ZC'],
  484. 'PV_4L_FX' => $data['PV_4L_FX'],
  485. 'PV_5L' => $data['PV_5L'],
  486. 'PV_5L_TOUCH' => $data['PV_5L_TOUCH'],
  487. 'PV_5L_ZC' => $data['PV_5L_ZC'],
  488. 'PV_5L_FX' => $data['PV_5L_FX'],
  489. 'SURPLUS_1L' => $data['SURPLUS_1L'],
  490. 'SURPLUS_2L' => $data['SURPLUS_2L'],
  491. 'SURPLUS_3L' => $data['SURPLUS_3L'],
  492. 'SURPLUS_4L' => $data['SURPLUS_4L'],
  493. 'SURPLUS_5L' => $data['SURPLUS_5L'],
  494. 'PERIOD_NUM' => $this->_periodNum,
  495. 'CALC_MONTH' => $this->_calcYearMonth,
  496. 'CREATED_AT' => Date::nowTime(),
  497. 'LAST_EMP_LV' => $userInfo['LAST_EMP_LV']
  498. ];
  499. unset($data);
  500. return $result;
  501. }
  502. /**
  503. * 本月业绩
  504. * @param $userId
  505. * @return array
  506. */
  507. public function nowMonthPerfData($userId){
  508. $data = CalcCache::nowMonthPerf($userId, $this->_periodNum);
  509. $baseInfo = CalcCache::getUserInfo($userId, $this->_periodNum);
  510. $result = [
  511. 'ID' => SnowFake::instance()->generateId(),
  512. 'USER_ID' => $userId,
  513. 'FX_AMOUNT_CASH' => $data['FX_AMOUNT_CASH'],
  514. 'PV_PCS' => $data['PV_PCS'],
  515. 'PV_PCS_FX' => $data['PV_PCS_FX'],
  516. 'PV_PSS' => $data['PV_PSS'],
  517. 'PV_1L' => $data['PV_1L'],
  518. 'PV_2L' => $data['PV_2L'],
  519. 'PV_3L' => $data['PV_3L'],
  520. 'PV_4L' => $data['PV_4L'],
  521. 'PV_5L' => $data['PV_5L'],
  522. 'PV_1L_TOTAL' => $data['PV_1L_TOTAL'],
  523. 'PV_2L_TOTAL' => $data['PV_2L_TOTAL'],
  524. 'PV_3L_TOTAL' => $data['PV_3L_TOTAL'],
  525. 'PV_4L_TOTAL' => $data['PV_4L_TOTAL'],
  526. 'PV_5L_TOTAL' => $data['PV_5L_TOTAL'],
  527. 'PV_PSS_TOTAL' => $data['PV_PSS_TOTAL'],
  528. 'CALC_MONTH' => $this->_calcYearMonth,
  529. 'CREATED_AT' => Date::nowTime(),
  530. 'LAST_EMP_LV' => $baseInfo['LAST_EMP_LV']
  531. ];
  532. unset($data);
  533. return $result;
  534. }
  535. /**
  536. * 循环父级并执行回调函数
  537. * @param $userId
  538. * @param callable $callbackFunc
  539. * @param int $offset
  540. * @return bool
  541. */
  542. public function loopNetworkParentDo($userId, callable $callbackFunc, int $offset = 0) {
  543. $allParents = Cache::getAllNetworkParents($userId, true);
  544. $allData = array_slice($allParents, $offset, $this->_limit);
  545. unset($allParents);
  546. if ($allData) {
  547. foreach ($allData as $data) {
  548. $funcResult = $callbackFunc($data);
  549. if ($funcResult === self::LOOP_FINISH) {
  550. return true;
  551. } elseif ($funcResult === self::LOOP_CONTINUE) {
  552. continue;
  553. }
  554. unset($data, $funcResult);
  555. }
  556. unset($allData);
  557. return $this->loopNetworkParentDo($userId, $callbackFunc, $offset + $this->_limit);
  558. }
  559. return true;
  560. }
  561. /**
  562. * 循环推荐网络的父级
  563. * @param $userId
  564. * @param callable $callbackFunc
  565. * @param int $offset
  566. * @return bool
  567. */
  568. public function loopRelationParentDo($userId, callable $callbackFunc, int $offset = 0) {
  569. $allParents = Cache::getAllRelationParents($userId,true);
  570. $allData = array_slice($allParents, $offset, $this->_limit);
  571. unset($allParents);
  572. if ($allData) {
  573. foreach ($allData as $data) {
  574. $funcResult = $callbackFunc($data);
  575. if ($funcResult === self::LOOP_FINISH) {
  576. return true;
  577. } elseif ($funcResult === self::LOOP_CONTINUE) {
  578. continue;
  579. }
  580. unset($data, $funcResult);
  581. }
  582. unset($allData);
  583. return $this->loopRelationParentDo($userId, $callbackFunc, $offset + $this->_limit);
  584. }
  585. return true;
  586. }
  587. /**
  588. * 更新百分比并发送
  589. * @param $percent
  590. */
  591. private function _updatePercent($percent) {
  592. // 把数据写入数据库中
  593. Period::updateAll(['PERF_PERCENT' => $percent], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
  594. }
  595. }