PointToLoveService.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <?php
  2. /****************************************************************
  3. * Author: libaojia
  4. * Date: 2017/11/22 下午2:10
  5. * Email: livsyitian@163.com
  6. * QQ: 995265288
  7. * User: 芸众商城 www.yunzshop.com
  8. ****************************************************************/
  9. namespace app\common\services\finance;
  10. use app\common\facades\Setting;
  11. use app\common\models\Member;
  12. use app\common\models\Order;
  13. use Carbon\Carbon;
  14. use Illuminate\Support\Facades\DB;
  15. use Illuminate\Support\Facades\Log;
  16. use Yunshop\Love\Common\Services\LoveChangeService;
  17. class PointToLoveService
  18. {
  19. private $pointSet;
  20. private $pointAmount;
  21. private $orderCycleAmount;
  22. public function handleTransferQueue($uniacid)
  23. {
  24. Setting::$uniqueAccountId = \YunShop::app()->uniacid = $uniacid;
  25. $result = $this->transferStart();
  26. if ($result !== true) {
  27. \Log::info('--积分自动转入爱心值Uniacid:' . $uniacid . '自动转入失败--');
  28. }
  29. \Log::info('--积分自动转入爱心值Uniacid:' . $uniacid . '自动转入完成--');
  30. }
  31. private function pointSet()
  32. {
  33. return Setting::get('point.set');
  34. }
  35. /**
  36. * 积分持有总和,作为除数,不能返回零
  37. *
  38. * @return float
  39. */
  40. private function pointAmount()
  41. {
  42. if (!isset($this->pointAmount)) $this->pointAmount = $this->_pointAmount();
  43. return $this->pointAmount ?: 1;
  44. }
  45. /**
  46. * _积分持有总和
  47. *
  48. * @return float
  49. */
  50. private function _pointAmount()
  51. {
  52. //todo 需要排除已删除会员持有
  53. return Member::uniacid()->sum('credit1');
  54. }
  55. /**
  56. * 周期订单总和
  57. *
  58. * @return float
  59. */
  60. private function orderCycleAmount()
  61. {
  62. if (!isset($this->orderCycleAmount)) $this->orderCycleAmount = $this->_orderCycleAmount();
  63. return $this->orderCycleAmount;
  64. }
  65. /**
  66. * _周期订单总和
  67. *
  68. * @return float
  69. */
  70. private function _orderCycleAmount()
  71. {
  72. return Order::uniacid()->whereBetween('finish_time', $this->getTimeSlot())->sum('price');
  73. }
  74. /**
  75. * 周期时间:每周/每天
  76. *
  77. * @return array
  78. */
  79. private function getTimeSlot()
  80. {
  81. if ($this->pointSet['transfer_cycle'] == 1) {
  82. $startTime = Carbon::now()->subWeek(1)->startOfWeek()->timestamp;
  83. $endTime = Carbon::now()->subWeek(1)->endOfWeek()->timestamp;
  84. } else {
  85. $startTime = Carbon::yesterday()->startOfDay()->timestamp;
  86. $endTime = Carbon::yesterday()->endOfDay()->timestamp;
  87. }
  88. return [$startTime, $endTime];
  89. }
  90. private function changeValue($memberPoint, $rate)
  91. {
  92. if ($this->pointSet['transfer_compute_mode'] == 1) {
  93. $amount = bcdiv(bcmul($this->orderCycleAmount(), $rate, 4), 100, 4);
  94. $point = bcmul(bcdiv($amount, $this->pointAmount(), 4), $memberPoint, 2);
  95. } else {
  96. $point = bcdiv(bcmul($memberPoint, $rate, 4), 100, 2);
  97. }
  98. return $point;
  99. }
  100. public function transferStart()
  101. {
  102. $this->pointSet = $this->pointSet();
  103. $members = Member::uniacid()->where('credit1', '>', 0)->with('pointLove')->get();
  104. foreach ($members as $key => $member) {
  105. $rate = $this->getRate($member);
  106. $change_value = $this->changeValue($member->credit1, $rate);
  107. if ($change_value <= 0) {
  108. continue;
  109. }
  110. DB::beginTransaction();
  111. try {
  112. $point_change_data = [
  113. 'point_income_type' => PointService::POINT_INCOME_LOSE,
  114. 'point_mode' => PointService::POINT_MODE_TRANSFER_LOVE,
  115. 'member_id' => $member->uid,
  116. 'point' => -$change_value,
  117. 'remark' => '积分自动转入:' . $change_value . '转入比例:' . $rate,
  118. ];
  119. //修改用户积分
  120. $result = (new PointService($point_change_data))->changePoint();
  121. if (!$result) {
  122. Log::info('积分自动转入爱心值失败', print_r($point_change_data, true));
  123. DB::rollBack();
  124. continue;
  125. }
  126. $change_value = $this->getExchange($member, $change_value);
  127. $love_change_data = [
  128. 'member_id' => $member->uid,
  129. 'change_value' => $change_value,
  130. 'operator' => 0,
  131. 'operator_id' => 0,
  132. 'remark' => '积分自动转入:' . $change_value . '转入比例:' . $rate,
  133. 'relation' => ''
  134. ];
  135. //修改爱心值
  136. $result = (new LoveChangeService())->pointTransfer($love_change_data);
  137. if (!$result) {
  138. Log::info('积分自动转入爱心值失败', print_r($love_change_data, true));
  139. DB::rollBack();
  140. continue;
  141. }
  142. DB::commit();
  143. } catch (\Exception $e) {
  144. Log::info('积分自动转入爱心值失败' . $e->getMessage(), print_r($love_change_data, true));
  145. DB::rollBack();
  146. continue;
  147. }
  148. }
  149. return true;
  150. }
  151. private function getRate($memberModel)
  152. {
  153. //如果转入类型是营业额,直接只用全局比例
  154. if ($this->pointSet['transfer_compute_mode'] == 1) {
  155. return $this->pointSet['transfer_love_rate'] ?: 0;
  156. }
  157. $set = $this->pointSet;
  158. $rate = 0;
  159. //如果全局比例为空、为零
  160. if (empty($set['transfer_love_rate'])) {
  161. $rate = 0;
  162. }
  163. //全局比例设置
  164. if (isset($set['transfer_love_rate']) && $set['transfer_love_rate'] > 0) {
  165. $rate = $set['transfer_love_rate'];
  166. }
  167. //会员独立设置判断
  168. if (isset($memberModel->pointLove) && $memberModel->pointLove->rate > 0) {
  169. $rate = $memberModel->pointLove->rate;
  170. }
  171. //独立设置为 -1,跳过此会员
  172. if (isset($memberModel->pointLove) && $memberModel->pointLove->rate == -1) {
  173. $rate = 0;
  174. }
  175. return $rate;
  176. }
  177. private function getExchange($memberModel, $change_value)
  178. {
  179. $set = Setting::get('point.set');
  180. $transfer_integral = 1;
  181. $transfer_love = 1;
  182. //如果全局比例为空
  183. if (empty($set['transfer_integral']) || empty($set['transfer_integral_love'])) {
  184. $transfer_integral = 1;
  185. $transfer_love = 1;
  186. }
  187. //全局比例设置
  188. if (isset($set['transfer_integral']) && $set['transfer_integral'] > 0) {
  189. $transfer_integral = $set['transfer_integral'];
  190. }
  191. //全局比例设置
  192. if (isset($set['transfer_integral_love']) && $set['transfer_integral_love'] > 0) {
  193. $transfer_love = $set['transfer_integral_love'];
  194. }
  195. //会员独立设置判断
  196. if (isset($memberModel->pointLove) && $memberModel->pointLove > 0) {
  197. //判断会员是否单独设置积分转入爱心值比例
  198. if ($memberModel->pointLove->transfer_love && $memberModel->pointLove->transfer_integral) {
  199. $transfer_love = $memberModel->pointLove->transfer_love;
  200. $transfer_integral = $memberModel->pointLove->transfer_integral;
  201. }
  202. }
  203. $rate = bcmul(bcdiv($transfer_love, $transfer_integral, 4), $change_value, 2);
  204. return $rate;
  205. }
  206. }