user_mcards.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. declare(strict_types=1);
  3. namespace mcard;
  4. use \Exception;
  5. class user_mcards
  6. {
  7. private $mCardModel;
  8. private $mUserId;
  9. private $mCards = [];
  10. public function __construct($userid)
  11. {
  12. $this->mUserId = $userid;
  13. $this->mCardModel = Model('member_card');
  14. $this->load_cards();
  15. }
  16. public function hasCards() {
  17. foreach ($this->mCards as $key => $cards) {
  18. if(!empty($cards)) {
  19. return true;
  20. }
  21. }
  22. return false;
  23. }
  24. public function left_amount()
  25. {
  26. $total = 0.00;
  27. foreach ($this->mCards as $key => $cards) {
  28. if($key != 'period') {
  29. foreach ($cards as $card) {
  30. $total += $card->left_amount();
  31. }
  32. }
  33. }
  34. return round($total,2);
  35. }
  36. public function addCard($params)
  37. {
  38. $type = intval($params['card_type']);
  39. $discount = round(doubleval($params['discount']), 2);
  40. $data = ['member_id' => $this->mUserId, 'card_type' => $type,
  41. 'discount' => $discount,
  42. 'state' => STATE_USING, 'add_time' => time()];
  43. if ($type === AmountType) {
  44. $amount = round(doubleval($params['total_amount']), 2);
  45. $data['total_amount'] = $amount;
  46. $data['left_amount'] = $amount;
  47. } elseif ($type === PeriodType) {
  48. $data['package_type'] = $this->package_type($params['package_type']);
  49. } elseif ($type === BothType) {
  50. $amount = round(doubleval($params['total_amount']), 2);
  51. $data['total_amount'] = $amount;
  52. $data['left_amount'] = $amount;
  53. $data['package_type'] = $this->package_type($params['package_type']);
  54. } else {
  55. return false;
  56. }
  57. if (isset($data['package_type'])) {
  58. [$start, $end] = $this->calc_time($data['package_type']);
  59. $data['start_time'] = $start;
  60. $data['end_time'] = $end;
  61. }
  62. $ret = $this->mCardModel->addCard($data);
  63. if ($ret > 0) {
  64. $this->load_cards();
  65. return true;
  66. } else {
  67. return false;
  68. }
  69. }
  70. private function calc_time($type)
  71. {
  72. $start = time();
  73. if ($type == MonthPachage) {
  74. $end = strtotime('+1 months 1 day', $start);
  75. } elseif ($type == QuarterPackage) {
  76. $end = strtotime('+3 months 1 day', $start);
  77. } else {
  78. $end = strtotime('+1 year 1 day', $start);
  79. }
  80. $end = strtotime(date('Y-m-d', $end));
  81. $start = strtotime(date('Y-m-d', $start));
  82. return [$start, $end];
  83. }
  84. private function package_type($package)
  85. {
  86. $package = strtolower($package);
  87. if ($package == 'month') {
  88. return MonthPachage;
  89. } elseif ($package == 'quarter') {
  90. return QuarterPackage;
  91. } elseif ($package == 'year') {
  92. return YearPackage;
  93. } else {
  94. throw new Exception("会员卡时间类型错误.");
  95. }
  96. }
  97. private function load_cards()
  98. {
  99. $this->mCards['amount'] = [];
  100. $this->mCards['period'] = [];
  101. $this->mCards['aperiod'] = [];
  102. $cards = $this->mCardModel->getUsableCards($this->mUserId);
  103. foreach ($cards as $item)
  104. {
  105. $card_type = intval($item['card_type']);
  106. if ($card_type == AmountType) {
  107. $card = new amount_card($item);
  108. $name = 'amount';
  109. } elseif ($card_type == PeriodType) {
  110. $card = new period_card($item);
  111. $name = 'period';
  112. } else {
  113. $card = new amount_period_card($item);
  114. $name = 'aperiod';
  115. }
  116. if ($card->usable()) {
  117. $this->mCards[$name][] = $card;
  118. }
  119. }
  120. }
  121. public function enough($amount)
  122. {
  123. if (!empty($this->mCards['period'])) return true;
  124. $total = 0.0;
  125. $total += $this->account($this->mCards['aperiod']);
  126. $total += $this->account($this->mCards['amount']);
  127. return intval($total * 100) >= intval($amount * 100);
  128. }
  129. public function calc_price($goods_id,$price)
  130. {
  131. if(canUseVip($goods_id)) {
  132. return $this->_calc_amount($price);
  133. } else {
  134. return $price;
  135. }
  136. }
  137. public function calc_amount($goods_id,$amount)
  138. {
  139. if(canUseVip($goods_id)) {
  140. return $this->_calc_amount($amount);
  141. } else {
  142. return $amount;
  143. }
  144. }
  145. private function _calc_amount($amount)
  146. {
  147. if($this->enough($amount))
  148. {
  149. $amount = intval($amount * 100);
  150. $total_price = 0.00;
  151. $calc_price = function (card $card, int $cent) use(&$total_price)
  152. {
  153. [$consumer,$useup,$price] = $card->calc($cent);
  154. $total_price += $price;
  155. return $consumer;
  156. };
  157. foreach ($this->mCards['aperiod'] as $card) {
  158. if ($amount <= 0) {
  159. break;
  160. } else {
  161. $amount -= $calc_price($card, $amount);
  162. }
  163. }
  164. foreach ($this->mCards['amount'] as $card) {
  165. if ($amount <= 0) {
  166. break;
  167. } else {
  168. $amount -= $calc_price($card, $amount);
  169. }
  170. }
  171. return $total_price;
  172. }
  173. else {
  174. return $amount;
  175. }
  176. }
  177. private function account($cards)
  178. {
  179. $total = 0.0;
  180. foreach ($cards as $card) {
  181. $total += $card->left_amount();
  182. }
  183. return $total;
  184. }
  185. public function deduct($amount)
  186. {
  187. if (!empty($this->mCards['period'])) return true;
  188. $amount = intval($amount * 100);
  189. $self = $this;
  190. $deduct_money = function (card $card, int $cent) use($self)
  191. {
  192. [$consumer,$useup] = $card->deduct($cent);
  193. $self->mCardModel->detuct($card->card_id(),$consumer,$useup);
  194. //增加消费额度减少记录
  195. return $consumer;
  196. };
  197. foreach ($this->mCards['aperiod'] as $card) {
  198. if ($amount <= 0) {
  199. break;
  200. } else {
  201. $amount -= $deduct_money($card, $amount);
  202. }
  203. }
  204. foreach ($this->mCards['amount'] as $card) {
  205. if ($amount <= 0) {
  206. break;
  207. } else {
  208. $amount -= $deduct_money($card, $amount);
  209. }
  210. }
  211. $this->load_cards();
  212. return ($amount <= 0);
  213. }
  214. }