Buyvirtual.php 47 KB

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