FundService.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <?php
  2. namespace addons\QiShangTong\common\service;
  3. use addons\QiShangTong\common\enums\QiShangTongEnums;
  4. use addons\QiShangTong\common\models\QiShangTongBalance;
  5. use addons\QiShangTong\common\models\QiShangTongBalanceLog;
  6. use common\enums\AddonsEnum;
  7. use common\enums\RabbitMqEnum;
  8. use common\enums\StatusEnum;
  9. use common\helpers\FormatHelper;
  10. use common\models\mall\Mall;
  11. use common\models\order\Order;
  12. class FundService
  13. {
  14. public function page(int $mall_id, array $params)
  15. {
  16. $where = [
  17. ['status' => [StatusEnum::DISABLED, StatusEnum::ENABLED]]
  18. ];
  19. if (SettingService::isMasterMall($mall_id)) {
  20. if (!empty($params['keyword'])) {
  21. $ids = Mall::find()->where(['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]])
  22. ->andWhere(['or', ['like', 'id', $params['keyword']], ['like', 'id', $params['keyword']]])->select('id')->column();
  23. if (empty($ids)) return [];
  24. $where[] = ['mall_id' => $ids];
  25. }
  26. } else {
  27. $where[] = ['mall_id' => $mall_id];
  28. }
  29. if (!empty($params['date_start'])) $where[] = ['>=', 'created_at', strtotime($params['date_start'])];
  30. if (!empty($params['date_end'])) $where[] = ['<=', 'created_at', strtotime($params['date_end'])];
  31. $ret = QiShangTongBalanceLog::listPage([
  32. 'where' => $where,
  33. 'order' => 'id desc',
  34. 'limit' => $params['limit'] ?? 10,
  35. 'with' => ['mall']
  36. ]);
  37. if (!empty(QiShangTongBalanceLog::getStaticError())) return QiShangTongBalanceLog::getStaticError();
  38. if (!empty($ret['list'])) {
  39. foreach ($ret['list'] as &$item) {
  40. $item['type_txt'] = QiShangTongEnums::BALANCE_LOG_TYPE_MAP[$item['type']] ?? '未知类型';
  41. $item['logo'] = MallService::getLogo($item['id']);
  42. }
  43. }
  44. return $ret;
  45. }
  46. /**
  47. * 异动
  48. * @param array $params mall_id, amount, remark, type, direction, order_no, addons
  49. * @return string|QiShangTongBalanceLog
  50. */
  51. public function create(array $params)
  52. {
  53. $t = \Yii::$app->db->beginTransaction();
  54. try {
  55. $params['status'] = SettingService::isMasterMall($params['mall_id']) ? StatusEnum::DELETE : StatusEnum::ENABLED;
  56. $params['amount'] = intval(bcmul($params['amount'], 100));
  57. if ($params['status'] == StatusEnum::ENABLED) {
  58. $account = QiShangTongBalance::findOne(['mall_id' => $params['mall_id']]);
  59. if (empty($account)) {
  60. $account = new QiShangTongBalance();
  61. $account->mall_id = $params['mall_id'];
  62. }
  63. $balance = $account->balance;
  64. if ($params['direction'] == StatusEnum::ENABLED) { // +
  65. $account->balance = bcadd($account->balance, $params['amount']);
  66. } else { // -
  67. $account->balance = bcsub($account->balance, $params['amount']);
  68. }
  69. if ($account->balance < 0) throw new \Exception("余额不足,账户金额为: " .
  70. bcmul(empty($balance) ? 0 : $balance, 0.01, 2));
  71. if (!$account->save()) throw new \Exception($account->getErrorMessage());
  72. $params['before_amount'] = $balance;
  73. $params['after_amount'] = $account->balance;
  74. }
  75. $model = new QiShangTongBalanceLog();
  76. $model->loadDefaultValues();
  77. if (!$model->load($params, '') || !$model->save()) throw new \Exception($model->getErrorMessage());
  78. $t->commit();
  79. } catch (\Exception $exception) {
  80. $t->rollBack();
  81. return $exception->getMessage();
  82. }
  83. return $model;
  84. }
  85. /**
  86. * 充值
  87. * @param array $params
  88. * @param $admin
  89. * @return string|QiShangTongBalanceLog
  90. */
  91. public function recharge(array $params, $admin)
  92. {
  93. $data = [
  94. 'mall_id' => $params['mall_id'],
  95. 'amount' => abs($params['amount']),
  96. 'remark' => "ID为[{$admin['id']}]的雇员,为商城[{$params['mall_id']}]操作金额为[{$params['amount']}],其备注信息为[{$params['remark']}]",
  97. 'type' => $params['amount'] > 0 ? QiShangTongEnums::BALANCE_LOG_TYPE_RECHARGE : QiShangTongEnums::BALANCE_LOG_TYPE_DEDUCT,
  98. 'direction' => $params['amount'] > 0 ? 1 : 2,
  99. 'order_no' => Order::generateOrderNo('RC'),
  100. 'addons' => AddonsEnum::ADDONS_NAME_QI_SHANG_TONG
  101. ];
  102. return $this->create($data);
  103. }
  104. /**
  105. * @param array $params
  106. * @return mixed|string|true|null
  107. */
  108. public function setRate(array $params)
  109. {
  110. $account = QiShangTongBalance::findOne(['mall_id' => $params['mall_id']]);
  111. if (empty($account)) {
  112. $account = new QiShangTongBalance();
  113. $account->mall_id = $params['mall_id'];
  114. }
  115. $account->{$params['field']} = bcmul($params['val'], 100);
  116. if (!$account->save()) return $account->getErrorMessage();
  117. try {
  118. (new GoodsService())->changePrice($params['mall_id']);
  119. } catch (\Exception $e) {
  120. return $e->getMessage();
  121. }
  122. return true;
  123. }
  124. public function statistics(array $params)
  125. {
  126. $rQuery = QiShangTongBalanceLog::find()->where(['direction' => 1]);
  127. $dQuery = QiShangTongBalanceLog::find()->where(['direction' => 2]);
  128. if (!empty($params['mall_id'])) {
  129. $rQuery->andWhere(['mall_id' => $params['mall_id']]);
  130. $dQuery->andWhere(['mall_id' => $params['mall_id']]);
  131. }
  132. $r = $rQuery->sum('amount');
  133. $d = $dQuery->sum('amount');
  134. return [
  135. 'recharge' => !empty($r) ? $r : 0,
  136. 'deduct' => !empty($d) ? $d : 0,
  137. ];
  138. }
  139. public static function asyncRefund(int $id)
  140. {
  141. \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_ORDER, RabbitMqEnum::ORDER_QUEUE, ['id' => $id],
  142. self::class, 'refund');
  143. }
  144. public function refund($params)
  145. {
  146. if (empty($params) || empty($params['id'])) return true;
  147. $id = $params['id'];
  148. $t = \Yii::$app->db->beginTransaction();
  149. try {
  150. $fund = QiShangTongBalanceLog::findOne($id);
  151. if (empty($fund)) return true;
  152. $fund->status = StatusEnum::DELETE;
  153. if (!$fund->save()) throw new \Exception($fund->getErrorMessage());
  154. $mall = QiShangTongBalance::findOne(['mall_id' => $fund->mall_id]);
  155. $mall->balance += $fund->amount;
  156. if (!$mall->save()) throw new \Exception($mall->getErrorMessage());
  157. $t->commit();
  158. } catch (\Exception $e) {
  159. $t->rollBack();
  160. \Yii::error(FormatHelper::exception($e, __METHOD__));
  161. return false;
  162. }
  163. return true;
  164. }
  165. }