CalcServePerfCalc.php 29 KB

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