CashierOrderCreate.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace addon\cashier\model\order;
  11. use addon\cardservice\model\MemberCard;
  12. use app\model\BaseModel;
  13. use app\model\order\OrderCreateTool;
  14. use app\model\order\OrderLog;
  15. use app\model\system\Pay;
  16. /**
  17. * 订单创建(普通订单)
  18. *
  19. * @author Administrator
  20. *
  21. */
  22. class CashierOrderCreate extends BaseModel
  23. {
  24. use OrderCreateTool;
  25. private $error = 0; //是否有错误
  26. private $error_printf = [];
  27. public $pay_type = 'ONLINE_PAY';
  28. public $trade_config = [];//配送方式的配置
  29. public function create($calculate_data)
  30. {
  31. $calculate_data = $this->calculate($calculate_data);
  32. if ($calculate_data[ 'code' ] < 0)
  33. return $calculate_data;
  34. if (isset($calculate_data[ 'code' ]) && $calculate_data[ 'code' ] < 0)
  35. return $calculate_data;
  36. $check_error = $this->checkError();
  37. if ($check_error[ 'code' ] < 0) {
  38. return $check_error;
  39. }
  40. $calculate_data = $calculate_data[ 'data' ];
  41. model('order')->startTrans();
  42. try {
  43. $member_id = $calculate_data[ 'member_id' ] ?? 0;
  44. $pay_model = new Pay();
  45. $out_trade_no = $pay_model->createOutTradeNo($member_id);
  46. $site_id = $calculate_data[ 'site_id' ];
  47. $order_no = $this->createOrderNo($site_id, $member_id);
  48. $site_info = $calculate_data[ 'site_info' ];
  49. $order_type = 5;//收银订单
  50. $order_name = $calculate_data[ 'order_name' ] ?? '';
  51. $member_info = $calculate_data[ 'member_info' ] ?? [];
  52. $nickname = $member_info[ 'nickname' ] ?? '';//会员昵称
  53. $headimg = $member_info[ 'headimg' ] ?? '';
  54. $mobile = $member_info[ 'mobile' ] ?? '';
  55. $nickname = !empty($nickname) ? $nickname : $mobile;
  56. $goods_list = $calculate_data[ 'goods_list' ] ?? [];
  57. $pay_money = $calculate_data[ 'pay_money' ] ?? 0;
  58. $order_status = '0';//订单状态
  59. $store_id = $calculate_data[ 'store_id' ] ?? 0;
  60. $store_info = $calculate_data[ 'store_info' ] ?? [];
  61. $store_name = $store_info[ 'store_name' ] ?? '';
  62. $extend = $calculate_data[ 'extend' ] ?? [];
  63. $sell_time = $calculate_data[ 'create_time' ] ?? 0;
  64. if ($sell_time == 0) {
  65. $sell_time = time();
  66. } else {
  67. $sell_time = strtotime($sell_time);
  68. }
  69. //这里有bug 无参数cashier_order_type
  70. // $cashier_order_type = $calculate_data[ 'cashier_order_type' ];
  71. $cashier_order_type = $calculate_data[ 'type' ];
  72. // dump($calculate_data['sku_array'][0]['money']);exit;
  73. // dump($calculate_data);exit;
  74. $operator = $calculate_data[ 'operator' ] ?? [];
  75. $operator_id = $operator[ 'uid' ] ?? 0;
  76. $operator_name = $operator[ 'username' ] ?? '';
  77. $order_from = 'cashier';
  78. $order_from_name = ( new CashierOrder )->order_from_list[ $order_from ][ 'name' ] ?? '';
  79. $cashier_order_model = new CashierOrder();
  80. //创建订单
  81. $data_order = [
  82. 'order_no' => $order_no,
  83. 'site_id' => $site_id,
  84. 'site_name' => $site_info[ 'name' ],
  85. 'order_name' => $order_name,
  86. 'out_trade_no' => $out_trade_no,
  87. 'member_id' => $member_id,
  88. 'nickname' => $nickname,
  89. 'headimg' => $headimg,
  90. 'mobile' => $mobile,
  91. // 'pay_money' => $calculate_data[ 'pay_money' ],
  92. 'pay_money' => $calculate_data['sku_array'][0]['money'],
  93. 'goods_money' => $calculate_data[ 'goods_money' ] ?? 0,
  94. 'real_goods_money' => $calculate_data[ 'real_goods_money' ] ??0,
  95. // 'order_money' => $calculate_data[ 'order_money' ],
  96. 'order_money' =>$calculate_data['sku_array'][0]['money'],
  97. 'store_id' => $store_id,
  98. 'create_time' => time(),
  99. 'order_from' => $order_from,
  100. 'order_from_name' => $order_from_name,
  101. 'order_type' => $order_type,
  102. 'order_type_name' => '收银订单',
  103. 'order_status' => 0,
  104. 'order_status_name' => '待支付',
  105. 'order_status_action' => json_encode($cashier_order_model->order_status[ 0 ], JSON_UNESCAPED_UNICODE),
  106. 'cashier_sell_time' => $sell_time,
  107. 'cashier_order_type' => $cashier_order_type,
  108. 'cashier_operator_id' => $operator_id,
  109. 'cashier_operator_name' => $operator_name,
  110. 'order_scene' => 'cashier',
  111. 'goods_num' => $calculate_data[ 'goods_num' ] ?? 1,
  112. 'remark' => $calculate_data[ 'remark' ] ?? ''
  113. ];
  114. $order_id = model('order')->add($data_order);
  115. $calculate_data[ 'order_no' ] = $order_no;
  116. $calculate_data[ 'out_trade_no' ] = $out_trade_no;
  117. $order_goods_id_map = [];
  118. foreach ($goods_list as $goods_k => $goods_info) {
  119. $card_item_id = $goods_info[ 'card_item_id' ] ?? 0;
  120. //订单项目表
  121. $data_order_goods = [
  122. 'order_id' => $order_id,
  123. 'site_id' => $site_id,
  124. 'member_id' => $member_id,
  125. 'goods_id' => $goods_info[ 'goods_id' ],
  126. 'sku_id' => $goods_info[ 'sku_id' ],
  127. 'goods_name' => $goods_info[ 'goods_name' ],
  128. 'sku_name' => $goods_info[ 'sku_name' ],
  129. 'sku_no' => $goods_info[ 'sku_no' ] ?? '',
  130. 'sku_image' => $goods_info[ 'goods_image' ] ?? '',
  131. 'spec_name' => $goods_info[ 'spec_name' ] ?? '',
  132. 'price' => $goods_info[ 'price' ],
  133. 'num' => $goods_info[ 'num' ],
  134. 'goods_money' => $goods_info[ 'goods_money' ],
  135. 'is_virtual' => $goods_info[ 'is_virtual' ] ?? 1,
  136. 'goods_class' => $goods_info[ 'goods_class' ],
  137. 'goods_class_name' => $goods_info[ 'goods_class_name' ],
  138. 'store_id' => $store_id,
  139. 'extend' => json_encode($extend),
  140. 'real_goods_money' => $goods_info[ 'real_goods_money' ],
  141. 'card_item_id' => $card_item_id,
  142. 'card_promotion_money' => $goods_info[ 'card_promotion_money' ] ?? 0,//次卡抵扣优惠
  143. ];
  144. //扣除库存
  145. if (in_array($cashier_order_type, [ 'goods', 'card' ])) {
  146. $stock_result = $this->skuDecStock($goods_info, $store_id);
  147. if ($stock_result[ 'code' ] < 0) {
  148. model('order')->rollback();
  149. return $stock_result;
  150. }
  151. }
  152. $order_goods_id = model('order_goods')->add($data_order_goods);
  153. $goods_list[ $goods_k ][ 'order_goods_id' ] = $order_goods_id;
  154. $order_goods_id_map[ $goods_k ] = $order_goods_id;
  155. }
  156. $calculate_data[ 'order_id' ] = $order_id;
  157. model('order')->commit();
  158. $log_data = array (
  159. 'order_id' => $order_id,
  160. 'action' => 'create',
  161. 'site_id' => $site_id,
  162. 'member_id' => $member_id
  163. );
  164. ( new OrderLog() )->addLog($log_data);
  165. $res = [
  166. 'order_id' => $order_id,
  167. 'out_trade_no' => $out_trade_no
  168. ];
  169. // 生成整体付费支付单据
  170. $pay_model->addPay($site_id, $out_trade_no, $this->pay_type, $order_name, $order_name, $pay_money, '', 'CashierOrderPayNotify', '');
  171. //执行自动关闭
  172. $this->addOrderCronClose($order_id, $site_id); //增加关闭订单自动事件
  173. return $this->success($res);
  174. } catch (\Exception $e) {
  175. model('order')->rollback();
  176. return $this->error('', $e->getMessage() . $e->getFile() . $e->getLine());
  177. }
  178. }
  179. /**
  180. * 计算
  181. * @param $data
  182. * @return mixed
  183. */
  184. public function calculate($data)
  185. {
  186. $data = $this->initStore($data);//初始化仓库门店
  187. $member_id = $data[ 'member_id' ] ?? 0;
  188. $data = $this->initSiteData($data); //初始化站点信息
  189. //商品列表信息
  190. $calculate_result = $this->getItemList($data);
  191. if ($calculate_result[ 'code' ] < 0) {
  192. return $calculate_result;
  193. }
  194. return $calculate_result;
  195. }
  196. /**
  197. * 购买项列表
  198. * @param $data
  199. * @return mixed
  200. */
  201. public function getItemList($data)
  202. {
  203. $type = $data[ 'type' ];
  204. $data_result = event('CashierCalculate', $data, true);
  205. if (empty($data_result)) {
  206. switch ( $type ) {
  207. case 'goods':
  208. $data[ 'cashier_order_type' ] = 'goods';
  209. //处理产品数据
  210. $sku_array = $data[ 'sku_array' ] ?? [];
  211. //消费分为产品和买单(暂)
  212. $product_id_array = [];
  213. $money_array = [];//买单
  214. foreach ($sku_array as $k => $v) {
  215. $money = $v[ 'money' ] ?? 0;
  216. $sku_id = $v[ 'sku_id' ] ?? 0;
  217. $num = $v[ 'num' ] ?? 1;
  218. if ($money > 0) {
  219. $money_array[] = [ 'money' => $money, 'sku_id' => $sku_id, 'num' => $num ];
  220. } else {
  221. if ($sku_id > 0) {
  222. $product_id_array[] = $v;
  223. }
  224. }
  225. }
  226. $data[ 'product_array' ] = $product_id_array;
  227. $calculate_result = $this->toCalculate($data);
  228. if ($calculate_result[ 'code' ] < 0) {
  229. return $calculate_result;
  230. }
  231. $data = $calculate_result[ 'data' ];
  232. $data[ 'money_array' ] = $money_array;
  233. $calculate_result = $this->moneyCalculate($data);
  234. if ($calculate_result[ 'code' ] < 0) {
  235. return $calculate_result;
  236. }
  237. $goods_list = $calculate_result[ 'data' ][ 'goods_list' ] ?? [];
  238. if (empty($goods_list))
  239. return $this->error([], '缺少必填参数商品数据');
  240. $calculate_result[ 'data' ][ 'goods_list' ] = array_reverse($calculate_result[ 'data' ][ 'goods_list' ]);
  241. $data = $calculate_result[ 'data' ];
  242. break;
  243. case 'card'://卡项
  244. $data[ 'cashier_order_type' ] = 'card';
  245. $shop_goods_list_result = $this->cardCalculate($data);
  246. if ($shop_goods_list_result[ 'code' ] < 0) {
  247. return $shop_goods_list_result;
  248. }
  249. $data = $shop_goods_list_result[ 'data' ];
  250. break;
  251. }
  252. } else {
  253. $data = $data_result[ 'data' ];
  254. }
  255. return $this->success($data);
  256. }
  257. /**
  258. * 个性化(主要用于商品)计算
  259. * @param $data
  260. * @return mixed
  261. */
  262. public function toCalculate($data)
  263. {
  264. $product_array = $data[ 'product_array' ] ?? [];
  265. if (!empty($product_array)) {
  266. $shop_goods_list_result = $this->getShopGoodsList($data);
  267. if ($shop_goods_list_result[ 'code' ] < 0) {
  268. return $shop_goods_list_result;
  269. }
  270. $data = $shop_goods_list_result[ 'data' ];
  271. //商品部分的计算
  272. $data = $this->goodsCalculate($data);
  273. //卡项抵消
  274. $delivery_money = $data[ 'delivery_money' ] ?? 0;
  275. $real_goods_money = $data[ 'real_goods_money' ] ?? $data[ 'goods_money' ];
  276. $order_money = moneyFormat($real_goods_money + $delivery_money);
  277. $pay_money = $order_money;
  278. $data[ 'pay_money' ] = $pay_money;
  279. //总结计算
  280. $data[ 'order_money' ] = $order_money;
  281. }
  282. return $this->success($data);
  283. }
  284. /**
  285. * 买单计算
  286. * @param $data
  287. */
  288. public function moneyCalculate($data)
  289. {
  290. $money_array = $data[ 'money_array' ];
  291. if (!empty($money_array)) {
  292. $goods_money = $data[ 'goods_money' ] ?? 0;
  293. $order_name = $data[ 'order_name' ] ?? '';
  294. $order_money = $data[ 'order_money' ] ?? 0;
  295. $pay_money = $data[ 'pay_money' ] ?? 0;
  296. $goods_list = $data[ 'goods_list' ] ?? [];
  297. $goods_image = 'public/uniapp/cashier/cashier-order-money.png';
  298. $goods_num = 0;
  299. foreach ($money_array as $k => $v) {
  300. $num = $v[ 'num' ] ?? 1;
  301. $item_price = $v[ 'money' ];
  302. if ($item_price > 0) {
  303. $sku_id = $v[ 'sku_id' ];
  304. $item_goods_money = moneyFormat($item_price * $num);
  305. $item_order_name = $item_goods_money . '元买单';
  306. $sku_name = '无码商品';
  307. $goods_list[] = array (
  308. 'goods_id' => 0,
  309. 'sku_id' => $sku_id,
  310. 'price' => $item_price,
  311. 'num' => $num,
  312. 'goods_money' => $item_goods_money,
  313. 'goods_name' => $item_order_name,
  314. 'sku_name' => $sku_name,
  315. 'goods_image' => $goods_image,
  316. 'spec_name' => '',
  317. 'goods_class' => 'money',
  318. 'goods_class_name' => '无码商品',
  319. 'real_goods_money' => $item_goods_money
  320. );
  321. $goods_money += $item_goods_money;
  322. $order_money += $order_money;
  323. $pay_money += $pay_money;
  324. $order_name = string_split($order_name, ",", $item_order_name);
  325. $goods_num += $num;
  326. }
  327. }
  328. $data[ 'goods_money' ] = $goods_money;
  329. $data[ 'real_goods_money' ] = $goods_money;
  330. $data[ 'goods_list' ] = $goods_list;
  331. $data[ 'order_name' ] = $order_name;
  332. $data[ 'order_money' ] = $goods_money;
  333. $data[ 'goods_num' ] = $goods_num;
  334. $data[ 'pay_money' ] = $goods_money;
  335. }
  336. return $this->success($data);
  337. }
  338. public function goodsCalculate($data)
  339. {
  340. $site_id = $data[ 'site_id' ];
  341. $goods_list = $data[ 'goods_list' ];
  342. $sku_array = $data[ 'product_array' ];
  343. //具备某个参数(控制是否是单品活动)
  344. //计算订单总额 ,订单总优惠 ,
  345. $goods_money = 0;
  346. $real_goods_money = 0;
  347. foreach ($goods_list as $k => $v) {
  348. // 计算单价 可能情况 (折扣价 会员价)
  349. $goods_item = $v;
  350. $sku_id = $v[ 'sku_id' ];
  351. //商品类主体中应该封装一个函数用于获取商品价格(可能还会有关联会员价 满减 折扣....)
  352. if ($v[ 'is_unify_price' ] == 1) {
  353. $price = moneyFormat($v[ 'sku_price' ]);
  354. } else {
  355. $price = moneyFormat($v[ 'price' ]);
  356. }
  357. $v[ 'price' ] = $price;
  358. $member_price_result = $this->getGoodsMemberPrice($v, $data);
  359. if ($member_price_result[ 'code' ] >= 0) {
  360. $price = $member_price_result[ 'data' ];
  361. $goods_item[ 'is_member_price' ] = true;
  362. }
  363. $num = $goods_item[ 'num' ];//购买数量
  364. $item_goods_money = moneyFormat($price * $num);//商品总额()
  365. $goods_item[ 'price' ] = $price;
  366. $goods_item[ 'goods_money' ] = $item_goods_money;
  367. $goods_item[ 'site_id' ] = $site_id;
  368. // $min_buy = $goods_item[ 'min_buy' ];
  369. // $max_buy = $goods_item[ 'max_buy' ];
  370. // if ($min_buy > 0 && $min_buy > $num)
  371. // $this->setError('GOODS_LESS_MIN_NUM');
  372. //
  373. // if ($max_buy > 0 && $max_buy < $num)
  374. // $this->setError('GOODS_OUT_MAX_NUM');
  375. $item_real_goods_money = $goods_item[ 'goods_money' ];
  376. $goods_item[ 'real_goods_money' ] = $item_real_goods_money;
  377. //卡项
  378. $goods_item = $this->itemCardCalculate($goods_item, $data);
  379. if (empty($goods_item)) {
  380. unset($goods_list[ $k ]);
  381. continue;
  382. } else {
  383. $item_goods_money = $goods_item[ 'goods_money' ];
  384. $item_real_goods_money = $goods_item[ 'real_goods_money' ];
  385. }
  386. $goods_money += $item_goods_money;
  387. $real_goods_money += $item_real_goods_money;
  388. $goods_item[ 'real_goods_money' ] = $item_real_goods_money;
  389. $goods_list[ $k ] = $goods_item;
  390. }
  391. $data[ 'goods_list' ] = $goods_list;
  392. $data[ 'goods_money' ] = $goods_money;
  393. $data[ 'real_goods_money' ] = $real_goods_money;
  394. return $data;
  395. }
  396. /**
  397. * 商品卡项抵扣(抵扣会将商品单价视为0)
  398. * @param $goods_item
  399. * @param $card_item
  400. */
  401. public function itemCardCalculate($goods_item, $data)
  402. {
  403. $card_item_id = $goods_item[ 'card_item_id' ] ?? 0;
  404. $member_id = $data[ 'member_id' ];
  405. $sku_id = $goods_item[ 'sku_id' ];
  406. if ($card_item_id > 0) {
  407. $num = $goods_item[ 'num' ];
  408. $member_card_model = new MemberCard();
  409. $card_item_params = array (
  410. 'member_id' => $member_id,
  411. 'sku_id' => $sku_id,
  412. 'item_id' => $card_item_id
  413. );
  414. $item_card_result = $member_card_model->getUseCardNum($card_item_params);
  415. if ($item_card_result[ 'code' ] < 0) {
  416. return [];
  417. }
  418. $item_card_data = $item_card_result[ 'data' ];
  419. $card_item_info = $item_card_data[ 'card_item_info' ];
  420. $card_info = $item_card_data[ 'card_info' ];
  421. $goods_item[ 'card_item_info' ] = $card_item_info;
  422. $goods_item[ 'card_info' ] = $card_info;
  423. $card_num = $item_card_data[ 'card_num' ];
  424. $goods_item[ 'card_num' ] = $card_num;
  425. if ($card_num > 0) {
  426. if ($num > $card_num) {
  427. $num = $card_num;
  428. }
  429. }
  430. $goods_item[ 'num' ] = $num;
  431. $price = $goods_item[ 'price' ];
  432. $card_promotion_money = moneyFormat($price * $num);
  433. $goods_money = moneyFormat($price * $num);
  434. $goods_item[ 'price' ] = $price;
  435. $goods_item[ 'goods_money' ] = $goods_money;
  436. $real_goods_money = moneyFormat($goods_money - $card_promotion_money);
  437. $real_goods_money = $real_goods_money < 0 ? 0 : $real_goods_money;
  438. $goods_item[ 'card_promotion_money' ] = $card_promotion_money;
  439. $goods_item[ 'real_goods_money' ] = $real_goods_money;
  440. }
  441. return $goods_item;
  442. }
  443. /**
  444. * 获取立即购买商品信息
  445. * @param $data
  446. * @return array
  447. */
  448. public function getShopGoodsList($data)
  449. {
  450. $store_id = $data[ 'store_id' ];
  451. $sku_array = $data[ 'product_array' ];
  452. $sku_ids = array_column($sku_array, 'sku_id');
  453. $sku_data = array_column($sku_array, null, 'sku_id');
  454. $data[ 'sku_data' ] = $sku_data;
  455. $site_id = $data[ 'site_id' ];
  456. $field = 'gs.site_id,gs.goods_id,gs.sku_id,gs.goods_name,gs.sku_name,gs.spec_name,gs.sku_image,g.goods_image,gs.price as sku_price,gs.sku_no,
  457. g.is_virtual,g.min_buy,g.max_buy,g.unit,sgs.stock,
  458. g.goods_class,g.goods_class_name,sgs.price,(sgs.sale_num + g.virtual_sale) as sale_num,g.is_unify_price';
  459. $alias = 'gs';
  460. $join = [
  461. [ 'goods g', 'g.goods_id = gs.goods_id', 'inner' ],
  462. [
  463. 'store_goods_sku sgs',
  464. 'sgs.sku_id = gs.sku_id and sgs.store_id = ' . $store_id,
  465. 'left'
  466. ]
  467. ];
  468. $goods_condition = [
  469. [ 'gs.is_delete', '=', 0 ],
  470. [ 'sgs.status', '=', 1 ],
  471. // [ 'gs.goods_state', '=', 1 ],
  472. [ 'gs.sku_id', 'in', $sku_ids ],
  473. [ 'gs.site_id', '=', $site_id ]
  474. ];
  475. $temp_goods_list = model('goods_sku')->getList($goods_condition, $field, '', $alias, $join);
  476. if (empty($temp_goods_list)) {
  477. return $this->error([], '商品不存在!');
  478. }
  479. foreach ($temp_goods_list as $k => $v) {
  480. $temp_goods_list[ $k ][ 'sale_num' ] = numberFormat($temp_goods_list[ $k ][ 'sale_num' ]);
  481. $temp_goods_list[ $k ][ 'stock' ] = numberFormat($temp_goods_list[ $k ][ 'stock' ]);
  482. }
  483. $column_goods_list = array_column($temp_goods_list, null, 'sku_id');
  484. $order_name = '';
  485. $goods_num = 0;
  486. $goods_list = [];
  487. //分配关联商品数据
  488. foreach ($sku_array as $k => $v) {
  489. $sku_id = $v[ 'sku_id' ];
  490. $goods_info = $column_goods_list[ $sku_id ] ?? 0;
  491. if (empty($goods_info)) {
  492. return $this->error([], '商品不存在!');
  493. }
  494. $order_name = string_split($order_name, ",", $goods_info[ 'goods_name' ]);
  495. $item_num = $v[ 'num' ] ?? 1;
  496. if ($goods_info[ 'goods_class' ] != 6) {
  497. if ($item_num < 1) {
  498. return $this->error([], '商品数量不能小于1!');
  499. }
  500. } else {
  501. if ($item_num < 0) {
  502. return $this->error([], '称重重量不能小于0!');
  503. }
  504. }
  505. $goods_info[ 'card_item_id' ] = $v[ 'card_item_id' ] ?? 0;
  506. $goods_num += $item_num;
  507. $is_virtual = $is_virtual ?? $goods_info[ 'is_virtual' ];
  508. // $goods_info[ 'trade_type' ] = $goods_info['goods_class'];//业务类型
  509. $goods_info[ 'num' ] = $item_num;
  510. $goods_info[ 'sku_image' ] = explode(',', $goods_info[ 'sku_image' ])[ 0 ] ?? '';
  511. $goods_info[ 'goods_image' ] = explode(',', $goods_info[ 'goods_image' ])[ 0 ] ?? '';
  512. $goods_list[ $k ] = $goods_info;
  513. }
  514. $data[ 'goods_list' ] = $goods_list;
  515. $data[ 'order_name' ] = $order_name;
  516. $data[ 'goods_num' ] = $goods_num;
  517. return $this->success($data);
  518. }
  519. /**
  520. * 卡项的计算
  521. * @param $data
  522. */
  523. public function cardCalculate($data)
  524. {
  525. $store_id = $data[ 'store_id' ];
  526. $sku_array = $data[ 'sku_array' ];
  527. $sku_ids = array_column($sku_array, 'sku_id');
  528. $sku_num_array = array_column($sku_array, 'num', 'sku_id');
  529. // $sku_ids = $data['sku_ids'];//sku_id数组weight
  530. $site_id = $data[ 'site_id' ];
  531. $field = 'gs.site_id,gs.goods_id,gs.sku_id,gs.goods_name,gs.sku_name,gs.spec_name,gs.sku_image,g.goods_image,sgs.price,gs.price as sku_price,gs.sku_no,
  532. g.is_virtual,g.unit,sgs.stock,
  533. g.min_buy,g.max_buy,
  534. g.goods_class,g.goods_class_name,(sgs.sale_num + g.virtual_sale) as sale_num,g.is_unify_price';
  535. $alias = 'gs';
  536. $join = [
  537. [ 'goods g', 'g.goods_id = gs.goods_id', 'inner' ],
  538. [
  539. 'store_goods_sku sgs',
  540. 'sgs.sku_id = gs.sku_id and sgs.store_id = ' . $store_id,
  541. 'left'
  542. ]
  543. ];
  544. $goods_condition = [
  545. [ 'gs.is_delete', '=', 0 ],
  546. [ 'sgs.status', '=', 1 ],
  547. [ 'gs.sku_id', 'in', $sku_ids ],
  548. [ 'gs.site_id', '=', $site_id ],
  549. ];
  550. $goods_list = model('goods_sku')->getList($goods_condition, $field, '', $alias, $join);
  551. $order_name = '';
  552. $goods_num = 0;
  553. foreach ($goods_list as $k => $v) {
  554. $sku_id = $v[ 'sku_id' ];
  555. $order_name = string_split($order_name, ",", $v[ 'goods_name' ]);
  556. $item_num = $sku_num_array[ $sku_id ] ?? 1;
  557. $goods_num += $item_num;
  558. $goods_info = $v;
  559. $is_virtual = $is_virtual ?? $v[ 'is_virtual' ];
  560. $goods_info[ 'num' ] = $item_num;
  561. $goods_info[ 'sale_num' ] = numberFormat($goods_info[ 'sale_num' ]);
  562. $goods_info[ 'stock' ] = numberFormat($goods_info[ 'stock' ]);
  563. $goods_list[ $k ] = $goods_info;
  564. }
  565. $data[ 'goods_list' ] = $goods_list;
  566. $data[ 'order_name' ] = $order_name;
  567. $data[ 'goods_num' ] = $goods_num;
  568. $goods_list = $data[ 'goods_list' ];
  569. //具备某个参数(控制是否是单品活动)
  570. //计算订单总额 ,订单总优惠 ,
  571. $goods_money = 0;
  572. $real_goods_money = 0;
  573. foreach ($goods_list as $k => $v) {
  574. // 计算单价 可能情况 (折扣价 会员价)
  575. $goods_item = $v;
  576. //商品类主体中应该封装一个函数用于获取商品价格(可能还会有关联会员价 满减 折扣....)
  577. if ($v[ 'is_unify_price' ] == 1) {
  578. $price = moneyFormat($v[ 'sku_price' ]);
  579. } else {
  580. $price = moneyFormat($v[ 'price' ]);
  581. }
  582. $v[ 'price' ] = $price;
  583. $member_price_result = $this->getGoodsMemberPrice($v, $data);
  584. if ($member_price_result[ 'code' ] >= 0) {
  585. $price = $member_price_result[ 'data' ];
  586. $goods_item[ 'is_member_price' ] = true;
  587. }
  588. $goods_item[ 'price' ] = $price;
  589. $num = $goods_item[ 'num' ];//购买数量
  590. $item_goods_money = moneyFormat($price * $num);//商品总额()
  591. // $min_buy = $goods_item[ 'min_buy' ];
  592. // $max_buy = $goods_item[ 'max_buy' ];
  593. // if ($min_buy > 0 && $min_buy > $num) {
  594. // $this->setError('GOODS_LESS_MIN_NUM');
  595. // }
  596. // if ($max_buy > 0 && $max_buy < $num) {
  597. // $this->setError('GOODS_OUT_MAX_NUM');
  598. // }
  599. $goods_money += $item_goods_money;
  600. $item_real_goods_money = $item_goods_money;
  601. $real_goods_money += $item_real_goods_money;
  602. $goods_item[ 'goods_money' ] = $item_goods_money;
  603. $goods_item[ 'real_goods_money' ] = $item_real_goods_money;
  604. $goods_item[ 'sku_image' ] = explode(',', $goods_item[ 'sku_image' ])[ 0 ] ?? '';
  605. $goods_item[ 'goods_image' ] = explode(',', $goods_item[ 'goods_image' ])[ 0 ] ?? '';
  606. $goods_list[ $k ] = $goods_item;
  607. }
  608. $data[ 'goods_list' ] = $goods_list;
  609. $data[ 'goods_money' ] = moneyFormat($goods_money);
  610. $data[ 'real_goods_money' ] = moneyFormat($real_goods_money);
  611. $delivery_money = $data[ 'delivery_money' ] ?? 0;
  612. $order_money = moneyFormat($real_goods_money + $delivery_money);
  613. $pay_money = $order_money;
  614. //总结计算
  615. $data[ 'order_money' ] = $order_money;
  616. $data[ 'pay_money' ] = $pay_money;
  617. return $this->success($data);
  618. }
  619. /**
  620. * 设置错误
  621. * @param $error_code
  622. */
  623. protected function setError($error_code, $error_printf = [])
  624. {
  625. $this->error = $error_code;
  626. $this->error_printf = $error_printf;
  627. }
  628. /**
  629. * 校验错误
  630. * @return bool
  631. */
  632. public function checkError()
  633. {
  634. if (!empty($this->error)) {
  635. $error_msg = $this->getError();
  636. return $this->error([ 'error_code' => $this->error, 'error_msg' => $error_msg ], $error_msg);
  637. } else {
  638. return $this->success();
  639. }
  640. }
  641. /**
  642. * 获取错误
  643. * @return mixed
  644. */
  645. protected function getError()
  646. {
  647. $error_list = [
  648. 'GOODS_STOCK_EMPTY' => '%s库存不足%s',
  649. 'ADDRESS_EMPTY' => '%s收货地址必须选择!%s',
  650. 'TRADE_TYPE_EMPTY' => '%s配送方式必须选择!%s',
  651. 'GOODS_LESS_MIN_NUM' => '%s商品数量不能小于最小购买量%s',
  652. 'GOODS_OUT_MAX_NUM' => '%s商品数量不能超出最大购买量%s',
  653. 'MOBILE_EMPTY' => '%s联系人手机号不能为空%s',
  654. 'NAME_EMPTY' => '%s联系人名称不能为空%s',
  655. 'YUEYUE_ERROR' => '%s %s',
  656. ];
  657. $error_msg = $error_list[ $this->error ] ?? '';
  658. return sprintf($error_msg, $this->error_printf[ 0 ] ?? '', $this->error_printf[ 1 ] ?? '');
  659. }
  660. }