UserWallet.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. <?php
  2. /**
  3. * 厦门云联储网络科技有限公司
  4. * https://www.baokuaiyun.com
  5. * Copyright (c) 2023 爆块云 All rights reserved.
  6. */
  7. namespace app\models;
  8. use app\jobs\AiCloudInventoryMemberJob;
  9. use app\logic\CurrencyLogic;
  10. use Exception;
  11. use Yii;
  12. use yii\behaviors\TimestampBehavior;
  13. use yii\db\ActiveRecord;
  14. /**
  15. * This is the model class for table "{{%user_wallet}}".
  16. * @property int id ID
  17. * @property int store_id
  18. * @property int user_id
  19. * @property int saas_id
  20. * @property float money
  21. * @property float money_total
  22. * @property float frozen
  23. * @property float withdraw
  24. * @property string currency_code
  25. * @property int created_at
  26. * @property int updated_at
  27. */
  28. class UserWallet extends \yii\db\ActiveRecord
  29. {
  30. /**
  31. * 商城订单
  32. */
  33. const TYPE_ORDER = 'order';
  34. /**
  35. * 当面付
  36. */
  37. const TYPE_SCAN = 'scan';
  38. /**
  39. * 合伙人
  40. */
  41. const TYPE_PARTNER = 'partner';
  42. const TYPE_STORE_UNION = 'store_union';
  43. const TYPE_UNIT_FOUNDER = 'unit_founder';
  44. /**
  45. * 红包
  46. */
  47. const TYPE_RED_PACKET = 'red_packet';
  48. /**
  49. * 提现
  50. */
  51. const TYPE_CASH = 'cash';
  52. /**
  53. * 后台改动
  54. */
  55. const TYPE_OPERATOR_BACK = 'operator_back';
  56. const TYPE_NAME_LIST = array(
  57. self::TYPE_ORDER => '商城订单',
  58. self::TYPE_SCAN => '当面付',
  59. self::TYPE_RED_PACKET => '串码红包',
  60. self::TYPE_CASH => '提现',
  61. self::TYPE_OPERATOR_BACK => '后台充值',
  62. );
  63. /**
  64. * {@inheritdoc}
  65. */
  66. public static function tableName()
  67. {
  68. return '{{%user_wallet}}';
  69. }
  70. public function behaviors()
  71. {
  72. return [
  73. [
  74. 'class' => TimestampBehavior::class,
  75. 'attributes' => [
  76. ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
  77. ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at']
  78. ]
  79. ]
  80. ];
  81. }
  82. /**
  83. * {@inheritdoc}
  84. */
  85. public function rules()
  86. {
  87. return [
  88. [['store_id', 'user_id', 'saas_id'], 'integer'],
  89. [['money', 'money_total', 'frozen', 'withdraw'], 'number'],
  90. [['created_at', 'updated_at'], 'safe'],
  91. [['currency_code'], 'string', 'max' => 50],
  92. ];
  93. }
  94. /**
  95. * {@inheritdoc}
  96. */
  97. public function attributeLabels()
  98. {
  99. return [
  100. 'id' => 'ID',
  101. 'store_id' => '店铺id',
  102. 'user_id' => '用户id',
  103. 'saas_id' => '联盟id',
  104. 'money' => '余额',
  105. 'money_total' => '余额总金额',
  106. 'frozen' => '冻结',
  107. 'withdraw' => '提现',
  108. 'currency_code' => '业务货币代码',
  109. 'created_at' => '创建时间',
  110. 'updated_at' => '更新时间',
  111. ];
  112. }
  113. /**
  114. * 获取用户业务货币钱包
  115. */
  116. public static function getCurrencyWallet($store_id, $user_id, $currency_code)
  117. {
  118. $currency = Currency::findOne(['code' => $currency_code]);
  119. $wallet = self::find()->where(['user_id' => $user_id, 'store_id' => $store_id, 'currency_code' => $currency_code])->one();
  120. if (empty($wallet)) {
  121. $wallet = new self();
  122. $wallet->store_id = $store_id;
  123. $wallet->user_id = $user_id;
  124. if ($store_id == -1) {
  125. $wallet->saas_id = $user_id;
  126. } else {
  127. $wallet->saas_id = SaasUser::findSaasIdByUserId($user_id);
  128. }
  129. $wallet->currency_code = $currency_code;
  130. if (!$wallet->save()) {
  131. $msg = "店铺:{$store_id},业务:{$currency_code},用户:{$user_id} 钱包保存失败" . json_encode($wallet->getErrors());
  132. //debug_log([__METHOD__, __LINE__, $msg], "app_debug.log");
  133. }
  134. }
  135. $wallet->money = round($wallet->money, $currency->scale);
  136. $wallet->money_total = round($wallet->money_total, $currency->scale);
  137. $wallet->frozen = round($wallet->frozen, $currency->scale);
  138. $wallet->withdraw = round($wallet->withdraw, $currency->scale);
  139. return $wallet;
  140. }
  141. public static function getCurrencyWalletBalance($saas_id, $currency_code)
  142. {
  143. $currency = Currency::findOne(['code' => $currency_code]);
  144. $total = UserWallet::find()->where([
  145. 'saas_id' => $saas_id,
  146. 'currency_code' => $currency_code
  147. ])->select("SUM(`money`) as total")->scalar();
  148. return $total > 0 ? round($total, $currency->scale) : 0;
  149. }
  150. /**
  151. * 新增余额操作
  152. * @param $currency
  153. * @param $user_id
  154. * @param $store_id
  155. * @param $money
  156. * @param $desc
  157. * @param $type
  158. * @param string $source_table
  159. * @param int $source_id
  160. * @param bool $reduce_frozen
  161. * @return boolean
  162. */
  163. public static function addLog($currency, $store_id, $user_id, $money, $desc, $type, string $source_table = '', int $source_id = 0,$new_store_id=0,$award_type="")
  164. {
  165. $trans = Yii::$app->db->beginTransaction();
  166. try {
  167. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} enable:{$currency['enable']} =============="], "app_debug.log");
  168. if ($currency['enable'] == 0) throw new Exception('货币' . $currency['code'] . '未开启');
  169. if ($money == 0 || empty($user_id)) {
  170. throw new Exception("用户 $user_id 不存在或金额为0");
  171. }
  172. if($store_id != -1){
  173. $moblie = \Yii::$app->db->createCommand("
  174. SELECT binding
  175. FROM cyy_user
  176. WHERE store_id=:store_id
  177. AND id = :id
  178. ")
  179. ->bindValue(':store_id', $store_id)
  180. ->bindValue(':id', $user_id)
  181. ->queryScalar();
  182. $user_id_new = \Yii::$app->db->createCommand("
  183. SELECT id
  184. FROM cyy_saas_user
  185. WHERE mobile=:mobile
  186. ")
  187. ->bindValue(':mobile', $moblie)
  188. ->queryScalar();
  189. if(!empty($user_id_new)){
  190. $user_id = $user_id_new;
  191. }
  192. }
  193. $user_wallet = self::getCurrencyWallet(-1, $user_id, $currency['code']);
  194. if (($money + $user_wallet->money) < 0) {
  195. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} 不足 =============="], "app_debug.log");
  196. throw new Exception($currency['name'] . '不足');
  197. }
  198. $admin_info = \Yii::$app->db->createCommand("
  199. SELECT *
  200. FROM cyy_store
  201. WHERE id = :storeId
  202. ", [
  203. ':storeId' => $new_store_id
  204. ])->queryOne();
  205. $change_status = 0;
  206. $change_status_one = 0;
  207. /*if(!empty($award_type)){
  208. if(!empty($admin_info['award_type'])){
  209. $new_types = explode(',',$admin_info['award_type']);
  210. if(in_array($award_type,$new_types)){
  211. $saas_user = \Yii::$app->db->createCommand("
  212. SELECT *
  213. FROM cyy_saas_user
  214. WHERE id=:id
  215. ")
  216. ->bindValue(':id', $user_id)
  217. ->queryOne();
  218. if(!empty($saas_user)){
  219. if($money>$saas_user['total_amount']){
  220. $change_status = 1;
  221. }else{
  222. $change_status_one = 1;
  223. }
  224. }
  225. }
  226. }
  227. }*/
  228. if($change_status ==0){
  229. /*if($change_status_one == 1){
  230. \Yii::$app->db->createCommand("
  231. UPDATE cyy_saas_user
  232. SET total_amount = total_amount - :money
  233. WHERE id = :id
  234. ")
  235. ->bindValue(':id', $user_id)
  236. ->bindValue(':money', $money)
  237. ->execute();
  238. }*/
  239. $user_wallet = self::getCurrencyWallet(-1, $user_id, $currency['code']);
  240. if (($money + $user_wallet->money) < 0) {
  241. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} 不足 =============="], "app_debug.log");
  242. throw new Exception($currency['name'] . '不足');
  243. }
  244. if ($money < 0 && $user_wallet->money <= abs($money)) {
  245. $money = -$user_wallet->money;
  246. }
  247. $before_money = $user_wallet->money ?? 0;
  248. $user_wallet->money += $money * 1;
  249. if ($money > 0) {
  250. $user_wallet->money_total += $money * 1;
  251. }
  252. if (!$user_wallet->save()) throw new Exception($user_wallet->getErrorMessage());
  253. //获取日志类
  254. $currency_logic = new CurrencyLogic($currency);
  255. $model = $currency_logic->getModel('wallet_log');
  256. if ($model === false) {
  257. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} 用户钱包日志模型获取失败 =============="], "app_debug.log");
  258. throw new Exception("用户钱包日志模型获取失败");
  259. }
  260. $model->store_id = $store_id;
  261. $model->user_id = $user_id;
  262. $model->saas_id = $user_wallet->saas_id;
  263. $model->currency_code = $currency['code'];
  264. $model->money = $money;
  265. $model->before_money = $before_money;
  266. $model->type = $type;
  267. $model->source_table = $source_table;
  268. $model->source_id = $source_id;
  269. $model->desc = $desc;
  270. if (!$model->save()) {
  271. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} model保存失败 =============="], "app_debug.log");
  272. throw new Exception($model->getErrorMessage());
  273. }
  274. $trans->commit();
  275. // 升级成为Ai云库存会员
  276. $aiCloudInventoryMemberJob = new AiCloudInventoryMemberJob(['saasId' => $user_wallet->saas_id,'storeId'=>$store_id]);
  277. if (!queue_push($aiCloudInventoryMemberJob)) { //推送失败再推送一次
  278. queue_push($aiCloudInventoryMemberJob);
  279. }
  280. return $model->id;
  281. }else{
  282. \Yii::$app->db->createCommand("
  283. UPDATE cyy_saas_user
  284. SET wait_amount = wait_amount + :money
  285. WHERE id = :id
  286. ")
  287. ->bindValue(':id', $user_id)
  288. ->bindValue(':money', $money)
  289. ->execute();
  290. $trans->commit();
  291. }
  292. } catch (Exception $e) {
  293. $trans->rollBack();
  294. //debug_log([__METHOD__, __LINE__, "用户钱包保存失败:{$e->getMessage()}"], "app_wallet_debug.log");
  295. return false;
  296. }
  297. }
  298. /**
  299. * 新增余额操作
  300. * @param $currency
  301. * @param $user_id
  302. * @param $store_id
  303. * @param $money
  304. * @param $desc
  305. * @param $type
  306. * @param string $source_table
  307. * @param int $source_id
  308. * @param bool $reduce_frozen
  309. * @return boolean
  310. */
  311. public static function addLogNew($currency, $store_id, $user_id, $money, $desc, $type, string $source_table = '', int $source_id = 0)
  312. {
  313. $trans = Yii::$app->db->beginTransaction();
  314. try {
  315. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} enable:{$currency['enable']} =============="], "app_debug.log");
  316. if ($currency['enable'] == 0) throw new Exception('货币' . $currency['code'] . '未开启');
  317. if ($money == 0 || empty($user_id)) {
  318. throw new Exception("用户 $user_id 不存在或金额为0");
  319. }
  320. $user_wallet = self::getCurrencyWallet($store_id, $user_id, $currency['code']);
  321. if (($money + $user_wallet->money) < 0) {
  322. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} 不足 =============="], "app_debug.log");
  323. throw new Exception($currency['name'] . '不足');
  324. }
  325. if ($money < 0 && $user_wallet->money <= abs($money)) {
  326. $money = -$user_wallet->money;
  327. }
  328. $before_money = $user_wallet->money ?? 0;
  329. $user_wallet->money += $money * 1;
  330. if ($money > 0) {
  331. $user_wallet->money_total += $money * 1;
  332. }
  333. if (!$user_wallet->save()) throw new Exception($user_wallet->getErrorMessage());
  334. //获取日志类
  335. $currency_logic = new CurrencyLogic($currency);
  336. $model = $currency_logic->getModel('wallet_log');
  337. if ($model === false) {
  338. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} 用户钱包日志模型获取失败 =============="], "app_debug.log");
  339. throw new Exception("用户钱包日志模型获取失败");
  340. }
  341. $model->store_id = $store_id;
  342. $model->user_id = $user_id;
  343. $model->saas_id = $user_wallet->saas_id;
  344. $model->currency_code = $currency['code'];
  345. $model->money = $money;
  346. $model->before_money = $before_money;
  347. $model->type = $type;
  348. $model->source_table = $source_table;
  349. $model->source_id = $source_id;
  350. $model->desc = $desc;
  351. if (!$model->save()) {
  352. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} model保存失败 =============="], "app_debug.log");
  353. throw new Exception($model->getErrorMessage());
  354. }
  355. $trans->commit();
  356. // 升级成为Ai云库存会员
  357. $aiCloudInventoryMemberJob = new AiCloudInventoryMemberJob(['saasId' => $user_wallet->saas_id,'storeId'=>$store_id]);
  358. if (!queue_push($aiCloudInventoryMemberJob)) { //推送失败再推送一次
  359. queue_push($aiCloudInventoryMemberJob);
  360. }
  361. return $model->id;
  362. } catch (Exception $e) {
  363. $trans->rollBack();
  364. //debug_log([__METHOD__, __LINE__, "用户钱包保存失败:{$e->getMessage()}"], "app_wallet_debug.log");
  365. return false;
  366. }
  367. }
  368. //用于拒绝提现
  369. public static function addLogRef($currency, $store_id, $user_id, $money, $desc, $type, string $source_table = '', int $source_id = 0, bool $reduce_frozen = false)
  370. {
  371. $trans = Yii::$app->db->beginTransaction();
  372. try {
  373. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} enable:{$currency['enable']} =============="], "app_debug.log");
  374. if ($currency['enable'] == 0) throw new Exception('货币' . $currency['code'] . '未开启');
  375. if ($money == 0 || empty($user_id)) {
  376. throw new Exception("用户 $user_id 不存在或金额为0");
  377. }
  378. $user_wallet = self::getCurrencyWallet($store_id, $user_id, $currency['code']);
  379. if (($money + $user_wallet->money) < 0) {
  380. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} 不足 =============="], "app_debug.log");
  381. throw new Exception($currency['name'] . '不足');
  382. }
  383. if ($money < 0 && $user_wallet->money <= abs($money)) {
  384. $money = -$user_wallet->money;
  385. }
  386. $before_money = $user_wallet->money ?? 0;
  387. $user_wallet->money += $money * 1;
  388. //不需要加到累计消费
  389. // if ($money > 0) {
  390. // $user_wallet->money_total += $money * 1;
  391. // }
  392. if (!$user_wallet->save()) throw new Exception($user_wallet->getErrorMessage());
  393. //获取日志类
  394. $currency_logic = new CurrencyLogic($currency);
  395. $model = $currency_logic->getModel('wallet_log');
  396. if ($model === false) {
  397. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} 用户钱包日志模型获取失败 =============="], "app_debug.log");
  398. throw new Exception("用户钱包日志模型获取失败");
  399. }
  400. $model->store_id = $store_id;
  401. $model->user_id = $user_id;
  402. $model->saas_id = $user_wallet->saas_id;
  403. $model->currency_code = $currency['code'];
  404. $model->money = $money;
  405. $model->before_money = $before_money;
  406. $model->type = $type;
  407. $model->source_table = $source_table;
  408. $model->source_id = $source_id;
  409. $model->desc = $desc;
  410. if (!$model->save()) {
  411. // //debug_log([__METHOD__, __LINE__, "============== UserWallet addLog money:{$money} user_id:{$user_id} currency:{$currency['code']} model保存失败 =============="], "app_debug.log");
  412. throw new Exception($model->getErrorMessage());
  413. }
  414. $trans->commit();
  415. return $model->id;
  416. } catch (Exception $e) {
  417. $trans->rollBack();
  418. //debug_log([__METHOD__, __LINE__, "用户钱包保存失败:{$e->getMessage()}"], "app_wallet_debug.log");
  419. return false;
  420. }
  421. }
  422. }