Buyvirtual.php 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  1. <?php
  2. namespace app\common\logic;
  3. use think\facade\Db;
  4. /**
  5. * ============================================================================
  6. *
  7. * ============================================================================
  8. *
  9. * ----------------------------------------------------------------------------
  10. *
  11. * ============================================================================
  12. * 逻辑层模型
  13. */
  14. class Buyvirtual
  15. {
  16. /**
  17. * 虚拟商品购买第一步,得到购买数据(商品、店铺、会员)
  18. * @param int $goods_id 商品ID
  19. * @param int $quantity 购买数量
  20. * @param int $member_id 会员ID
  21. * @return array
  22. */
  23. public function getBuyStep1Data($goods_id, $quantity, $member_id)
  24. {
  25. return $this->getBuyStepData($goods_id, $quantity, $member_id);
  26. }
  27. /**
  28. * 虚拟商品购买第二步,得到购买数据(商品、店铺、会员)
  29. * @param int $goods_id 商品ID
  30. * @param int $quantity 购买数量
  31. * @param int $member_id 会员ID
  32. * @return array
  33. */
  34. public function getBuyStep2Data($goods_id, $quantity, $member_id, $extra = array())
  35. {
  36. return $this->getBuyStepData($goods_id, $quantity, $member_id, $extra);
  37. }
  38. /**
  39. * 得到虚拟商品购买数据(商品、店铺、会员)
  40. * @param int $goods_id 商品ID
  41. * @param int $quantity 购买数量
  42. * @param int $member_id 会员ID
  43. * @return array
  44. */
  45. public function getBuyStepData($goods_id, $quantity, $member_id, $extra = array())
  46. {
  47. $goods_model = model('goods');
  48. $goods_info = $goods_model->getGoodsOnlineInfoAndPromotionById($goods_id);
  49. if (empty($goods_info)) {
  50. return ds_callback(false, '该商品不符合购买条件,可能的原因有:下架、不存在、过期等');
  51. }
  52. $result2 = $goods_model->getGoodsCommonInfoByID($goods_info['goods_commonid']);
  53. $goods_info = array_merge($result2, $goods_info);
  54. if ($goods_info['is_virtual'] != 1 || ($goods_info['virtual_type'] == 0 && $goods_info['virtual_indate'] < TIMESTAMP)) {
  55. return ds_callback(false, '该商品不符合购买条件,可能的原因有:下架、不存在、过期等');
  56. }
  57. if ($goods_info['virtual_limit'] > $goods_info['goods_storage']) {
  58. $goods_info['virtual_limit'] = $goods_info['goods_storage'];
  59. }
  60. if (isset($extra['pintuan_id']) && intval($extra['pintuan_id']) > 0) {
  61. //如果是特定拼团商品,则只按照拼团的规则进行处理
  62. model('buy_1', 'logic')->getPintuanInfo($goods_info, $quantity, $extra, $member_id);
  63. } else {
  64. //取得抢购信息
  65. $goods_info = $this->_getGroupbuyInfo($goods_info);
  66. }
  67. $quantity = abs(intval($quantity));
  68. $quantity = $quantity == 0 ? 1 : $quantity;
  69. $quantity = $quantity > $goods_info['virtual_limit'] ? $goods_info['virtual_limit'] : $quantity;
  70. if ($quantity > $goods_info['goods_storage']) {
  71. return ds_callback(false, '该商品库存不足');
  72. }
  73. $goods_info['quantity'] = $quantity;
  74. $goods_info['goods_total'] = ds_price_format($goods_info['goods_price'] * $goods_info['quantity']);
  75. $goods_info['goods_original_total'] = ds_price_format($goods_info['goods_original_price'] * $goods_info['quantity']);
  76. $goods_info['goods_discount_total'] = ds_price_format($goods_info['goods_original_total'] - $goods_info['goods_total']);
  77. $goods_info['goods_image_url'] = goods_cthumb($goods_info['goods_image'], 240, $goods_info['store_id']);
  78. $return = array();
  79. $return['goods_info'] = $goods_info;
  80. $return['store_info'] = model('store')->getStoreOnlineInfoByID($goods_info['store_id'], 'store_name,store_id,member_id');
  81. $return['member_info'] = model('member')->getMemberInfoByID($member_id);
  82. // $pd_payment_info = model('payment')->getPaymentOpenInfo(array('payment_code'=>'predeposit'));
  83. // if (empty($pd_payment_info)) {
  84. // $return['member_info']['available_predeposit'] = 0;
  85. // $return['member_info']['available_rc_balance'] = 0;
  86. // }
  87. //返回店铺可用的代金券
  88. $return['store_voucher_list'] = array();
  89. if (config('ds_config.voucher_allow')) {
  90. $voucher_model = model('voucher');
  91. $condition = array();
  92. $condition[] = array('voucher_store_id', '=', $goods_info['store_id']);
  93. $condition[] = array('voucher_owner_id', '=', $member_id);
  94. $return['store_voucher_list'] = $voucher_model->getCurrentAvailableVoucher($condition, $goods_info['goods_total']);
  95. }
  96. //返回平台可用的代金券
  97. $return['mall_voucher_list'] = array();
  98. if (config('ds_config.voucher_allow')) {
  99. $goods_info['goods_num'] = $goods_info['quantity'];
  100. $goods_list[0] = $goods_info;
  101. $condition = array();
  102. $condition[] = array('mallvoucheruser_ownerid', '=', $member_id);
  103. $condition[] = array('mallvoucheruser_goodsid', '=', $goods_info['goods_id']);
  104. $return['mall_voucher_list'] = model('buy_1', 'logic')->getAvailableMallVoucherUserList($goods_list, $member_id);
  105. }
  106. return ds_callback(true, '', $return);
  107. }
  108. /**
  109. * 虚拟商品购买第三步
  110. * @param array $post 接收POST数据,必须传入goods_id:商品ID,quantity:购买数量,buyer_phone:接收手机,buyer_msg:买家留言
  111. * @param int $member_id
  112. * @return array
  113. */
  114. public function buyStep3($post, $member_id)
  115. {
  116. $result = $this->getBuyStepData($post['goods_id'], $post['quantity'], $member_id, $post);
  117. if (!$result['code'])
  118. return $result;
  119. $goods_info = $result['data']['goods_info'];
  120. $member_info = $result['data']['member_info'];
  121. $goods_info['store_voucher_list'] = isset($result['data']['store_voucher_list']) ? $result['data']['store_voucher_list'] : array();
  122. $goods_info['mall_voucher_list'] = isset($result['data']['mall_voucher_list']) ? $result['data']['mall_voucher_list'] : array();
  123. //应付总金额计算
  124. $pay_total = $goods_info['goods_price'] * $goods_info['quantity'];
  125. $store_id = $goods_info['store_id'];
  126. $store_goods_total_list = array($store_id => $pay_total);
  127. $pay_total = $store_goods_total_list[$store_id];
  128. if ($goods_info['virtual_type'] == 0) {
  129. if ($post['buyer_phone'] == encrypt_show($member_info['member_mobile'], 4, 4)) {
  130. $post['buyer_phone'] = $member_info['member_mobile'];
  131. }
  132. } else {
  133. $post['buyer_phone'] = '';
  134. }
  135. //整理数据
  136. $input = array();
  137. $input['quantity'] = $goods_info['quantity'];
  138. $input['buyer_phone'] = $post['buyer_phone'];
  139. $input['buyer_msg'] = $post['buyer_msg'];
  140. $input['pay_total'] = $pay_total;
  141. $input['order_from'] = $post['order_from'];
  142. $input['pintuan_id'] = isset($post['pintuan_id']) ? $post['pintuan_id'] : 0;
  143. $input['pintuangroup_id'] = isset($post['pintuangroup_id']) ? $post['pintuangroup_id'] : 0;
  144. $goods_model = model('goods');
  145. $input['voucher'] = isset($post['voucher']) ? $post['voucher'] : '';
  146. $input['mallvoucher'] = isset($post['mallvoucher']) ? $post['mallvoucher'] : '';
  147. try {
  148. //开始事务
  149. Db::startTrans();
  150. //生成订单
  151. $order_info = $this->_createOrder($input, $goods_info, $member_info);
  152. //生成推广记录
  153. $this->addOrderInviter($order_info);
  154. //变更库存和销量
  155. $res = $goods_model->createOrderUpdateStorage(array($goods_info['goods_id'] => $goods_info['quantity']), $goods_info['virtual_type'] > 1 ? true : false);
  156. if (!$res['code']) {
  157. throw new \think\Exception($res['msg'], 10006);
  158. }
  159. //提交事务
  160. Db::commit();
  161. } catch (Exception $e) {
  162. //回滚事务
  163. Db::rollback();
  164. return ds_callback(false, $e->getMessage());
  165. }
  166. //更新抢购信息
  167. $this->_updateGroupBuy($goods_info);
  168. return ds_callback(true, '', array('order_id' => $order_info['order_id'], 'order_sn' => $order_info['order_sn']));
  169. }
  170. /**
  171. * 生成推广记录
  172. * @param array $order_list
  173. */
  174. public function addOrderInviter($order = array())
  175. {
  176. if (!config('ds_config.inviter_open')) {
  177. return;
  178. }
  179. if (empty($order) || !is_array($order))
  180. return;
  181. $inviter_ratio_1 = config('ds_config.inviter_ratio_1');
  182. $inviter_ratio_2 = config('ds_config.inviter_ratio_2');
  183. $inviter_ratio_3 = config('ds_config.inviter_ratio_3');
  184. $orderinviter_model = model('orderinviter');
  185. $order_id = $order['order_id'];
  186. $goods = $order;
  187. //查询商品的分销信息
  188. $goods_common_info = Db::name('goodscommon')->alias('gc')->join('goods g', 'g.goods_commonid=gc.goods_commonid')->where('g.goods_id=' . $goods['goods_id'])->field('gc.goods_commonid,gc.inviter_open,gc.inviter_ratio')->find();
  189. if (!$goods_common_info['inviter_open']) {
  190. return;
  191. }
  192. $goods_amount = $order['order_amount'] * $goods_common_info['inviter_ratio'] / 100;
  193. $inviter_ratios = array(
  194. $inviter_ratio_1,
  195. $inviter_ratio_2,
  196. $inviter_ratio_3,
  197. );
  198. //判断买家是否是分销员
  199. if (config('ds_config.inviter_return')) {
  200. if (Db::name('inviter')->where('inviter_state=1 AND inviter_id=' . $order['buyer_id'])->value('inviter_id')) {
  201. if (isset($inviter_ratios[0]) && floatval($inviter_ratios[0]) > 0) {
  202. $ratio = round($inviter_ratios[0] * $goods_common_info['inviter_ratio'] / 100, 2);
  203. $money_1 = round($inviter_ratios[0] / 100 * $goods_amount, 2);
  204. if ($money_1 > 0) {
  205. //生成推广记录
  206. Db::name('orderinviter')->insert(array(
  207. 'orderinviter_addtime' => TIMESTAMP,
  208. 'orderinviter_store_name' => $order['store_name'],
  209. 'orderinviter_goods_amount' => $order['order_amount'],
  210. 'orderinviter_goods_quantity' => $goods['goods_num'],
  211. 'orderinviter_order_type' => 1,
  212. 'orderinviter_store_id' => $goods['store_id'],
  213. 'orderinviter_goods_commonid' => $goods_common_info['goods_commonid'],
  214. 'orderinviter_goods_id' => $goods['goods_id'],
  215. 'orderinviter_level' => 1,
  216. 'orderinviter_ratio' => $ratio,
  217. 'orderinviter_goods_name' => $goods['goods_name'],
  218. 'orderinviter_order_id' => $order_id,
  219. 'orderinviter_order_sn' => $order['order_sn'],
  220. 'orderinviter_member_id' => $order['buyer_id'],
  221. 'orderinviter_member_name' => $order['buyer_name'],
  222. 'orderinviter_money' => $money_1,
  223. 'orderinviter_remark' => '获得分销员返佣,佣金比例' . $ratio . '%,订单号' . $order['order_sn'],
  224. ));
  225. }
  226. }
  227. }
  228. }
  229. //一级推荐人
  230. $inviter_1_id = Db::name('member')->where('member_id', $order['buyer_id'])->value('inviter_id');
  231. if (!$inviter_1_id || !Db::name('inviter')->where('inviter_state=1 AND inviter_id=' . $inviter_1_id)->value('inviter_id')) {
  232. return;
  233. }
  234. $inviter_1 = Db::name('member')->where('member_id', $inviter_1_id)->field('inviter_id,member_id,member_name')->find();
  235. if ($inviter_1 && isset($inviter_ratios[0]) && floatval($inviter_ratios[0]) > 0) {
  236. $ratio = round($inviter_ratios[0] * $goods_common_info['inviter_ratio'] / 100, 2);
  237. $money_1 = round($inviter_ratios[0] / 100 * $goods_amount, 2);
  238. if ($money_1 > 0) {
  239. //生成推广记录
  240. Db::name('orderinviter')->insert(array(
  241. 'orderinviter_addtime' => TIMESTAMP,
  242. 'orderinviter_store_name' => $order['store_name'],
  243. 'orderinviter_goods_amount' => $order['order_amount'],
  244. 'orderinviter_goods_quantity' => $goods['goods_num'],
  245. 'orderinviter_order_type' => 1,
  246. 'orderinviter_store_id' => $goods['store_id'],
  247. 'orderinviter_goods_commonid' => $goods_common_info['goods_commonid'],
  248. 'orderinviter_goods_id' => $goods['goods_id'],
  249. 'orderinviter_level' => 1,
  250. 'orderinviter_ratio' => $ratio,
  251. 'orderinviter_goods_name' => $goods['goods_name'],
  252. 'orderinviter_order_id' => $order_id,
  253. 'orderinviter_order_sn' => $order['order_sn'],
  254. 'orderinviter_member_id' => $inviter_1['member_id'],
  255. 'orderinviter_member_name' => $inviter_1['member_name'],
  256. 'orderinviter_money' => $money_1,
  257. 'orderinviter_remark' => '获得一级推荐佣金,佣金比例' . $ratio . '%,推荐关系' . $inviter_1['member_name'] . '->' . $order['buyer_name'] . ',订单号' . $order['order_sn'],
  258. ));
  259. }
  260. }
  261. if (config('ds_config.inviter_level') <= 1) {
  262. return;
  263. }
  264. //二级推荐人
  265. $inviter_2_id = Db::name('member')->where('member_id', $inviter_1_id)->value('inviter_id');
  266. if (!$inviter_2_id || !Db::name('inviter')->where('inviter_state=1 AND inviter_id=' . $inviter_2_id)->value('inviter_id')) {
  267. return;
  268. }
  269. $inviter_2 = Db::name('member')->where('member_id', $inviter_2_id)->field('inviter_id,member_id,member_name')->find();
  270. if ($inviter_2 && isset($inviter_ratios[1]) && floatval($inviter_ratios[1]) > 0) {
  271. $ratio = round($inviter_ratios[1] * $goods_common_info['inviter_ratio'] / 100, 2);
  272. $money_2 = round($inviter_ratios[1] / 100 * $goods_amount, 2);
  273. if ($money_2 > 0) {
  274. //生成推广记录
  275. Db::name('orderinviter')->insert(array(
  276. 'orderinviter_addtime' => TIMESTAMP,
  277. 'orderinviter_store_name' => $order['store_name'],
  278. 'orderinviter_goods_amount' => $order['order_amount'],
  279. 'orderinviter_goods_quantity' => $goods['goods_num'],
  280. 'orderinviter_order_type' => 1,
  281. 'orderinviter_store_id' => $goods['store_id'],
  282. 'orderinviter_goods_commonid' => $goods_common_info['goods_commonid'],
  283. 'orderinviter_goods_id' => $goods['goods_id'],
  284. 'orderinviter_level' => 2,
  285. 'orderinviter_ratio' => $ratio,
  286. 'orderinviter_goods_name' => $goods['goods_name'],
  287. 'orderinviter_order_id' => $order_id,
  288. 'orderinviter_order_sn' => $order['order_sn'],
  289. 'orderinviter_member_id' => $inviter_2['member_id'],
  290. 'orderinviter_member_name' => $inviter_2['member_name'],
  291. 'orderinviter_money' => $money_2,
  292. 'orderinviter_remark' => '获得二级推荐佣金,佣金比例' . $ratio . '%,推荐关系' . $inviter_2['member_name'] . '->' . $inviter_1['member_name'] . '->' . $order['buyer_name'] . ',订单号' . $order['order_sn'],
  293. ));
  294. }
  295. }
  296. if (config('ds_config.inviter_level') <= 2) {
  297. return;
  298. }
  299. //三级推荐人
  300. $inviter_3_id = Db::name('member')->where('member_id', $inviter_2_id)->value('inviter_id');
  301. if (!$inviter_3_id || !Db::name('inviter')->where('inviter_state=1 AND inviter_id=' . $inviter_3_id)->value('inviter_id')) {
  302. return;
  303. }
  304. $inviter_3 = Db::name('member')->where('member_id', $inviter_3_id)->field('inviter_id,member_id,member_name')->find();
  305. if ($inviter_3 && isset($inviter_ratios[2]) && floatval($inviter_ratios[2]) > 0) {
  306. $ratio = round($inviter_ratios[2] * $goods_common_info['inviter_ratio'] / 100, 2);
  307. $money_3 = round($inviter_ratios[2] / 100 * $goods_amount, 2);
  308. if ($money_3 > 0) {
  309. //生成推广记录
  310. Db::name('orderinviter')->insert(array(
  311. 'orderinviter_addtime' => TIMESTAMP,
  312. 'orderinviter_store_name' => $order['store_name'],
  313. 'orderinviter_goods_amount' => $order['order_amount'],
  314. 'orderinviter_goods_quantity' => $goods['goods_num'],
  315. 'orderinviter_order_type' => 1,
  316. 'orderinviter_store_id' => $goods['store_id'],
  317. 'orderinviter_goods_commonid' => $goods_common_info['goods_commonid'],
  318. 'orderinviter_goods_id' => $goods['goods_id'],
  319. 'orderinviter_level' => 3,
  320. 'orderinviter_ratio' => $ratio,
  321. 'orderinviter_goods_name' => $goods['goods_name'],
  322. 'orderinviter_order_id' => $order_id,
  323. 'orderinviter_order_sn' => $order['order_sn'],
  324. 'orderinviter_member_id' => $inviter_3['member_id'],
  325. 'orderinviter_member_name' => $inviter_3['member_name'],
  326. 'orderinviter_money' => $money_3,
  327. 'orderinviter_remark' => '获得三级推荐佣金,佣金比例' . $ratio . '%,推荐关系' . $inviter_3['member_name'] . '->' . $inviter_2['member_name'] . '->' . $inviter_1['member_name'] . '->' . $order['buyer_name'] . ',订单号' . $order['order_sn'],
  328. ));
  329. }
  330. }
  331. }
  332. /**
  333. * 生成订单
  334. * @param array $input 表单数据
  335. * @param unknown $goods_info 商品数据
  336. * @param unknown $member_info 会员数据
  337. * @throws Exception
  338. * @return array
  339. */
  340. private function _createOrder($input, $goods_info, $member_info)
  341. {
  342. extract($input);
  343. $vrorder_model = model('vrorder');
  344. $goods_model = model('goods');
  345. //存储生成的订单,函数会返回该数组
  346. $order_list = array();
  347. $order = array();
  348. $order_code = array();
  349. //验证店铺代金券
  350. if (!empty($input['voucher'])) {
  351. if (preg_match_all('/^(\d+)\|(\d+)\|([\d.]+)$/', $input['voucher'], $matchs)) {
  352. if (floatval($matchs[3][0]) > 0) {
  353. $input_voucher = array();
  354. $input_voucher['vouchertemplate_id'] = $matchs[1][0];
  355. $input_voucher['voucher_price'] = $matchs[3][0];
  356. $voucher_list = $goods_info['store_voucher_list'];
  357. if (is_array($voucher_list) && isset($voucher_list[$input_voucher['vouchertemplate_id']])) {
  358. $input_voucher['voucher_id'] = $voucher_list[$input_voucher['vouchertemplate_id']]['voucher_id'];
  359. $input_voucher['voucher_code'] = $voucher_list[$input_voucher['vouchertemplate_id']]['voucher_code'];
  360. $input_voucher['voucher_owner_id'] = $voucher_list[$input_voucher['vouchertemplate_id']]['voucher_owner_id'];
  361. $input_voucher['voucher_price'] = floatval($input_voucher['voucher_price']);
  362. $order['voucher_price'] = $input_voucher['voucher_price'];
  363. $order['voucher_code'] = $input_voucher['voucher_code'];
  364. $pay_total = bcsub($pay_total, $input_voucher['voucher_price'], 2);
  365. if ($pay_total < 0) {
  366. $pay_total = 0;
  367. }
  368. } else {
  369. $input_voucher = array();
  370. }
  371. }
  372. }
  373. }
  374. //验证平台代金券
  375. if (!empty($input['mallvoucher'])) {
  376. if (preg_match_all('/^(\d+)\|([\d.]+)$/', $input['mallvoucher'], $matchs)) {
  377. if (floatval($matchs[2][0]) > 0) {
  378. $input_mallvoucher = array();
  379. $input_mallvoucher['mallvouchertemplate_id'] = $matchs[1][0];
  380. $input_mallvoucher['mallvoucheruser_price'] = $matchs[2][0];
  381. $mallvoucher_list = $goods_info['mall_voucher_list'];
  382. if (is_array($mallvoucher_list) && isset($mallvoucher_list[$input_mallvoucher['mallvouchertemplate_id']])) {
  383. $input_mallvoucher['mallvoucheruser_id'] = $mallvoucher_list[$input_mallvoucher['mallvouchertemplate_id']]['mallvoucheruser_id'];
  384. $input_mallvoucher['mallvoucheruser_code'] = $mallvoucher_list[$input_mallvoucher['mallvouchertemplate_id']]['mallvoucheruser_code'];
  385. $input_mallvoucher['mallvoucheruser_ownerid'] = $mallvoucher_list[$input_mallvoucher['mallvouchertemplate_id']]['mallvoucheruser_ownerid'];
  386. $input_mallvoucher['mallvoucheruser_price'] = floatval($input_mallvoucher['mallvoucheruser_price']);
  387. $order['mallvoucher_price'] = $input_mallvoucher['mallvoucheruser_price'];
  388. $order['mallvoucher_code'] = $input_mallvoucher['mallvoucheruser_code'];
  389. $pay_total = bcsub($pay_total, $input_mallvoucher['mallvoucheruser_price'], 2);
  390. if ($pay_total < 0) {
  391. $pay_total = 0;
  392. }
  393. } else {
  394. $input_mallvoucher = array();
  395. }
  396. }
  397. }
  398. }
  399. $order['order_sn'] = makePaySn($member_info['member_id']);
  400. $order['store_id'] = $goods_info['store_id'];
  401. $order['store_name'] = $goods_info['store_name'];
  402. $order['buyer_id'] = $member_info['member_id'];
  403. $order['buyer_name'] = $member_info['member_name'];
  404. $order['buyer_phone'] = $input['buyer_phone'];
  405. $order['buyer_msg'] = $input['buyer_msg'];
  406. $order['add_time'] = TIMESTAMP;
  407. $order['order_state'] = ORDER_STATE_NEW;
  408. $order['order_amount'] = $pay_total;
  409. $order['goods_id'] = $goods_info['goods_id'];
  410. $order['goods_name'] = $goods_info['goods_name'];
  411. $order['goods_price'] = $goods_info['goods_price'];
  412. $order['goods_num'] = $input['quantity'];
  413. $order['goods_image'] = $goods_info['goods_image'];
  414. $store_gc_id_commis_rate_list = model('storebindclass')->getStoreGcidCommisRateList(array($goods_info));
  415. $order['commis_rate'] = floatval(@$store_gc_id_commis_rate_list[$goods_info['store_id']][$goods_info['gc_id']]);
  416. $order['gc_id'] = $goods_info['gc_id'];
  417. $order['virtual_type'] = $goods_info['virtual_type'];
  418. if ($order['virtual_type'] > 0) {
  419. if ($order['virtual_type'] == 1) {
  420. $res = $goods_model->getAvailableGoodsCard($goods_info);
  421. if ($res['code']) {
  422. if ($input['quantity'] > count($res['data']['card_list'])) {
  423. throw new \think\Exception('卡券数量不足', 10006);
  424. }
  425. $virtual_content = [];
  426. for ($i = 0; $i < $input['quantity']; $i++) {
  427. $virtual_content[] = $res['data']['card_list'][$i];
  428. }
  429. $virtual_content = implode('\r\n', $virtual_content);
  430. } else {
  431. throw new \think\Exception($res['msg'], 10006);
  432. }
  433. } else {
  434. $virtual_content = $goods_info['virtual_content'];
  435. }
  436. $order['virtual_content'] = $virtual_content;
  437. }
  438. $order['vr_indate'] = $goods_info['virtual_indate'];
  439. $order['vr_invalid_refund'] = $goods_info['virtual_invalid_refund'];
  440. $order['order_from'] = $input['order_from'];
  441. $order['order_promotion_type'] = 0;
  442. if (isset($goods_info['ifgroupbuy']) && $goods_info['ifgroupbuy'] == 1) {
  443. $order['order_promotion_type'] = 1;
  444. $order['promotions_id'] = $goods_info['groupbuy_id'];
  445. } else if (isset($goods_info['ifpintuan']) && intval($input['pintuan_id']) > 0) {
  446. $order['order_promotion_type'] = 2;
  447. $order['promotions_id'] = $input['pintuangroup_id'];
  448. }
  449. $order_id = $vrorder_model->addVrorder($order);
  450. if (!$order_id) {
  451. throw new \think\Exception('订单保存失败', 10006);
  452. }
  453. $order['order_id'] = $order_id;
  454. if ($order['order_promotion_type'] == 2) {
  455. $res = model('buy_1', 'logic')->updatePintuan($input, $goods_info, $order, 1, $member_info['member_id']);
  456. if (!$order['promotions_id']) {
  457. $vrorder_model->editVrorder(array('promotions_id' => $res['pintuangroup_id']), array('order_id' => $order['order_id']));
  458. }
  459. }
  460. // 提醒[库存报警]
  461. if ($goods_info['goods_storage_alarm'] >= ($goods_info['goods_storage'] - $input['quantity'])) {
  462. $param = array();
  463. $param['common_id'] = $goods_info['goods_commonid'];
  464. $param['sku_id'] = $goods_info['goods_id'];
  465. $ten_param = array($param['common_id'], $param['sku_id']);
  466. $weixin_param = array(
  467. 'url' => config('ds_config.h5_store_site_url') . '/pages/seller/goods/GoodsForm2?commonid=' . $goods_info['goods_commonid'] . '&class_id=' . $goods_info['gc_id'],
  468. 'data' => array(
  469. "keyword1" => array(
  470. "value" => $goods_info['goods_storage'] - $input['quantity'],
  471. "color" => "#333"
  472. ),
  473. "keyword2" => array(
  474. "value" => date('Y-m-d H:i'),
  475. "color" => "#333"
  476. )
  477. ),
  478. );
  479. model('cron')->addCron(array('cron_exetime' => TIMESTAMP, 'cron_type' => 'sendStoremsg', 'cron_value' => serialize(array('code' => 'goods_storage_alarm', 'store_id' => $goods_info['store_id'], 'param' => $param, 'ali_param' => $param, 'ten_param' => $ten_param, 'weixin_param' => $weixin_param))));
  480. }
  481. //更新使用的店铺代金券状态
  482. if (!empty($input_voucher) && is_array($input_voucher)) {
  483. $input_voucher_list[0] = $input_voucher;
  484. model('voucher')->editVoucherState($input_voucher_list);
  485. }
  486. //更新使用的平台代金券状态
  487. if (!empty($input_mallvoucher) && is_array($input_mallvoucher)) {
  488. model('Mallvouchertemplate')->editMallvoucherState($input_mallvoucher);
  489. }
  490. return $order;
  491. }
  492. /**
  493. * 更新抢购购买人数和数量
  494. */
  495. private function _updateGroupBuy($goods_info)
  496. {
  497. if (isset($goods_info['ifgroupbuy']) && $goods_info['groupbuy_id']) {
  498. $groupbuy_info = array();
  499. $groupbuy_info['groupbuy_id'] = $goods_info['groupbuy_id'];
  500. $groupbuy_info['quantity'] = $goods_info['quantity'];
  501. model('cron')->addCron(array('cron_exetime' => TIMESTAMP, 'cron_type' => 'editGroupbuySaleCount', 'cron_value' => serialize($groupbuy_info)));
  502. }
  503. }
  504. /**
  505. * 充值卡支付
  506. * 如果充值卡足够就单独支付了该订单,如果不足就暂时冻结,等API支付成功了再彻底扣除
  507. */
  508. private function _rcbPay($order_info, $input, $buyer_info)
  509. {
  510. $available_rcb_amount = floatval($buyer_info['available_rc_balance']);
  511. if ($available_rcb_amount <= 0)
  512. return;
  513. if (!isset($order_info['rcb_amount'])) {
  514. $order_info['rcb_amount'] = 0;
  515. }
  516. if (!isset($order_info['pd_amount'])) {
  517. $order_info['pd_amount'] = 0;
  518. }
  519. $vrorder_model = model('vrorder');
  520. $predeposit_model = model('predeposit');
  521. $order_amount = floatval($order_info['order_amount']);
  522. $data_pd = array();
  523. $data_pd['member_id'] = $buyer_info['member_id'];
  524. $data_pd['member_name'] = $buyer_info['member_name'];
  525. $data_pd['amount'] = $order_amount;
  526. $data_pd['order_sn'] = $order_info['order_sn'];
  527. if ($available_rcb_amount >= $order_amount) {
  528. // 预存款立即支付,订单支付完成
  529. $predeposit_model->changeRcb('order_pay', $data_pd);
  530. $available_rcb_amount -= $order_amount;
  531. // 订单状态 置为已支付
  532. $data_order = array();
  533. $order_info['order_state'] = $data_order['order_state'] = ORDER_STATE_PAY;
  534. $data_order['payment_time'] = TIMESTAMP;
  535. $data_order['payment_code'] = 'predeposit';
  536. $data_order['rcb_amount'] = $order_info['order_amount'];
  537. $result = $vrorder_model->editVrorder($data_order, array('order_id' => $order_info['order_id']));
  538. if (!$result) {
  539. throw new \think\Exception('订单更新失败', 10006);
  540. }
  541. if ($order_info['order_promotion_type'] != 2) {
  542. //发放兑换码
  543. $insert = $vrorder_model->addVrorderCode($order_info);
  544. //发送兑换码到手机
  545. $param = array('order_id' => $order_info['order_id'], 'buyer_id' => $order_info['buyer_id'], 'buyer_phone' => $order_info['buyer_phone']);
  546. $vrorder_model->sendVrCode($param);
  547. // 支付成功发送店铺消息
  548. $param = array();
  549. $param['code'] = 'new_order';
  550. $param['store_id'] = $order_info['store_id'];
  551. $param['ali_param'] = array(
  552. 'order_sn' => $order_info['order_sn']
  553. );
  554. $param['ten_param'] = array(
  555. $order_info['order_sn']
  556. );
  557. $param['param'] = $param['ali_param'];
  558. $param['weixin_param'] = array(
  559. 'url' => config('ds_config.h5_store_site_url') . '/pages/seller/vrorder/OrderDetail?order_id=' . $order_info['order_id'],
  560. 'data' => array(
  561. "keyword1" => array(
  562. "value" => $order_info['order_sn'],
  563. "color" => "#333"
  564. ),
  565. "keyword2" => array(
  566. "value" => $order_info['goods_name'],
  567. "color" => "#333"
  568. ),
  569. "keyword3" => array(
  570. "value" => $order_info['order_amount'],
  571. "color" => "#333"
  572. ),
  573. "keyword4" => array(
  574. "value" => date('Y-m-d H:i', $order_info['add_time']),
  575. "color" => "#333"
  576. )
  577. ),
  578. );
  579. model('cron')->addCron(array('cron_exetime' => TIMESTAMP, 'cron_type' => 'sendStoremsg', 'cron_value' => serialize($param)));
  580. if (!$insert) {
  581. throw new \think\Exception('兑换码发送失败', 10006);
  582. }
  583. }
  584. } else {
  585. //暂冻结预存款,后面还需要 API彻底完成支付
  586. $data_pd['amount'] = $available_rcb_amount;
  587. $predeposit_model->changeRcb('order_freeze', $data_pd);
  588. //预存款支付金额保存到订单
  589. $data_order = array();
  590. $order_info['rcb_amount'] = $data_order['rcb_amount'] = $available_rcb_amount;
  591. $result = $vrorder_model->editVrorder($data_order, array('order_id' => $order_info['order_id']));
  592. if (!$result) {
  593. throw new \think\Exception('订单更新失败', 10006);
  594. }
  595. }
  596. return $order_info;
  597. }
  598. /**
  599. * 预存款支付
  600. * 如果预存款足够就单独支付了该订单,如果不足就暂时冻结,等API支付成功了再彻底扣除
  601. */
  602. private function _pdPay($order_info, $input, $buyer_info)
  603. {
  604. if ($order_info['order_state'] == ORDER_STATE_PAY)
  605. return;
  606. $available_pd_amount = floatval($buyer_info['available_predeposit']);
  607. if ($available_pd_amount <= 0)
  608. return;
  609. if (!isset($order_info['rcb_amount'])) {
  610. $order_info['rcb_amount'] = 0;
  611. }
  612. if (!isset($order_info['pd_amount'])) {
  613. $order_info['pd_amount'] = 0;
  614. }
  615. $vrorder_model = model('vrorder');
  616. $predeposit_model = model('predeposit');
  617. //充值卡支付金额
  618. $rcb_amount = isset($order_info['rcb_amount']) ? floatval($order_info['rcb_amount']) : 0;
  619. $order_amount = floatval($order_info['order_amount']) - $rcb_amount;
  620. $data_pd = array();
  621. $data_pd['member_id'] = $buyer_info['member_id'];
  622. $data_pd['member_name'] = $buyer_info['member_name'];
  623. $data_pd['amount'] = $order_amount;
  624. $data_pd['order_sn'] = $order_info['order_sn'];
  625. if ($available_pd_amount >= $order_amount) {
  626. //预存款立即支付,订单支付完成
  627. $predeposit_model->changePd('order_pay', $data_pd);
  628. $available_pd_amount -= $order_amount;
  629. //下单,支付被冻结的充值卡
  630. $pd_amount = $rcb_amount;
  631. if ($pd_amount > 0) {
  632. $data_pd = array();
  633. $data_pd['member_id'] = $buyer_info['member_id'];
  634. $data_pd['member_name'] = $buyer_info['member_name'];
  635. $data_pd['amount'] = $pd_amount;
  636. $data_pd['order_sn'] = $order_info['order_sn'];
  637. $predeposit_model->changeRcb('order_comb_pay', $data_pd);
  638. }
  639. // 订单状态 置为已支付
  640. $data_order = array();
  641. $data_order['order_state'] = ORDER_STATE_PAY;
  642. $data_order['payment_time'] = TIMESTAMP;
  643. $data_order['payment_code'] = 'predeposit';
  644. $data_order['pd_amount'] = $order_amount;
  645. $result = $vrorder_model->editVrorder($data_order, array('order_id' => $order_info['order_id']));
  646. if (!$result) {
  647. throw new \think\Exception('订单更新失败', 10006);
  648. }
  649. if ($order_info['order_promotion_type'] != 2) {
  650. //发放兑换码
  651. $vrorder_model->addVrorderCode($order_info);
  652. //发送兑换码到手机
  653. $param = array('order_id' => $order_info['order_id'], 'buyer_id' => $order_info['buyer_id'], 'buyer_phone' => $order_info['buyer_phone']);
  654. $vrorder_model->sendVrCode($param);
  655. // 支付成功发送店铺消息
  656. $param = array();
  657. $param['code'] = 'new_order';
  658. $param['store_id'] = $order_info['store_id'];
  659. $param['ali_param'] = array(
  660. 'order_sn' => $order_info['order_sn']
  661. );
  662. $param['ten_param'] = array(
  663. $order_info['order_sn']
  664. );
  665. $param['param'] = $param['ali_param'];
  666. $param['weixin_param'] = array(
  667. 'url' => config('ds_config.h5_store_site_url') . '/pages/seller/vrorder/OrderDetail?order_id=' . $order_info['order_id'],
  668. 'data' => array(
  669. "keyword1" => array(
  670. "value" => $order_info['order_sn'],
  671. "color" => "#333"
  672. ),
  673. "keyword2" => array(
  674. "value" => $order_info['goods_name'],
  675. "color" => "#333"
  676. ),
  677. "keyword3" => array(
  678. "value" => $order_info['order_amount'],
  679. "color" => "#333"
  680. ),
  681. "keyword4" => array(
  682. "value" => date('Y-m-d H:i', $order_info['add_time']),
  683. "color" => "#333"
  684. )
  685. ),
  686. );
  687. model('cron')->addCron(array('cron_exetime' => TIMESTAMP, 'cron_type' => 'sendStoremsg', 'cron_value' => serialize($param)));
  688. }
  689. } else {
  690. //暂冻结预存款,后面还需要 API彻底完成支付
  691. $data_pd['amount'] = $available_pd_amount;
  692. $predeposit_model->changePd('order_freeze', $data_pd);
  693. //预存款支付金额保存到订单
  694. $data_order = array();
  695. $data_order['pd_amount'] = $available_pd_amount;
  696. $result = $vrorder_model->editVrorder($data_order, array('order_id' => $order_info['order_id']));
  697. if (!$result) {
  698. throw new \think\Exception('订单更新失败', 10006);
  699. }
  700. }
  701. }
  702. /**
  703. * 充值卡支付
  704. * 如果充值卡足够就单独支付了该订单,如果不足就暂时冻结,等API支付成功了再彻底扣除
  705. */
  706. public function rcbPay($order_info, $input, $buyer_info)
  707. {
  708. $available_rcb_amount = floatval($buyer_info['available_rc_balance']);
  709. if ($available_rcb_amount <= 0)
  710. return $order_info;
  711. $vrorder_model = model('vrorder');
  712. $predeposit_model = model('predeposit');
  713. $order_amount = round($order_info['order_amount'] - $order_info['rcb_amount'] - $order_info['pd_amount'], 2);
  714. $data_pd = array();
  715. $data_pd['member_id'] = $buyer_info['member_id'];
  716. $data_pd['member_name'] = $buyer_info['member_name'];
  717. $data_pd['amount'] = $order_amount;
  718. $data_pd['order_sn'] = $order_info['order_sn'];
  719. if ($available_rcb_amount >= $order_amount) {
  720. // 预存款立即支付,订单支付完成
  721. $predeposit_model->changeRcb('order_pay', $data_pd);
  722. $available_rcb_amount -= $order_amount;
  723. //支付被冻结的充值卡
  724. $rcb_amount = isset($order_info['rcb_amount']) ? floatval($order_info['rcb_amount']) : 0;
  725. if ($rcb_amount > 0) {
  726. $data_pd = array();
  727. $data_pd['member_id'] = $buyer_info['member_id'];
  728. $data_pd['member_name'] = $buyer_info['member_name'];
  729. $data_pd['amount'] = $rcb_amount;
  730. $data_pd['order_sn'] = $order_info['order_sn'];
  731. $predeposit_model->changeRcb('order_comb_pay', $data_pd);
  732. }
  733. // 订单状态 置为已支付
  734. $data_order = array();
  735. $order_info['order_state'] = $data_order['order_state'] = ORDER_STATE_PAY;
  736. $data_order['payment_time'] = TIMESTAMP;
  737. $data_order['payment_code'] = 'predeposit';
  738. $data_order['rcb_amount'] = round($order_info['rcb_amount'] + $order_amount, 2);
  739. $result = $vrorder_model->editVrorder($data_order, array('order_id' => $order_info['order_id']));
  740. if (!$result) {
  741. throw new \think\Exception('订单更新失败', 10006);
  742. }
  743. if ($order_info['order_promotion_type'] != 2) {
  744. if ($order_info['virtual_type'] == 0) {
  745. //发放兑换码
  746. $insert = $vrorder_model->addVrorderCode($order_info);
  747. if (!$insert) {
  748. throw new \think\Exception('兑换码发送失败', 10006);
  749. }
  750. } else {
  751. $logic_vrorder = model('vrorder', 'logic');
  752. $result = $logic_vrorder->changeOrderStateSuccess($order_info['order_id']);
  753. if (!$result['code']) {
  754. throw new \think\Exception($result['msg'], 10006);
  755. }
  756. }
  757. }
  758. } else {
  759. //暂冻结预存款,后面还需要 API彻底完成支付
  760. $data_pd['amount'] = $available_rcb_amount;
  761. $predeposit_model->changeRcb('order_freeze', $data_pd);
  762. //预存款支付金额保存到订单
  763. $data_order = array();
  764. $order_info['rcb_amount'] = $data_order['rcb_amount'] = round($order_info['rcb_amount'] + $available_rcb_amount, 2);
  765. $result = $vrorder_model->editVrorder($data_order, array('order_id' => $order_info['order_id']));
  766. if (!$result) {
  767. throw new \think\Exception('订单更新失败', 10006);
  768. }
  769. }
  770. return $order_info;
  771. }
  772. /**
  773. * 预存款支付 主要处理
  774. * 如果预存款足够就单独支付了该订单,如果不足就暂时冻结,等API支付成功了再彻底扣除
  775. */
  776. public function pdPay($order_info, $input, $buyer_info)
  777. {
  778. if ($order_info['order_state'] == ORDER_STATE_PAY)
  779. return $order_info;
  780. $available_pd_amount = floatval($buyer_info['available_predeposit']);
  781. if ($available_pd_amount <= 0)
  782. return $order_info;
  783. $vrorder_model = model('vrorder');
  784. $predeposit_model = model('predeposit');
  785. $order_amount = round($order_info['order_amount'] - $order_info['rcb_amount'] - $order_info['pd_amount'], 2);
  786. $data_pd = array();
  787. $data_pd['member_id'] = $buyer_info['member_id'];
  788. $data_pd['member_name'] = $buyer_info['member_name'];
  789. $data_pd['amount'] = $order_amount;
  790. $data_pd['order_sn'] = $order_info['order_sn'];
  791. if ($available_pd_amount >= $order_amount) {
  792. //预存款立即支付,订单支付完成
  793. $predeposit_model->changePd('order_pay', $data_pd);
  794. $available_pd_amount -= $order_amount;
  795. //下单,支付被冻结的充值卡
  796. $pd_amount = floatval($order_info['rcb_amount']);
  797. if ($pd_amount > 0) {
  798. $data_pd = array();
  799. $data_pd['member_id'] = $buyer_info['member_id'];
  800. $data_pd['member_name'] = $buyer_info['member_name'];
  801. $data_pd['amount'] = $pd_amount;
  802. $data_pd['order_sn'] = $order_info['order_sn'];
  803. $predeposit_model->changeRcb('order_comb_pay', $data_pd);
  804. }
  805. //支付被冻结的预存款
  806. $pd_amount = isset($order_info['pd_amount']) ? floatval($order_info['pd_amount']) : 0;
  807. if ($pd_amount > 0) {
  808. $data_pd = array();
  809. $data_pd['member_id'] = $buyer_info['member_id'];
  810. $data_pd['member_name'] = $buyer_info['member_name'];
  811. $data_pd['amount'] = $pd_amount;
  812. $data_pd['order_sn'] = $order_info['order_sn'];
  813. $predeposit_model->changePd('order_comb_pay', $data_pd);
  814. }
  815. // 订单状态 置为已支付
  816. $data_order = array();
  817. $order_info['order_state'] = $data_order['order_state'] = ORDER_STATE_PAY;
  818. $order_info['payment_time'] = $data_order['payment_time'] = TIMESTAMP;
  819. $order_info['payment_code'] = $data_order['payment_code'] = 'predeposit';
  820. $order_info['pd_amount'] = $data_order['pd_amount'] = round($order_info['pd_amount'] + $order_amount, 2);
  821. $result = $vrorder_model->editVrorder($data_order, array('order_id' => $order_info['order_id']));
  822. if (!$result) {
  823. throw new \think\Exception('订单更新失败', 10006);
  824. }
  825. if ($order_info['order_promotion_type'] != 2) {
  826. if ($order_info['virtual_type'] == 0) {
  827. //发放兑换码
  828. $vrorder_model->addVrorderCode($order_info);
  829. } else {
  830. $logic_vrorder = model('vrorder', 'logic');
  831. $result = $logic_vrorder->changeOrderStateSuccess($order_info['order_id']);
  832. if (!$result['code']) {
  833. throw new \think\Exception($result['msg'], 10006);
  834. }
  835. }
  836. }
  837. } else {
  838. //暂冻结预存款,后面还需要 API彻底完成支付
  839. $data_pd['amount'] = $available_pd_amount;
  840. $predeposit_model->changePd('order_freeze', $data_pd);
  841. //预存款支付金额保存到订单
  842. $data_order = array();
  843. $order_info['pd_amount'] = $data_order['pd_amount'] = round($order_info['pd_amount'] + $available_pd_amount, 2);
  844. $result = $vrorder_model->editVrorder($data_order, array('order_id' => $order_info['order_id']));
  845. if (!$result) {
  846. throw new \think\Exception('订单更新失败', 10006);
  847. }
  848. }
  849. return $order_info;
  850. }
  851. /**
  852. * 取得抢购信息
  853. * @param array $goods_info
  854. * @return array
  855. */
  856. private function _getGroupbuyInfo($goods_info = array())
  857. {
  858. if (!config('ds_config.groupbuy_allow') || empty($goods_info) || !is_array($goods_info))
  859. return $goods_info;
  860. $groupbuy_info = model('groupbuy')->getGroupbuyInfoByGoodsCommonID($goods_info['goods_commonid']);
  861. if (empty($groupbuy_info))
  862. return $goods_info;
  863. // 虚拟抢购数量限制
  864. if ($groupbuy_info['groupbuy_upper_limit'] > 0 && $groupbuy_info['groupbuy_upper_limit'] < $goods_info['virtual_limit']) {
  865. $goods_info['virtual_limit'] = $groupbuy_info['groupbuy_upper_limit'];
  866. }
  867. $goods_info['goods_price'] = $groupbuy_info['groupbuy_price'];
  868. $goods_info['groupbuy_id'] = $groupbuy_info['groupbuy_id'];
  869. $goods_info['ifgroupbuy'] = true;
  870. return $goods_info;
  871. }
  872. }