PeriodForm.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. <?php
  2. namespace common\models\forms;
  3. use common\helpers\bonus\BonusCalc;
  4. use common\helpers\bonus\BonusSend;
  5. use common\helpers\bonus\PerfCalc;
  6. use common\helpers\Cache;
  7. use common\helpers\Date;
  8. use common\components\Model;
  9. use common\components\SwooleAsyncTimer;
  10. use common\helpers\Form;
  11. use common\models\Period;
  12. use common\models\UserWallet;
  13. use common\models\User;
  14. use common\models\UserStatusAudit;
  15. use common\models\Withdraw;
  16. use yii\base\Exception;
  17. use Yii;
  18. use yii\helpers\Json;
  19. /**
  20. * Login form
  21. */
  22. class PeriodForm extends Model
  23. {
  24. public $periodNum;
  25. private $_periodModel;
  26. private $_limit = 1000;
  27. /**
  28. * @inheritdoc
  29. */
  30. public function rules()
  31. {
  32. return [
  33. [['periodNum'], 'trim'],
  34. [['periodNum'], 'required'],
  35. [['periodNum'], 'integer'],
  36. [['periodNum'], 'isPeriod'],
  37. ];
  38. }
  39. public function scenarios()
  40. {
  41. $parentScenarios = parent::scenarios();
  42. $customScenarios = [
  43. 'close' => ['periodNum'],
  44. 'perf' => ['periodNum'],
  45. 'calc' => ['periodNum'],
  46. 'send' => ['periodNum'],
  47. 'autoClose' => ['periodNum'],
  48. 'autoPerf' => ['periodNum'],
  49. ];
  50. return array_merge($parentScenarios, $customScenarios);
  51. }
  52. public function attributeLabels()
  53. {
  54. return [
  55. 'periodNum' => '期数',
  56. ];
  57. }
  58. public function isPeriod($attributes){
  59. $periodObj = Period::instance();
  60. $periodModel = Period::findOne(['PERIOD_NUM' => $this->periodNum]);
  61. if(!$periodModel){
  62. $this->addError($attributes, '所传期数不存在');
  63. }
  64. if($this->scenario == 'close') {
  65. if(!$periodObj->isCanClose($this->periodNum)){
  66. $this->addError($attributes, '所传期数不可封期');
  67. }
  68. }
  69. // elseif($this->scenario == 'perf') {
  70. // if(!$periodObj->isCanPerf($this->periodNum)){
  71. // $this->addError($attributes, '所传期数不可生成业绩单');
  72. // }
  73. // }
  74. elseif($this->scenario == 'calc') {
  75. if(!$periodObj->isCanCalc($this->periodNum)){
  76. $this->addError($attributes, '所传期数不可结算');
  77. }
  78. }
  79. elseif($this->scenario == 'send') {
  80. if(!$periodObj->isCanSend($this->periodNum)){
  81. $this->addError($attributes, '所传期数不可挂网');
  82. }
  83. }
  84. $this->_periodModel = $periodModel;
  85. }
  86. /**
  87. * 封期
  88. * @return null
  89. * @throws \yii\db\Exception
  90. */
  91. public function closePeriod(){
  92. if(!$this->validate()){
  93. return null;
  94. }
  95. $periodNum = $this->periodNum;
  96. // 进行封期操作
  97. $transaction = \Yii::$app->db->beginTransaction();
  98. try {
  99. $model = $this->_periodModel;
  100. $model->IS_CLOSED = 1;
  101. if(isset(\Yii::$app->user->id) && \Yii::$app->user->id){
  102. $model->CLOSE_ADMIN_ID = \Yii::$app->user->id;
  103. }
  104. $model->CLOSED_AT = Date::nowTime();
  105. if(!$model->save()){
  106. throw new Exception('封期失败,请重试');
  107. }
  108. $settings = \Yii::$app->params['swooleAsyncTimer'];
  109. $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
  110. $settings = array_merge($settings, $bonusSettings);
  111. $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('bonus/after-close', ['periodNum'=>$periodNum, 'closedAt'=>$model->CLOSED_AT], $settings);
  112. if($taskKey === false){
  113. $this->addError('send', '请求失败');
  114. return null;
  115. }
  116. $transaction->commit();
  117. } catch (Exception $e){
  118. $transaction->rollBack();
  119. $this->addError('close', $e->getMessage());
  120. return null;
  121. }
  122. return $periodNum;
  123. }
  124. /**
  125. * 自动封期
  126. * @return null
  127. * @throws \yii\db\Exception
  128. */
  129. public function autoClosePeriod(){
  130. if(!$this->validate()){
  131. return null;
  132. }
  133. $periodNum = $this->periodNum;
  134. // 进行封期操作
  135. $transaction = \Yii::$app->db->beginTransaction();
  136. try {
  137. $model = $this->_periodModel;
  138. $model->IS_CLOSED = 1;
  139. if(isset(\Yii::$app->user->id) && \Yii::$app->user->id){
  140. $model->CLOSE_ADMIN_ID = \Yii::$app->user->id;
  141. }
  142. $model->CLOSED_AT = Date::nowTime();
  143. if(!$model->save()){
  144. throw new Exception('封期失败,请重试');
  145. }
  146. $transaction->commit();
  147. } catch (Exception $e){
  148. $transaction->rollBack();
  149. $this->addError('close', $e->getMessage());
  150. return null;
  151. }
  152. //封期后的操作(这句话放这里的目的是为了保障封期的时间不受其他后期工作的影响,封期之后再完成封期后的操作)
  153. $this->afterCloseAsync($periodNum, $model->CLOSED_AT);
  154. return $periodNum;
  155. }
  156. /**
  157. * 给到期要加T的会员加T
  158. * @param $periodNum
  159. */
  160. private function _periodChangeStatus($periodNum){
  161. // 到期加T
  162. $allAddTData = UserStatusAudit::find()->where('IS_PERIOD_ADD_T=1 AND ADD_T_PERIOD_NUM<=:NOW_PERIOD_NUM AND AUDIT_STATUS=:AUDIT_STATUS', [':NOW_PERIOD_NUM'=>$periodNum, ':AUDIT_STATUS'=>\Yii::$app->params['auditStatus']['true']['value']])->asArray()->all();
  163. foreach($allAddTData as $data){
  164. User::updateAll(['ID_CARD_PREFIX'=>'T'], 'ID=:ID', [':ID'=>$data['USER_ID']]);
  165. }
  166. // 到期开通
  167. $allOpenData = UserStatusAudit::find()->where('IS_PERIOD_OPEN=1 AND OPEN_PERIOD_NUM<=:NOW_PERIOD_NUM AND AUDIT_STATUS=:AUDIT_STATUS', [':NOW_PERIOD_NUM'=>$periodNum, ':AUDIT_STATUS'=>\Yii::$app->params['auditStatus']['true']['value']])->asArray()->all();
  168. foreach($allOpenData as $openData){
  169. // 改变会员的状态 并取消身份证号加T,并设置首次开通标记
  170. User::updateAll(['STATUS'=>$openData['STATUS_VALUE'], 'STATUS_AT'=>Date::nowTime(), 'ID_CARD_PREFIX'=>'', 'IS_FIRST_OPEN'=>1], 'ID=:ID', [':ID'=>$openData['USER_ID']]);
  171. //从关停到开启
  172. if ($openData['ORI_VALUE'] == UserStatusForm::STATUS_CLOSE) {
  173. UserWallet::updateAll(['CLEAR_BY_CLOSED_AT' => 0], 'USER_ID=:USER_ID', [':USER_ID' => $openData['USER_ID']]);
  174. }
  175. }
  176. }
  177. /**
  178. * 页面请求异步处理编辑
  179. * @return string | null
  180. */
  181. public function calcWebToAsync(){
  182. if(!$this->validate()){
  183. return null;
  184. }
  185. // 把正在结算标记为真
  186. $model = $this->_periodModel;
  187. $model->IS_CALCING = 1;
  188. $model->CALC_ADMIN_ID = \Yii::$app->user->id;
  189. if(!$model->save()){
  190. $this->addError('calc', Form::formatErrorsForApi($model->getErrors()));
  191. return null;
  192. }
  193. // 异步处理添加任务
  194. $settings = \Yii::$app->params['swooleAsyncTimer'];
  195. $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
  196. $settings = array_merge($settings, $bonusSettings);
  197. $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('bonus/calc', \Yii::$app->request->get(), $settings);
  198. if($taskKey === false){
  199. $this->addError('send', '请求失败');
  200. return null;
  201. }
  202. return $model;
  203. }
  204. /**
  205. * 异步处理逻辑
  206. * @param $handleUserId
  207. * @return bool|null
  208. * @throws Exception
  209. * @throws \yii\db\Exception
  210. */
  211. public function calcAsync($handleUserId): ?bool
  212. {
  213. if(!$this->validate()){
  214. return null;
  215. }
  216. $bonusCalc = BonusCalc::instance();
  217. $asyncResult = $bonusCalc->calculateBonus($this->periodNum);
  218. if($asyncResult){
  219. $bonusCalc->endCalcTask();
  220. } else {
  221. $bonusCalc->errorCalcTask();
  222. $this->addErrors($bonusCalc->getErrors());
  223. }
  224. return $asyncResult;
  225. }
  226. /**
  227. * 页面请求异步处理生成业绩单
  228. * @return string | null
  229. */
  230. public function perfWebToAsync(){
  231. if(!$this->validate()){
  232. return null;
  233. }
  234. // 把正在结算标记为真
  235. $model = $this->_periodModel;
  236. $model->IS_PERFING = 1;
  237. $model->PERF_ADMIN_ID = \Yii::$app->user->id;
  238. if(!$model->save()){
  239. $this->addError('perf', Form::formatErrorsForApi($model->getErrors()));
  240. return null;
  241. }
  242. // 异步处理添加任务
  243. $settings = \Yii::$app->params['swooleAsyncTimer'];
  244. $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
  245. $settings = array_merge($settings, $bonusSettings);
  246. $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('bonus/perf', \Yii::$app->request->get(), $settings);
  247. if($taskKey === false){
  248. $this->addError('perf', '请求失败');
  249. return null;
  250. }
  251. return $model;
  252. }
  253. /**
  254. * 异步处理逻辑
  255. * @param $handleUserId
  256. * @return bool|null
  257. * @throws Exception
  258. * @throws \yii\db\Exception
  259. */
  260. public function perfAsync($handleUserId){
  261. if(!$this->validate()){
  262. return null;
  263. }
  264. $bonusCalc = PerfCalc::instance();
  265. //$bonusCalc->init($this->periodNum, $handleUserId);
  266. //$bonusCalc->setPeriodNum($this->periodNum);
  267. $asyncResult = $bonusCalc->calcStep($this->periodNum, $handleUserId);
  268. if($asyncResult){
  269. $bonusCalc->endCalcTask();
  270. } else {
  271. $bonusCalc->errorCalcTask();
  272. $this->addErrors($bonusCalc->getErrors());
  273. }
  274. return $asyncResult;
  275. }
  276. /**
  277. * 页面请求异步处理挂网
  278. * @return string | null
  279. */
  280. public function sendWebToAsync(){
  281. if(!$this->validate()){
  282. return null;
  283. }
  284. // 把正在挂网标记设为真
  285. $model = $this->_periodModel;
  286. $model->IS_SENDING = 1;
  287. $model->SENT_ADMIN_ID = \Yii::$app->user->id;
  288. if(!$model->save()){
  289. $this->addError('send', Form::formatErrorsForApi($model->getErrors()));
  290. return null;
  291. }
  292. // 异步处理添加任务
  293. $settings = \Yii::$app->params['swooleAsyncTimer'];
  294. $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
  295. $settings = array_merge($settings, $bonusSettings);
  296. $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('bonus/send', \Yii::$app->request->get(), $settings);
  297. if($taskKey === false){
  298. $this->addError('send', '请求失败');
  299. return null;
  300. }
  301. return $model;
  302. }
  303. /**
  304. * 异步处理挂网逻辑
  305. * @param $handleUserId
  306. * @return bool|null
  307. * @throws \yii\db\Exception
  308. */
  309. public function sendAsync($handleUserId): ?bool
  310. {
  311. if(!$this->validate()){
  312. return null;
  313. }
  314. $bonusSend = BonusSend::instance();
  315. $bonusSend->init($this->periodNum, $handleUserId);
  316. $asyncResult = $bonusSend->sendStep();
  317. if($asyncResult){
  318. $bonusSend->endTask();
  319. } else {
  320. $bonusSend->errorTask();
  321. $this->addErrors($bonusSend->getErrors());
  322. }
  323. return $asyncResult;
  324. }
  325. /**
  326. * 异步处理封期后的操作
  327. * @param $periodNum
  328. * @return bool
  329. * @throws \yii\db\Exception
  330. */
  331. public function afterCloseAsync($periodNum,$closedAt){
  332. //如果自动结算
  333. // if(boolval(Cache::getSystemConfig()['autoCalcPeriod']['VALUE'])){
  334. // $period = Period::instance();
  335. // if($period->isLastSent($periodNum)) {
  336. // $bonusCalc = PerfCalc::instance();
  337. // $asyncResult = $bonusCalc->calcStep($periodNum);
  338. // if ($asyncResult) {
  339. // $bonusCalc->endCalcTask();
  340. // } else {
  341. // $bonusCalc->errorCalcTask();
  342. // $this->addErrors($bonusCalc->getErrors());
  343. // }
  344. // return $asyncResult;
  345. // }
  346. // }
  347. }
  348. /**
  349. * 页面请求异步处理 自动计算
  350. * @return string | null
  351. */
  352. public function autoExec()
  353. {
  354. if (!$this->validate()) {
  355. return null;
  356. }
  357. // // 把正在结算标记为真
  358. $model = $this->_periodModel;
  359. // $model->IS_CALCING = 1;
  360. // $model->CALC_ADMIN_ID = \Yii::$app->user->id;
  361. // if (!$model->save()) {
  362. // $this->addError('calc', Form::formatErrorsForApi($model->getErrors()));
  363. // return null;
  364. // }
  365. // 异步处理添加任务
  366. $settings = \Yii::$app->params['swooleAsyncTimer'];
  367. $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
  368. $settings = array_merge($settings, $bonusSettings);
  369. $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('calc/auto-exec', \Yii::$app->request->get(), $settings);
  370. if ($taskKey === false) {
  371. $this->addError('send', '请求失败');
  372. return null;
  373. }
  374. return $model;
  375. }
  376. /**
  377. * 页面请求异步处理 自动计算
  378. * @return string | null
  379. */
  380. public function autoPerf()
  381. {
  382. if (!$this->validate()) {
  383. return null;
  384. }
  385. // // 把正在结算标记为真
  386. $model = $this->_periodModel;
  387. // $model->IS_CALCING = 1;
  388. // $model->CALC_ADMIN_ID = \Yii::$app->user->id;
  389. // if (!$model->save()) {
  390. // $this->addError('calc', Form::formatErrorsForApi($model->getErrors()));
  391. // return null;
  392. // }
  393. // 异步处理添加任务
  394. $settings = \Yii::$app->params['swooleAsyncTimer'];
  395. $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
  396. $settings = array_merge($settings, $bonusSettings);
  397. $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('calc/auto-perf', \Yii::$app->request->get(), $settings);
  398. if ($taskKey === false) {
  399. $this->addError('send', '请求失败');
  400. return null;
  401. }
  402. return $model;
  403. }
  404. /**
  405. * 页面请求异步处理 自动计算
  406. * @return string | null
  407. */
  408. public function autoPrePerf()
  409. {
  410. $settings = \Yii::$app->params['swooleAsyncTimer'];
  411. $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
  412. $settings = array_merge($settings, $bonusSettings);
  413. $params['handleUserId'] = null;
  414. $params['handleUserName'] = null;
  415. $params['periodNum'] = $this->periodNum;
  416. $taskKey = Cache::setAsyncParams($params);
  417. echo($taskKey.PHP_EOL);
  418. $data = [
  419. 'data' => [
  420. [
  421. 'a' => 'calc/auto-perf',
  422. 'p' => [$taskKey],
  423. ]
  424. ],
  425. ];
  426. try {
  427. (new SwooleAsyncTimer())->async(Json::encode($data), $settings);
  428. }catch (\Exception $e){
  429. echo($e);
  430. return null;
  431. }
  432. return true;
  433. }
  434. /**
  435. * 页面请求异步处理 生成业绩单
  436. * @return string | null
  437. */
  438. public function generatePerfOrder()
  439. {
  440. if (!$this->validate()) {
  441. return null;
  442. }
  443. // // 把正在结算标记为真
  444. $model = $this->_periodModel;
  445. // $model->IS_CALCING = 1;
  446. // $model->CALC_ADMIN_ID = \Yii::$app->user->id;
  447. // if (!$model->save()) {
  448. // $this->addError('calc', Form::formatErrorsForApi($model->getErrors()));
  449. // return null;
  450. // }
  451. // 异步处理添加任务
  452. $settings = \Yii::$app->params['swooleAsyncTimer'];
  453. $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
  454. $settings = array_merge($settings, $bonusSettings);
  455. $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('calc/perf-order', \Yii::$app->request->get(), $settings);
  456. if ($taskKey === false) {
  457. $this->addError('send', '请求失败');
  458. return null;
  459. }
  460. return $model;
  461. }
  462. /**
  463. * 页面请求异步处理 推送基础数据
  464. * @return string | null
  465. */
  466. public function pushBaseData()
  467. {
  468. if (!$this->validate()) {
  469. return null;
  470. }
  471. // // 把正在结算标记为真
  472. $model = $this->_periodModel;
  473. // $model->IS_CALCING = 1;
  474. // $model->CALC_ADMIN_ID = \Yii::$app->user->id;
  475. // if (!$model->save()) {
  476. // $this->addError('calc', Form::formatErrorsForApi($model->getErrors()));
  477. // return null;
  478. // }
  479. // 异步处理添加任务
  480. $settings = \Yii::$app->params['swooleAsyncTimer'];
  481. $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
  482. $settings = array_merge($settings, $bonusSettings);
  483. $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('calc/push-data', \Yii::$app->request->get(), $settings);
  484. if ($taskKey === false) {
  485. $this->addError('send', '请求失败');
  486. return null;
  487. }
  488. return $model;
  489. }
  490. /**
  491. * 拉取计算系统中生成的期业绩数据
  492. * @return null
  493. */
  494. public function pullPeriod()
  495. {
  496. if (!$this->validate()) {
  497. return null;
  498. }
  499. // // 把正在结算标记为真
  500. $model = $this->_periodModel;
  501. // $model->IS_CALCING = 1;
  502. // $model->CALC_ADMIN_ID = \Yii::$app->user->id;
  503. // if (!$model->save()) {
  504. // $this->addError('calc', Form::formatErrorsForApi($model->getErrors()));
  505. // return null;
  506. // }
  507. // 异步处理添加任务
  508. $settings = \Yii::$app->params['swooleAsyncTimer'];
  509. $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
  510. $settings = array_merge($settings, $bonusSettings);
  511. $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('calc/pull-period', \Yii::$app->request->get(), $settings);
  512. if ($taskKey === false) {
  513. $this->addError('send', '请求失败');
  514. return null;
  515. }
  516. return $model;
  517. }
  518. /**
  519. * 拉取计算系统中生成的奖金数据
  520. * @return null
  521. */
  522. public function pullBonus()
  523. {
  524. if (!$this->validate()) {
  525. return null;
  526. }
  527. // // 把正在结算标记为真
  528. $model = $this->_periodModel;
  529. // $model->IS_CALCING = 1;
  530. // $model->CALC_ADMIN_ID = \Yii::$app->user->id;
  531. // if (!$model->save()) {
  532. // $this->addError('calc', Form::formatErrorsForApi($model->getErrors()));
  533. // return null;
  534. // }
  535. // 异步处理添加任务
  536. $settings = \Yii::$app->params['swooleAsyncTimer'];
  537. $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
  538. $settings = array_merge($settings, $bonusSettings);
  539. $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('calc/pull-bonus', \Yii::$app->request->get(), $settings);
  540. if ($taskKey === false) {
  541. $this->addError('send', '请求失败');
  542. return null;
  543. }
  544. return $model;
  545. }
  546. }