IntegralController.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <?php
  2. namespace app\modules\client\controllers\v1\integralAppreciation;
  3. use app\models\IntegralAppreciationPool;
  4. use app\models\IntegralAppreciationPoolSub;
  5. use app\models\IntegralAppreciationTransferIntegralLog;
  6. use app\models\IntegralAppreciationUser;
  7. use app\models\Option;
  8. use app\models\User;
  9. use app\modules\client\controllers\BaseController;
  10. use app\modules\client\models\v1\integralAppreciation\IntegralForm;
  11. class IntegralController extends BaseController
  12. {
  13. /**
  14. * 积分记录
  15. */
  16. public function actionList() {
  17. $form = new IntegralForm();
  18. $form->attributes = get_params();
  19. $form->store_id = get_store_id();
  20. $form->user = get_user();
  21. return $this->asJson($form->getList());
  22. }
  23. //积分转赠
  24. public function actionGiveAssets() {
  25. $form = new IntegralForm();
  26. $form->attributes = post_params();
  27. $form->store_id = get_store_id();
  28. $form->user = get_user();
  29. return $this->asJson($form->giveAssets());
  30. }
  31. //积分信息
  32. public function actionGetUserIntegral() {
  33. $form = new IntegralForm();
  34. $form->attributes = post_params();
  35. $form->store_id = get_store_id();
  36. $form->user = get_user();
  37. return $this->asJson($form->getUserIntegral());
  38. }
  39. /**
  40. * 增值积分和余额互转
  41. */
  42. public function actionTransfer() {
  43. $type = input_params('type', '1'); //1:积分转余额 2:余额转积分
  44. $amount = input_params('amount', '0'); //数量
  45. $store_id = get_store_id();
  46. //获取增值积分配置信息
  47. $integral_appreciation_setting = Option::get('integral_appreciation_setting', $store_id, 'integral_appreciation')['value'];
  48. $integral_appreciation_setting = json_decode($integral_appreciation_setting ?? '', true);
  49. $is_open_integral_to_balance = $integral_appreciation_setting['is_open_integral_to_balance'] ?? 0; //是否开启积分转余额
  50. $is_open_balance_to_integral = $integral_appreciation_setting['is_open_balance_to_integral'] ?? 0; //是否开启余额转积分
  51. $integral_to_balance_min = $integral_appreciation_setting['integral_to_balance_min'] ?? 0; //积分转余额最小金额
  52. $balance_to_integral_min = $integral_appreciation_setting['balance_to_integral_min'] ?? 0; //余额转积分最小金额
  53. $integral_to_balance_max = $integral_appreciation_setting['integral_to_balance_max'] ?? 0;//积分转余额最大金额
  54. $balance_to_integral_max = $integral_appreciation_setting['balance_to_integral_max'] ?? 0; //余额转积分最大金额
  55. $integral_to_balance_fee = $integral_appreciation_setting['integral_to_balance_fee'] ?? 0; //积分转余额手续费比利
  56. $balance_to_integral_fee = $integral_appreciation_setting['balance_to_integral_fee'] ?? 0; //余额转积分手续费比利
  57. if(!$amount){
  58. return $this->asJson(['code'=>1, 'msg'=>'兑换数量不正确']);
  59. }
  60. $uid = get_user_id();
  61. if($type==1){
  62. if($is_open_integral_to_balance==0){
  63. return $this->asJson(['code'=>1, 'msg'=>'未开启积分转余额功能']);
  64. }
  65. if($integral_to_balance_min && $amount<$integral_to_balance_min){
  66. return $this->asJson(['code'=>1, 'msg'=>'积分转余额最小金额不能低于'.$integral_to_balance_min]);
  67. }
  68. if($integral_to_balance_max && $amount>$integral_to_balance_max){
  69. return $this->asJson(['code'=>1, 'msg'=>'积分转余额最大金额不能高于'.$integral_to_balance_max]);
  70. }
  71. $t = \Yii::$app->db->beginTransaction();
  72. try{
  73. //查看用户的增值积分
  74. $integral = 0;
  75. $integralAppreciationUser = IntegralAppreciationUser::findOne(['user_id' => $uid]);
  76. if($integralAppreciationUser){
  77. $integral = $integralAppreciationUser->integral;
  78. }else{
  79. $integralAppreciationUser = new IntegralAppreciationUser();
  80. $integralAppreciationUser->user_id = $uid;
  81. $integralAppreciationUser->store_id = $store_id;
  82. if (!$integralAppreciationUser->save()) {
  83. throw new \Exception(json_encode($integralAppreciationUser->errors, JSON_UNESCAPED_UNICODE));
  84. }
  85. }
  86. if($amount > $integral){
  87. throw new \Exception('用户积分不足');
  88. }
  89. //获取当前奖金池中的积分价格
  90. $integral_price = 0;
  91. $total_amount = 0;
  92. //加锁
  93. $poolLock = \Yii::$app->db->createCommand("SELECT * FROM cyy_integral_appreciation_pool WHERE store_id = :store_id FOR UPDATE", [':store_id' => $store_id])->queryOne();
  94. if($poolLock){
  95. $pool = IntegralAppreciationPool::findOne($poolLock['id']);
  96. $integral_price = $poolLock['integral_price'];
  97. $total_amount = $poolLock['amount'];
  98. }else{
  99. $pool = new IntegralAppreciationPool();
  100. $pool->store_id = $store_id;
  101. }
  102. //如果没有获取到积分价格 就使用设置项中的积分初始价格
  103. if ($integral_price <= 0) {
  104. $integral_price = $integral_appreciation_setting['integral_init_price'] ?: 0;
  105. }
  106. //积分转换成余额
  107. $transfer_amount = bcmul($amount, $integral_price, 2);
  108. //减去手续费
  109. $integral_premium=0;
  110. if($integral_to_balance_fee){
  111. $integral_premium = bcdiv(bcmul($transfer_amount, $integral_to_balance_fee, 2), 100, 2);
  112. $transfer_amount = bcsub($transfer_amount, $integral_premium, 2);
  113. }
  114. if($transfer_amount > $total_amount){
  115. throw new \Exception('池子余额不足');
  116. }
  117. //增加用户余额
  118. if($transfer_amount){
  119. $user = User::findOne(['id'=>$uid,'is_delete' => 0]);
  120. $user->money = bcadd($user->money, $transfer_amount, 2);
  121. $user->save();
  122. }
  123. //扣除用户增值积分
  124. $integralAppreciationUser->integral = bcsub($integralAppreciationUser->integral, $amount, 2);
  125. $integralAppreciationUser->save();
  126. $user_total_integral = IntegralAppreciationUser::find()->where(['store_id' => $store_id])->sum('integral') ?: 0;
  127. //更新池子积分价格
  128. $amountPool = $pool->amount ?: 0;
  129. $pool->amount = bcsub($amountPool, $transfer_amount, 2);
  130. $pool->total_integral = bcadd($pool->total_integral, $amount, 2);
  131. $pool->total_user_integral = $user_total_integral;
  132. $pool->integral_price = $pool->total_integral > 0 ? round($pool->amount / $pool->total_integral, 2) : 0;
  133. $pool->save();
  134. //积分池变更记录
  135. $poolSub = new IntegralAppreciationPoolSub();
  136. $poolSub->user_id = $uid;
  137. $poolSub->store_id = $store_id;
  138. $poolSub->amount = -$transfer_amount;
  139. $poolSub->integral_price = $integral_price;
  140. $poolSub->integral = $amount;
  141. $poolSub->reflux_type=4;
  142. $poolSub->after_integral_price=$pool->integral_price;
  143. $poolSub->save();
  144. //添加转换记录
  145. $result = IntegralAppreciationTransferIntegralLog::saveIntegralLog($uid, $store_id,$amount, $transfer_amount,$integral_price, $integral_premium, 1);
  146. if ($result['code']) {
  147. throw new \Exception($result['msg']);
  148. }
  149. $t->commit();
  150. return $this->asJson(['code'=>0, 'msg'=>'操作成功']);
  151. }catch (\Exception $e){
  152. $t->rollBack();
  153. return $this->asJson(['code'=>1, 'msg'=>$e->getMessage()]);
  154. }
  155. }else{
  156. if($is_open_balance_to_integral==0){
  157. return $this->asJson(['code'=>1, 'msg'=>'未开启余额转积分功能']);
  158. }
  159. if($balance_to_integral_min && $amount<$balance_to_integral_min){
  160. return $this->asJson(['code'=>1, 'msg'=>'余额转积分最小金额不能低于'.$balance_to_integral_min]);
  161. }
  162. if($balance_to_integral_max && $amount>$balance_to_integral_max){
  163. return $this->asJson(['code'=>1, 'msg'=>'余额转积分最大金额不能高于'.$balance_to_integral_max]);
  164. }
  165. $t = \Yii::$app->db->beginTransaction();
  166. try{
  167. $user = User::findOne(['id'=>$uid,'is_delete' => 0]);
  168. if($user->money < $amount){
  169. throw new \Exception('用户余额不足');
  170. }
  171. //获取当前奖金池中的积分价格
  172. $integral_price = 0;
  173. $total_integral = 0;
  174. //加锁
  175. $poolLock = \Yii::$app->db->createCommand("SELECT * FROM cyy_integral_appreciation_pool WHERE store_id = :store_id FOR UPDATE", [':store_id' => $store_id])->queryOne();
  176. if($poolLock){
  177. $pool = IntegralAppreciationPool::findOne($poolLock['id']);
  178. $integral_price = $poolLock['integral_price'];
  179. $total_integral = $poolLock['total_integral'];
  180. }else{
  181. $pool = new IntegralAppreciationPool();
  182. $pool->store_id = $store_id;
  183. }
  184. //如果没有获取到积分价格 就使用设置项中的积分初始价格
  185. if ($integral_price <= 0) {
  186. $integral_price = $integral_appreciation_setting['integral_init_price'] ?: 0;
  187. }
  188. //余额转换成积分
  189. $transfer_amount = bcdiv($amount, $integral_price, 2);
  190. //减去手续费
  191. $integral_premium = 0;
  192. if($balance_to_integral_fee){
  193. $integral_premium = bcdiv(bcmul($transfer_amount, $balance_to_integral_fee, 2), 100, 2);
  194. $transfer_amount = bcsub($transfer_amount, $integral_premium, 2);
  195. }
  196. if($transfer_amount > $total_integral){
  197. throw new \Exception('池子积分不足');
  198. }
  199. //减去用户余额
  200. $user->money = bcsub($user->money, $amount, 2);
  201. $user->save();
  202. //增加增值积分
  203. if($transfer_amount){
  204. $integralAppreciationUser = IntegralAppreciationUser::findOne(['user_id' => $uid]);
  205. if (!$integralAppreciationUser) {
  206. $integralAppreciationUser = new IntegralAppreciationUser();
  207. $integralAppreciationUser->user_id = $uid;
  208. $integralAppreciationUser->store_id = $store_id;
  209. if (!$integralAppreciationUser->save()) {
  210. throw new \Exception(json_encode($integralAppreciationUser->errors, JSON_UNESCAPED_UNICODE));
  211. }
  212. }
  213. $integralAppreciationUser->total_integral = bcadd($integralAppreciationUser->total_integral, $transfer_amount, 2);
  214. $integralAppreciationUser->integral = bcadd($integralAppreciationUser->integral, $transfer_amount, 2);
  215. if (!$integralAppreciationUser->save()) {
  216. throw new \Exception(json_encode($integralAppreciationUser->errors, JSON_UNESCAPED_UNICODE));
  217. }
  218. $user_total_integral = IntegralAppreciationUser::find()->where(['store_id' => $store_id])->sum('integral') ?: 0;
  219. //更新池子积分价格
  220. $amountPool = $pool->amount ?: 0;
  221. $pool->amount = bcadd($amountPool, $amount, 2);
  222. $pool->total_integral = bcsub($pool->total_integral, $transfer_amount, 2);
  223. $pool->total_user_integral = $user_total_integral;
  224. $pool->integral_price = $pool->total_integral > 0 ? round($pool->amount / $pool->total_integral, 2) : 0;
  225. $pool->save();
  226. //积分池变更记录
  227. $poolSub = new IntegralAppreciationPoolSub();
  228. $poolSub->store_id = $store_id;
  229. $poolSub->user_id = $uid;
  230. $poolSub->amount = $amount;
  231. $poolSub->integral_price = $integral_price;
  232. $poolSub->integral = -$transfer_amount;
  233. $poolSub->reflux_type=4;
  234. $poolSub->after_integral_price=$pool->integral_price;
  235. $poolSub->save();
  236. //添加转化记录
  237. $result = IntegralAppreciationTransferIntegralLog::saveIntegralLog($uid,$store_id, $amount, $transfer_amount,$integral_price, $integral_premium, 2);
  238. if ($result['code']) {
  239. throw new \Exception('添加转换记录失败'.$result['msg']);
  240. }
  241. }
  242. $t->commit();
  243. return $this->asJson(['code'=>0, 'msg'=>'操作成功']);
  244. }catch (\Exception $e){
  245. $t->rollBack();
  246. return $this->asJson(['code'=>1, 'msg'=>$e->getMessage()]);
  247. }
  248. }
  249. }
  250. /**
  251. * 积分余额互换记录
  252. */
  253. public function actionTransferList() {
  254. $type = input_params('type', 0); //1:积分转余额 2:余额转积分
  255. $time = input_params('time', ''); //年月
  256. $uid = get_user_id();
  257. $query = IntegralAppreciationTransferIntegralLog::find()->where(['user_id' => $uid]);
  258. if($type){
  259. $query->andWhere(['type' => $type]);
  260. }
  261. if ($time) {
  262. $start_time = strtotime($time);
  263. if (strpos($time, '-') !== false) {
  264. $end_time = strtotime('+1 month', strtotime($time));
  265. } else {
  266. $start_time = strtotime($time . '-01-01');
  267. $end_time = strtotime('+1 year', strtotime($time . '-01-01'));
  268. }
  269. $query->andWhere(['AND', ['>=', 'created_at', $start_time], ['<=', 'created_at', $end_time]]);
  270. }
  271. $query->orderBy('id DESC');
  272. $pagination = pagination_make($query);
  273. foreach ($pagination['list'] as &$item) {
  274. $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']);
  275. }
  276. return $this->asJson(['code'=>0, 'msg'=>'操作成功', 'data'=>$pagination]);
  277. }
  278. }