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