RechargeForm.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. namespace common\models\forms;
  3. use common\components\Model;
  4. use common\helpers\Cache;
  5. use common\helpers\Date;
  6. use common\helpers\Form;
  7. use common\helpers\PayStack;
  8. use common\helpers\Tool;
  9. use common\helpers\user\Cash;
  10. use common\helpers\user\Info;
  11. use common\models\Recharge;
  12. use common\models\UserInfo;
  13. use yii\base\Exception;
  14. /**
  15. * Login form
  16. */
  17. class RechargeForm extends Model {
  18. public $selectedIds;
  19. public $auditStatus;
  20. public $createRemark;
  21. public $userName;
  22. public $applyAmount;
  23. public $openBank;
  24. public $bankAddress;
  25. public $bankNo;
  26. // public $bankProvince;
  27. // public $bankCity;
  28. // public $bankCounty;
  29. public $sn;
  30. public $currency;
  31. public $amount;
  32. public $bankRealName;
  33. private $_userId;
  34. /**
  35. * @inheritdoc
  36. */
  37. public function rules() {
  38. return [
  39. [['userName', 'idCard', 'applyAmount', 'auditStatus', 'remark', 'selectedIds', 'sn','amount', 'bankRealName', 'bankNo'], 'trim'],
  40. [['selectedIds', 'auditStatus', 'userName','applyAmount', 'currency'/*,'openBank','bankNo','bankAddress'*/], 'required'],
  41. [['selectedIds'], 'exist', 'targetClass' => Recharge::class, 'targetAttribute' => 'ID', 'message' => '充值申请不存在'],
  42. [['userName'], 'exist', 'targetClass' => UserInfo::class, 'targetAttribute' => 'USER_NAME', 'message' => '会员不存在'],
  43. [['applyAmount'], 'price'],
  44. [['applyAmount'], 'isApplyAmount'],
  45. [['selectedIds'], 'isSelected'],
  46. //[['sn'], 'isSn'],
  47. ];
  48. }
  49. /**
  50. * 指定场景
  51. * @return array
  52. */
  53. public function scenarios() {
  54. $parentScenarios = parent::scenarios();
  55. $customScenarios = [
  56. 'addByAdmin' => ['userName', 'applyAmount'],
  57. 'addByUser' => ['applyAmount','openBank','bankNo','bankAddress','currency'],
  58. 'statusByAdmin' => ['selectedIds', 'auditStatus', 'createRemark'],
  59. ];
  60. return array_merge($parentScenarios, $customScenarios);
  61. }
  62. /**
  63. * @return array
  64. */
  65. public function attributeLabels() {
  66. return [
  67. 'selectedIds' => '充值申请ID',
  68. 'userName' => '会员编号',
  69. 'applyAmount' => '申请充值的金额',
  70. // 'openBank' => '汇款银行',
  71. // 'bankNo' => '汇款账号',
  72. // 'bankAddress' => '银行支行',
  73. 'currency' => '货币',
  74. // 'bankProvince' => '银行省',
  75. // 'bankCity' => '银行市',
  76. // 'bankCounty' => '银行县',
  77. ];
  78. }
  79. /**
  80. * 校验申请金额是否小于当前余额并符合配置中的设置
  81. * @param $attribute
  82. * @return bool
  83. */
  84. public function isApplyAmount($attribute) {
  85. if ($this->applyAmount <= 0) {
  86. $this->addError('scenario', '充值金额必须大于0');
  87. }
  88. if ((int)($this->applyAmount)!=$this->applyAmount) {
  89. $this->addError('scenario', '充值金额必须是整数');
  90. }
  91. if ($this->scenario == 'addByUser') {
  92. $this->_userId = \Yii::$app->user->id;
  93. } elseif ($this->scenario == 'addByAdmin') {
  94. $userInfo = UserInfo::findOneAsArray(['USER_NAME' => $this->userName]);
  95. if (!$userInfo) {
  96. $this->addError('scenario', $this->userName . '会员不存在');
  97. }else{
  98. $this->_userId = $userInfo['USER_ID'];
  99. }
  100. } else {
  101. $this->addError($attribute, '场景不存在');
  102. return false;
  103. }
  104. }
  105. /**
  106. * 批量数据
  107. * @param $attributes
  108. */
  109. public function isSelected($attributes) {
  110. if (!$this->selectedIds) {
  111. $this->addError($attributes, '必须选择一条数据');
  112. }
  113. // if (!is_array($this->selectedIds)) {
  114. // $this->selectedIds = [$this->selectedIds];
  115. // }
  116. }
  117. /**
  118. * 判断信息是否一致
  119. * @param $attribute
  120. * @throws Exception
  121. */
  122. public function isSn($attribute) {
  123. $sn = $this->sn;
  124. if (!$oneWithdraw = Recharge::findOneAsArray('SN=:SN AND AUDIT_STATUS=:AUDIT_STATUS', [':SN' => $sn, ':AUDIT_STATUS' => Recharge::STATUS_AUDITED])) {
  125. $this->addError($attribute, '不存在充值流水号为' . $sn . '的已审核记录');
  126. }
  127. if ($oneWithdraw) {
  128. $info = Info::baseInfo($oneWithdraw['USER_ID']);
  129. if ($this->userName != $info['USER_NAME']) {
  130. $this->addError($attribute, 'Excel中充值流水号' . $sn . '的用户名' . $this->userName . '与系统中的信息【' . $info['USER_NAME'] . '】不一致');
  131. }
  132. if ($this->amount != $oneWithdraw['AMOUNT']) {
  133. $this->addError($attribute, 'Excel中充值流水号' . $sn . '的充值金额' . $this->amount . '与系统中的信息【' . $oneWithdraw['AMOUNT'] . '】不一致');
  134. }
  135. if ($this->bankRealName != $oneWithdraw['REAL_NAME']) {
  136. $this->addError($attribute, 'Excel中充值流水号' . $sn . '的实时开户名' . $this->bankRealName . '与系统中的信息【' . $oneWithdraw['REAL_NAME'] . '】不一致');
  137. }
  138. if ($this->bankNo != $oneWithdraw['BANK_NO']) {
  139. $this->addError($attribute, 'Excel中充值流水号' . $sn . '的实时银行账户' . $this->bankNo . '与系统中的信息【' . $oneWithdraw['BANK_NO'] . '】不一致');
  140. }
  141. }
  142. }
  143. /**
  144. * 管理员充值
  145. * @return null|string
  146. * @throws \yii\db\Exception
  147. */
  148. public function recharge() {
  149. if (!$this->validate()) {
  150. return false;
  151. }
  152. $db = \Yii::$app->db;
  153. $transaction = $db->beginTransaction();
  154. try {
  155. Cash::changeUserCash($this->_userId, 'CASH', $this->applyAmount, ['REMARK' => '后台管理员充值']);
  156. $transaction->commit();
  157. } catch (Exception $e) {
  158. $transaction->rollBack();
  159. $this->addError('add', $e->getMessage());
  160. return false;
  161. }
  162. return true;
  163. }
  164. /**
  165. * 添加充值申请
  166. * @return null|string
  167. * @throws \yii\db\Exception
  168. */
  169. public function add() {
  170. if (!$this->validate()) {
  171. return false;
  172. }
  173. $db = \Yii::$app->db;
  174. $transaction = $db->beginTransaction();
  175. // 向paystack发起订单
  176. $userInfo = Info::baseInfo($this->_userId);
  177. $rechargeOrder = PayStack::transactionInit($this->currency, $this->applyAmount, $userInfo['EMAIL']);
  178. if($rechargeOrder['status']!=1){
  179. throw new Exception('api error');
  180. }
  181. try {
  182. $nowTime = Date::nowTime();
  183. $period = Recharge::getPeriod($nowTime);
  184. //增加记录
  185. $userInfo = Info::baseInfo($this->_userId);
  186. $rechargeModel = new Recharge();
  187. $rechargeModel->SN = $this->_generateSn();
  188. $rechargeModel->USER_ID = $this->_userId;
  189. $rechargeModel->REAL_NAME = Info::getUserRealNameByUserId($this->_userId);
  190. $rechargeModel->ID_CARD = $userInfo['ID_CARD'];
  191. $rechargeModel->RECHARGE_PERIOD_NUM = $period['nowPeriodNum'];
  192. $rechargeModel->RECHARGE_YEAR = $period['nowYear'];
  193. $rechargeModel->RECHARGE_MONTH = $period['nowMonth'];
  194. $rechargeModel->CURRENCY = $this->currency;
  195. $rechargeModel->AMOUNT = $this->applyAmount;
  196. $rechargeModel->RECHARGE_REF = $rechargeOrder['data']['reference'];
  197. $rechargeModel->RECHARGE_ORDER_ID = $rechargeOrder['data']['access_code'];
  198. $rechargeModel->RECHARGE_STATUS = 0;
  199. $rechargeModel->OPEN_BANK = 'a';
  200. $rechargeModel->BANK_ADDRESS = 'b';
  201. $rechargeModel->BANK_NO = 'c';
  202. // $rechargeModel->BANK_PROVINCE = $this->bankProvince ?? 0;
  203. // $rechargeModel->BANK_CITY = $this->bankCity ?? 0;
  204. // $rechargeModel->BANK_COUNTY = $this->bankCounty ?? 0;
  205. $rechargeModel->P_MONTH = Date::ociToDate($period['yearMonth'], Date::OCI_TIME_FORMAT_SHORT_MONTH);
  206. $rechargeModel->AUDIT_STATUS = Recharge::STATUS_APPLIED;
  207. $rechargeModel->CREATED_AT = $nowTime;
  208. if (!$rechargeModel->save()) {
  209. throw new Exception(Form::formatErrorsForApi($rechargeModel->getErrors()));
  210. }
  211. $transaction->commit();
  212. } catch (Exception $e) {
  213. $transaction->rollBack();
  214. $this->addError('add', $e->getMessage());
  215. return false;
  216. }
  217. return $rechargeModel;
  218. }
  219. /**
  220. * 生成流水号
  221. * @return string
  222. */
  223. private function _generateSn() {
  224. return 'CZ' . Date::today('Ymd') . $this->_random(10, 1);
  225. }
  226. /**
  227. * 生成随机数
  228. *
  229. * @param $length
  230. * @param int $numeric
  231. * @return string
  232. */
  233. private function _random($length, $numeric = 0) {
  234. $seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
  235. $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed));
  236. $hash = '';
  237. $max = strlen($seed) - 1;
  238. for ($i = 0; $i < $length; $i++) {
  239. $hash .= $seed[mt_rand(0, $max)];
  240. }
  241. return $hash;
  242. }
  243. /**
  244. * 设置充值订单的状态
  245. * @return null|static
  246. * @throws \yii\db\Exception
  247. */
  248. public function changeStatus() {
  249. if (!$this->validate()) {
  250. return null;
  251. }
  252. $logs = [];
  253. $db = \Yii::$app->db;
  254. $transaction = $db->beginTransaction();
  255. try {
  256. $oneRecharge = Recharge::findOne(['ID' => $this->selectedIds]);
  257. //判断状态
  258. if (($msg = Recharge::chkAuditStatus($oneRecharge->SN, $oneRecharge->AUDIT_STATUS, $this->auditStatus)) != '') {
  259. throw new Exception($msg);
  260. }
  261. //待审核->已审核 修改会员现金钱包
  262. if ($this->auditStatus == Recharge::STATUS_AUDITED) {
  263. Cash::changeUserCash($oneRecharge->USER_ID, 'CASH', abs($oneRecharge->AMOUNT), ['REMARK' => '会员充值申请审核']);
  264. }
  265. $oneRecharge->REMARK = $this->createRemark ?? '';
  266. $oneRecharge->AUDIT_ADMIN = \Yii::$app->user->id;
  267. $oneRecharge->AUDIT_STATUS = $this->auditStatus;
  268. $oneRecharge->AUDITED_AT = Date::nowTime();
  269. if (!$oneRecharge->save()) {
  270. throw new Exception(Form::formatErrorsForApi($oneRecharge->getErrors()));
  271. }
  272. $logs[$this->selectedIds] = $oneRecharge->SN;
  273. $transaction->commit();
  274. } catch (Exception $e) {
  275. $transaction->rollBack();
  276. $this->addError('auditStatus', $e->getMessage());
  277. return null;
  278. }
  279. return ['logs' => $logs, 'status' => $this->auditStatus];
  280. }
  281. }