MemberLevelOrder.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace addon\supermember\model;
  11. use addon\coupon\model\Coupon;
  12. use app\model\member\Member;
  13. use app\model\member\MemberAccount;
  14. use app\model\member\MemberLevel;
  15. use app\model\system\Cron;
  16. use app\model\system\Pay;
  17. use app\model\system\Stat;
  18. use think\facade\Cache;
  19. use app\model\BaseModel;
  20. use app\model\order\Config;
  21. /**
  22. * 会员卡订单
  23. */
  24. class MemberLevelOrder extends BaseModel
  25. {
  26. // 订单待支付
  27. const ORDER_CREATE = 0;
  28. // 订单已支付
  29. const ORDER_PAY = 1;
  30. // 订单已关闭
  31. const ORDER_CLOSE = -1;
  32. /**
  33. * 基础支付方式(不考虑实际在线支付方式或者货到付款方式)
  34. * @var unknown
  35. */
  36. public $pay_type = [
  37. 'ONLINE_PAY' => '在线支付',
  38. 'OFFLINE_PAY' => '线下支付',
  39. 'BALANCE' => '余额支付'
  40. ];
  41. /**
  42. * 获取支付方式
  43. * @return unknown
  44. */
  45. public function getPayType()
  46. {
  47. //获取订单基础的其他支付方式
  48. $pay_type = $this->pay_type;
  49. //获取当前所有在线支付方式
  50. $onlinepay = event('PayType', []);
  51. if (!empty($onlinepay)) {
  52. foreach ($onlinepay as $k => $v) {
  53. $pay_type[$v['pay_type']] = $v['pay_type_name'];
  54. }
  55. }
  56. return $pay_type;
  57. }
  58. /**
  59. * 订单创建
  60. * @param $data
  61. */
  62. public function create($data){
  63. //获取用户头像
  64. $member_model = new Member();
  65. $member = $member_model->getMemberInfo([['member_id', '=', $data['member_id']]], 'headimg,nickname,member_level');
  66. $member_info = $member['data'];
  67. // 获取卡信息
  68. $level_info = model('member_level')->getInfo([ ['level_id', '=', $data['level_id'] ],['site_id', '=', $data['site_id'] ] ]);
  69. if (empty($level_info)) return $this->error('', '未获取到会员卡信息');
  70. if ($level_info['level_type'] == 0) return $this->error('', '免费卡无需购买');
  71. $charge_rule = json_decode($level_info['charge_rule'], true);
  72. if (!isset($charge_rule[ $data['period_unit'] ]) && empty($charge_rule[ $data['period_unit'] ])) return $this->error('', '该会员卡未配置该收费规则');
  73. $order_money = $charge_rule[ $data['period_unit'] ];
  74. $pay = new Pay();
  75. if (isset($data['out_trade_no'])) {
  76. $out_trade_no = $data['out_trade_no'];
  77. } else {
  78. $out_trade_no = $pay->createOutTradeNo($data['member_id']);
  79. }
  80. $order_no = $this->createOrderNo($data['site_id'], $data['member_id']);
  81. $order_type = $member_info['member_level'] == $data['level_id'] ? 2 : 1; // 1购卡 2续费
  82. model('member_level_order')->startTrans();
  83. try {
  84. $create_data = [
  85. 'site_id' => $data['site_id'],
  86. 'order_no' => $order_no,
  87. 'out_trade_no' => $out_trade_no,
  88. 'level_name' => $level_info['level_name'],
  89. 'level_id' => $level_info['level_id'],
  90. 'order_type' => $order_type,
  91. 'charge_type' => $level_info['charge_type'],
  92. 'period_unit' => $data['period_unit'],
  93. 'buy_num' => 1,
  94. 'order_money' => $order_money,
  95. 'buyer_id' => $data['member_id'],
  96. 'nickname' => $member_info['nickname'],
  97. 'headimg' => $member_info['headimg'],
  98. 'create_time' => time()
  99. ];
  100. // 添加订单
  101. $order_id = model('member_level_order')->add($create_data);
  102. if (!isset($data['out_trade_no'])) {
  103. //生成支付单据
  104. $pay_body = $order_type == 1 ? '购买会员卡' : '会员卡续费';
  105. $pay->addPay($data['site_id'], $out_trade_no, "", $pay_body, $pay_body, $order_money, '', 'MemberLevelOrderPayNotify', '');
  106. }
  107. //计算订单自动关闭时间
  108. $config_model = new Config();
  109. $order_config_result = $config_model->getOrderEventTimeConfig($data['site_id']);
  110. $order_config = $order_config_result["data"];
  111. $now_time = time();
  112. if (!empty($order_config)) {
  113. $execute_time = $now_time + $order_config["value"]["auto_close"] * 60;//自动关闭时间
  114. } else {
  115. $execute_time = $now_time + 3600;//尚未配置 默认一天
  116. }
  117. $cron_model = new Cron();
  118. $cron_model->addCron(1, 0, "订单自动关闭", "MemberLevelOrderClose", $execute_time, $order_id);
  119. model("member_level_order")->commit();
  120. return $this->success(['out_trade_no' => $out_trade_no, 'order_id' => $order_id]);
  121. } catch (\Exception $e) {
  122. model('member_level_order')->rollback();
  123. return $this->error('', $e->getMessage());
  124. }
  125. }
  126. /**
  127. * 会员卡订单支付回调
  128. * @param $data
  129. */
  130. public function orderPay($data){
  131. $order_info = model('member_level_order')->getInfo([ ['out_trade_no', '=', $data['out_trade_no']] ]);
  132. if (!empty($order_info) && $order_info['order_status'] == self::ORDER_CREATE) {
  133. model('member_level_order')->startTrans();
  134. try {
  135. $pay_list = $this->getPayType();
  136. $order_id = $order_info['order_id'];
  137. $site_id = $order_info['site_id'];
  138. $pay_type_name = '';
  139. if (!empty($data['pay_type'])) {
  140. $pay_type_name = $pay_list[$data['pay_type']];
  141. }
  142. //修改订单状态
  143. $order_data = [
  144. 'pay_type' => $data['pay_type'],
  145. 'pay_type_name' => $pay_type_name,
  146. 'pay_time' => time(),
  147. 'order_status' => self::ORDER_PAY
  148. ];
  149. $res = model('member_level_order')->update($order_data, [['out_trade_no', '=', $data['out_trade_no']]]);
  150. // 会员卡付费类型是充值
  151. $member_account = new MemberAccount();
  152. if ($order_info['charge_type'] == 1) {
  153. $member_account->addMemberAccount($order_info['site_id'], $order_info['buyer_id'], 'balance', $order_info['order_money'], 'memberlevel', '0', '会员开卡充值');
  154. }
  155. // 查询会员信息
  156. $member_info = model('member')->getInfo([ ['member_id', '=', $order_info['buyer_id'] ] ]);
  157. // 查询会员卡信息
  158. $level_info = model('member_level')->getInfo([ ['level_id', '=', $order_info['level_id'] ] ]);
  159. // 如果是首次开卡发放开卡礼包
  160. $count = model('member_level_records')->getCount([ ['after_level_id', '=', $level_info['level_id']], ['member_id', '=', $order_info['buyer_id']] ]);
  161. if ($count == 0) {
  162. //赠送红包
  163. if ($level_info['send_balance'] > 0) {
  164. $member_account->addMemberAccount($order_info['site_id'], $order_info['buyer_id'], 'balance', $level_info['send_balance'], 'memberlevel', '会员开卡得红包' . $level_info['send_balance'], '会员开卡奖励发放');
  165. }
  166. //赠送积分
  167. if ($level_info['send_point'] > 0) {
  168. $member_account->addMemberAccount($order_info['site_id'], $order_info['buyer_id'], 'point', $level_info['send_point'], 'memberlevel', '会员开卡得积分' . $level_info['send_point'], '会员开卡奖励发放');
  169. }
  170. //给用户发放优惠券
  171. if (!empty($level_info['send_coupon'])) {
  172. $coupon_array = explode(',', $level_info['send_coupon']);
  173. $coupon_model = new Coupon();
  174. $coupon_array = array_map(function ($value){
  175. return ['coupon_type_id' => $value, 'num' => 1];
  176. }, $coupon_array);
  177. $coupon_model->giveCoupon($coupon_array, $order_info['site_id'], $order_info['buyer_id'], 5);
  178. }
  179. }
  180. if ($member_info['member_level'] != $level_info['level_id']) {
  181. if ($order_info['period_unit'] == 'quarter') {
  182. $expire_time = strtotime("+3 month");
  183. } else {
  184. $expire_time = strtotime("+{$order_info['buy_num']} {$order_info['period_unit']}");
  185. }
  186. // 添加会员卡变更记录
  187. $member_level_model = new MemberLevel();
  188. $member_level_model->addMemberLevelChangeRecord($order_info['buyer_id'], $order_info['site_id'], $level_info['level_id'], $expire_time, 'buy', $order_info['buyer_id'], 'member', $member_info['nickname']);
  189. } else {
  190. $old_expire_time = date('Y-m-d', $member_info['level_expire_time']);
  191. if ($order_info['period_unit'] == 'quarter') {
  192. $expire_time = strtotime("{$old_expire_time} +3 month");
  193. } else {
  194. $expire_time = strtotime("{$old_expire_time} +{$order_info['buy_num']} {$order_info['period_unit']}");
  195. }
  196. // 更新会员卡过期时间
  197. model('member')->update(['level_expire_time' => $expire_time],[ ['member_id', '=', $order_info['buyer_id'] ]]);
  198. $cron = new Cron();
  199. $cron->deleteCron([ ['event', '=', 'MemberLevelAutoExpire'], ['relate_id', '=', $order_info['buyer_id'] ] ]);
  200. $cron->addCron(1, 0, "会员卡自动过期", "MemberLevelAutoExpire", $expire_time, $order_info['buyer_id']);
  201. }
  202. $stat_model = new Stat();
  203. $stat_model->switchStat(['type' => 'member_level_order', 'data' => ['order_id' => $order_id, 'site_id' => $site_id]]);
  204. model('member_level_order')->commit();
  205. return $this->success();
  206. } catch (\Exception $e) {
  207. model('member_level_order')->rollback();
  208. return $this->error('', $e->getMessage());
  209. }
  210. }
  211. }
  212. /**
  213. * 生成订单编号
  214. *
  215. * @param array $site_id
  216. */
  217. public function createOrderNo($site_id, $member_id = 0)
  218. {
  219. $time_str = date('YmdHi');
  220. $max_no = Cache::get($site_id . "_" . $member_id . "_" . $time_str);
  221. if (!isset($max_no) || empty($max_no)) {
  222. $max_no = 1;
  223. } else {
  224. $max_no = $max_no + 1;
  225. }
  226. $order_no = $time_str . $member_id . sprintf("%03d", $max_no);
  227. Cache::set($site_id . "_" . $member_id . "_" . $time_str, $max_no);
  228. return $order_no;
  229. }
  230. /**
  231. * 关闭会员卡订单
  232. */
  233. public function closeLevelOrder($order_id) {
  234. $res = model('member_level_order')->update([ 'order_status' => self::ORDER_CLOSE ], [ ['order_id', '=', $order_id], ['order_status', '=', self::ORDER_CREATE] ]);
  235. return $this->success($res);
  236. }
  237. /**
  238. * 获取会员卡订单列表
  239. * @param array $condition
  240. * @param string $field
  241. * @param string $order
  242. * @param int $page
  243. * @param int $list_rows
  244. * @param string $alias
  245. * @param array $join
  246. * @return array
  247. */
  248. public function getLevelOrderPageList($condition = [], $page = 1, $list_rows = PAGE_LIST_ROWS, $field = '*', $order = 'create_time desc', $alias = 'a', $join = []){
  249. $list = model('member_level_order')->pageList($condition, $field, $order, $page, $list_rows, $alias, $join);
  250. return $this->success($list);
  251. }
  252. /**
  253. * 获取会员卡订单信息
  254. * @param array $where
  255. * @param bool $field
  256. * @param string $alias
  257. * @param null $join
  258. * @return array
  259. */
  260. public function getLevelOrderInfo($where = [], $field = '*', $alias = 'a', $join = null){
  261. $data = model('member_level_order')->getInfo($where, $field, $alias, $join);
  262. return $this->success($data);
  263. }
  264. /**
  265. * 线下支付
  266. * @param $out_trade_no
  267. * @return array
  268. */
  269. public function offlinePay($out_trade_no){
  270. model('member_level_order')->startTrans();
  271. try {
  272. $pay_model = new Pay();
  273. $result = $pay_model->onlinePay($out_trade_no, "OFFLINE_PAY", '', '');
  274. if ($result["code"] < 0) {
  275. model('order')->rollback();
  276. return $result;
  277. }
  278. model('order')->commit();
  279. return $result;
  280. } catch (\Exception $e) {
  281. model('member_level_order')->rollback();
  282. return $this->error('', $e->getMessage());
  283. }
  284. }
  285. /**
  286. * 查询订单总数
  287. * @param $condition
  288. * @return array
  289. */
  290. public function getOrderCount($condition, $field = '*', $alias = 'a', $join = null, $group = null){
  291. $count = model('member_level_order')->getCount($condition, $field, $alias, $join, $group);
  292. return $this->success($count);
  293. }
  294. /**
  295. * 查询订单总数
  296. * @param $condition
  297. * @param $filed
  298. * @return array
  299. */
  300. public function getOrderSum($condition, $filed){
  301. $sum = model('member_level_order')->getSum($condition, $filed);
  302. return $this->success($sum);
  303. }
  304. }