OrderSubmitForm.php 115 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\client\models\v1\order;
  8. use app\constants\OptionSetting;
  9. use app\models\Address;
  10. use app\models\AgentFrontBind;
  11. use app\models\AgentFrontErpInventory;
  12. use app\models\Cart;
  13. use app\models\common\CommonOrder;
  14. use app\models\DeliveryInfo;
  15. use app\models\District;
  16. use app\models\FoodCart;
  17. use app\models\FoodFlag;
  18. use app\models\Goods;
  19. use app\models\GoodsBook;
  20. use app\models\GoodsChainLevel;
  21. use app\models\IntegralAppreciationGoods;
  22. use app\models\IntegralAppreciationUser;
  23. use app\models\IntegralAppreciationUserIntegralLog;
  24. use app\models\Level;
  25. use app\models\LevelOrder;
  26. use app\models\Md;
  27. use app\models\MdGoods;
  28. use app\models\MdProfit;
  29. use app\models\Order;
  30. use app\models\OrderDetail;
  31. use app\models\OrderTransit;
  32. use app\models\QueueLog;
  33. use app\models\Register;
  34. use app\models\SaaSLeaguePriceLog;
  35. use app\models\SaasUser;
  36. use app\models\SeckillActivity;
  37. use app\models\SeckillActivityGoods;
  38. use app\models\SeckillActivityOrderLog;
  39. use app\models\ShareHolderLevel;
  40. use app\models\ShareHolderProfitGoodsLog;
  41. use app\models\Store;
  42. use app\models\Supplier;
  43. use app\models\User;
  44. use app\models\UserCoupon;
  45. use app\models\Option;
  46. use app\models\AccountLog;
  47. use app\models\LocalDeliveryFreight;
  48. use app\models\OfferPrice;
  49. use app\models\VerifyCard;
  50. use app\models\VerifyCardSale;
  51. use app\models\VerifyCardLog;
  52. use app\models\VideoGoods;
  53. use app\models\VideoGoodsList;
  54. use app\models\VideoGoodsSetting;
  55. use app\models\VideoGoodsShare;
  56. use app\models\WorkerOrderExt;
  57. use app\models\WorkerSetting;
  58. use app\modules\admin\models\MerchantForm;
  59. use app\plugins\adopt\models\AdoptGoods;
  60. use app\plugins\adopt\models\AdoptOrderInfo;
  61. use app\utils\CloudPrint;
  62. use app\utils\Delivery\Delivery;
  63. use app\utils\Delivery\Alipay\ADelivery;
  64. use app\utils\Delivery\WechatNewDelivery;
  65. use app\utils\Notice\NoticeSend;
  66. use app\utils\OrderNo;
  67. use app\utils\PrintOrder;
  68. use app\utils\Tools;
  69. use yii\helpers\ArrayHelper;
  70. use yii\helpers\Json;
  71. use app\modules\admin\models\ActivityCutPriceForm;
  72. use app\modules\admin\models\givingGifts\GivingGiftsForm;
  73. use yii\db\Expression;
  74. use app\modules\admin\models\mochat\MochatForm;
  75. use app\modules\admin\models\maiyatian\MaiyatianForm;
  76. use app\modules\admin\models\keloop\KeloopForm;
  77. class OrderSubmitForm extends OrderForm
  78. {
  79. public $user;
  80. public $payment;
  81. public $use_integral;
  82. public $buy_level_id;
  83. public $adopt_name;
  84. public $adopt_mobile;
  85. public $worker_time;
  86. public $is_fugou = 0;
  87. public function rules()
  88. {
  89. $rules = [
  90. [['payment', 'use_integral', 'buy_level_id', 'is_fugou'], 'integer'],
  91. [['adopt_name', 'adopt_mobile', 'worker_time'], 'string']
  92. ];
  93. return array_merge(parent::rules(), $rules);
  94. }
  95. public function preOrder()
  96. {
  97. if (!$this->validate())
  98. return [
  99. 'code' => 1,
  100. 'msg' => $this->getErrorSummary(false)[0],
  101. ];
  102. try {
  103. if (!$this->address['id']) {
  104. return [
  105. 'code' => 0,
  106. 'data' => [
  107. 'fee' => 0,
  108. 'resultcode' => 0
  109. ]
  110. ];
  111. // return [
  112. // 'code' => 1,
  113. // 'msg' => '请先选择收货地址',
  114. // ];
  115. }
  116. if (isset($this->pre_order_data)) {
  117. $this->mch_list = json_decode($this->pre_order_data, true);
  118. }
  119. $mch_list = $this->getMchListData(true);
  120. if (isset($mch_list['code']) && $mch_list['code'] == 1) {
  121. return $mch_list;
  122. }
  123. $goods_list = [];
  124. $fee = 0;
  125. foreach ($mch_list as $mch) {
  126. $is_front_delivery = 0;//做表里面的标识使用
  127. foreach ($mch['goods_list'] as $goods) {
  128. $goods_list[] = [
  129. 'name' => $goods['goods_name'],
  130. 'price' => $goods['price'],
  131. 'pic' => $goods['goods_pic'],
  132. 'num' => $goods['num'],
  133. 'weight' => $goods['weight'],
  134. ];
  135. }
  136. $delivery_time = $mch['delivery_time'];//送出时间
  137. if($this->order_no){
  138. $existOrder = Order::findOne(['order_no' => $this->order_no]);
  139. if($existOrder){
  140. return [
  141. 'code' => 1,
  142. 'msg' => '单号错误0,请后退到商品页重新下单',
  143. ];
  144. }
  145. $order_no = $this->order_no;
  146. }else{
  147. $order_no = OrderNo::getOrderNo(OrderNo::ORDER_ALIPAY_FOOD);
  148. $goods_id = array_column($mch['goods_list'], 'goods_id');
  149. sort($goods_id);
  150. $goods_id = implode(',', $goods_id);
  151. $goods_id = md5($goods_id);
  152. $order_no = cache()->get('delivery_order_no_' . $goods_id . '_' . get_user_id());
  153. }
  154. if (!$order_no) {
  155. throw new \Exception('同城配送暂不可用' . 'delivery_order_no_' . $goods_id . '_' . get_user_id());
  156. }
  157. $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, $this->store_id, 'store')['value'];
  158. $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, $this->store_id, 'pay', $local_type);
  159. foreach ($mch['goods_list'] as $goods) {
  160. if (intval($goods['is_front_delivery'])) {
  161. $is_front_delivery = 1;
  162. $local_type['value'] = "self";
  163. break;
  164. }
  165. }
  166. if($local_type['value'] == 'keloop') {//快跑者配送
  167. if(KeloopForm::isSaasOpen()){
  168. $preAddOrder = KeloopForm::preAddOrder($this->store_id, $order_no, $this->address['longitude'], $this->address['latitude']);
  169. if ($preAddOrder['code']) {
  170. return $preAddOrder;
  171. }
  172. $fee = bcadd($fee, (float)$preAddOrder['data']['fee'], 2);
  173. // return [
  174. // 'code' => 0,
  175. // 'msg' => 'ok',
  176. // 'data' => [
  177. // "resultcode" => 0,
  178. // 'fee' => (float)$preAddOrder['data']['fee'],
  179. // 'fee_data' => $preAddOrder['data']['fee_data'],
  180. // ],
  181. // 'order_no' => $order_no,
  182. // ];
  183. } else {
  184. return [
  185. 'code' => 1,
  186. 'msg' => '快跑者配送没有配置',
  187. ];
  188. }
  189. }
  190. if($local_type['value'] == 'maiyatian') {//麦芽田
  191. if(MaiyatianForm::isopen($this->store_id)){
  192. $getFreight = LocalDeliveryFreight::getFreight($this->store_id, $this->address, $delivery_time, LocalDeliveryFreight::TYPE_MAIYATIAN, $goods_list);
  193. if($getFreight['code'] != 0){
  194. return $getFreight;
  195. }
  196. $freight = $getFreight['data'];
  197. $preAddOrder = MaiyatianForm::preAddOrder($this->store_id, $order_no, $freight);
  198. $fee = bcadd($fee, (float)$freight, 2);
  199. // return [
  200. // 'code' => 0,
  201. // 'msg' => 'ok',
  202. // 'data' => [
  203. // "resultcode" => 0,
  204. //// 'fee' => (float)MaiyatianForm::getConf($this->store_id, 'cyy_delivery_fee'),
  205. // 'fee' => (float)$freight,
  206. // ],
  207. // 'order_no' => $order_no,
  208. // ];
  209. // return $preAddOrder;
  210. } else {
  211. return [
  212. 'code' => 1,
  213. 'msg' => '麦芽田没有配置',
  214. ];
  215. }
  216. } elseif($local_type['value'] == 'aggregate') {//聚合配送
  217. if(is_alipay_platform()){
  218. $this->address_id || $this->address_id = 220;
  219. $res = ADelivery::createOrder(1, $this->store_id, get_mini_id(), get_saas_user()->ali_user_id, $goods_list, $order_no, $this->address_id);;
  220. return array_merge($res, ['order_no' => $order_no]);
  221. }
  222. $store = Store::findOne($this->store_id);
  223. if (intval($store->wechat_delivery_type) === 0) {
  224. return array_merge(Delivery::preAddOrder($goods_list, $order_no), ['order_no' => $order_no]);
  225. } else {
  226. $form = new WechatNewDelivery();
  227. $result = $form->preAddOrder([
  228. 'address' => ArrayHelper::toArray($this->address),
  229. 'goods_list' => $goods_list,
  230. 'store_id' => $this->store_id,
  231. 'md_id' => get_md_id()
  232. ]);
  233. if ($result['code'] === 0) {
  234. DeliveryInfo::deleteAll(['order_no' => $order_no, 'store_id' => get_store_id(), 'status' => 0]);
  235. // 存预下单表
  236. $delivery_info = new DeliveryInfo();
  237. $delivery_info->store_id = get_store_id();
  238. $delivery_info->order_no = $order_no;
  239. $delivery_info->fee = bcdiv($result['data']['fee'], 100, 2);;
  240. $delivery_info->delivery_type = 0;
  241. $delivery_info->created_at = time();
  242. $delivery_info->is_local = DeliveryInfo::IS_LOCAL_NO;
  243. $serial_num = DeliveryInfo::find()->where(['>','created_at',strtotime(date('Y-m-d'))])->orderBy('serial_num desc')->asArray()->one()['serial_num'];
  244. $delivery_info->serial_num = $serial_num > 0 ? $serial_num + 1 : 1;
  245. $delivery_info->md_id = get_md_id();
  246. $delivery_info->wechat_delivery_type = 1;
  247. $delivery_info->save();
  248. // return array_merge($result, ['order_no' => $order_no]);
  249. $fee = bcadd($fee, (float)$result['data']['fee'], 2);
  250. } else {
  251. return $result;
  252. }
  253. // return array_merge($form->preAddOrder([
  254. // 'address' => ArrayHelper::toArray($this->address),
  255. // 'goods_list' => $goods_list,
  256. // 'store_id' => $this->store_id,
  257. // 'md_id' => 0
  258. // ]), ['order_no' => $order_no]);
  259. }
  260. } elseif(in_array($local_type['value'], ['self', 'self_store'])) {//平台自配
  261. // return Delivery::preAddOrder($goods_list, $order_no);
  262. /* 配送费搞一下 id891 WPing 2023年7月3日19:47:30 */
  263. if(!$this->address['id']){
  264. return [
  265. 'code' => 1,
  266. 'msg' => '请先选择收货地址',
  267. ];
  268. }
  269. $type = LocalDeliveryFreight::TYPE_LOCAL;
  270. if ($local_type['value'] === 'self_store') {
  271. $type = LocalDeliveryFreight::TYPE_STORE_LOCAL;
  272. }
  273. $getFreight = LocalDeliveryFreight::getFreight($this->store_id, $this->address, $delivery_time, $type, $goods_list);
  274. if($getFreight['code'] != 0){
  275. return $getFreight;
  276. }
  277. $freight = $getFreight['data'];
  278. DeliveryInfo::deleteAll(['order_no' => $order_no, 'store_id' => get_store_id(), 'status' => 0]);
  279. // 存预下单表
  280. $delivery_info = new DeliveryInfo();
  281. $delivery_info->store_id = get_store_id();
  282. $delivery_info->order_no = $order_no;
  283. $delivery_info->fee = $freight;
  284. $delivery_info->delivery_type = 0;
  285. $delivery_info->created_at = time();
  286. $delivery_info->is_local = DeliveryInfo::IS_LOCAL_YSE;
  287. $delivery_info->is_store_delivery_type = intval($local_type['value'] === 'self_store');
  288. $delivery_info->is_front_delivery = $is_front_delivery;//是否是仓库配送订单
  289. $serial_num = DeliveryInfo::find()->where(['>','created_at',strtotime(date('Y-m-d'))])->orderBy('serial_num desc')->asArray()->one()['serial_num'];
  290. $delivery_info->serial_num = $serial_num > 0 ? $serial_num + 1 : 1;
  291. $delivery_info->save();
  292. $fee = bcadd($fee, (float)$freight, 2);
  293. // return [
  294. // 'code' => 0,
  295. // 'msg' => 'success',
  296. // 'order_no' => $order_no,
  297. // 'data' => $getFreight['info'],
  298. // ];
  299. /* end */
  300. // return [
  301. // 'code' => 0,
  302. // 'data' => [
  303. // 'goods_list' => $goods_list,
  304. // 'order_no' => $order_no,
  305. // 'test' => [
  306. // 'address' => $address,
  307. // 'store' => $store,
  308. // 'distance' => $distance,
  309. // 'delivery_time' => $delivery_time,
  310. // 'delivery_time_stamp' => $delivery_time_stamp,
  311. // 'LocalDeliveryFreight' => $data,
  312. // 'freight_detail' => $freight_detail,
  313. // 'freight' => $freight,
  314. // ]
  315. // ],
  316. // 'msg' => '平台自配'
  317. // ];
  318. }
  319. }
  320. return [
  321. 'code' => 0,
  322. 'data' => [
  323. 'fee' => floatval($fee),
  324. 'resultcode' => 0
  325. ]
  326. ];
  327. } catch (\Exception $e) {
  328. return [
  329. 'code' => 1,
  330. 'msg1' => $e->getTraceAsString(),
  331. 'msg' => $e->getMessage()
  332. ];
  333. }
  334. }
  335. public function save()
  336. {
  337. if (!$this->validate())
  338. return [
  339. 'code' => 1,
  340. 'msg' => $this->getErrorSummary(false)[0],
  341. ];
  342. try {
  343. $mchListData = $this->getMchListData(true);
  344. if (isset($mchListData['code']) && $mchListData['code'] == 1) {
  345. return $mchListData;
  346. }
  347. if(count($mchListData) > 1){
  348. foreach($mchListData as $mch){
  349. if($mch['mch_id'] > 0 && $mch['send'] == 'shop'){
  350. throw new \Exception('(' . $mch['name'] . ')店铺需要单独提交订单');
  351. }
  352. }
  353. }
  354. } catch (\Exception $e) {
  355. return [
  356. 'code' => 1,
  357. 'msg' => $e->getMessage()
  358. ];
  359. }
  360. $order_id_list = [];
  361. $level = $this->level;
  362. $md_select = 0;
  363. /**
  364. * @var $address Address
  365. */
  366. $order_type_ext = 0;
  367. $address = (object)($this->address);
  368. $t = \Yii::$app->db->beginTransaction();
  369. if ($this->is_worker) {
  370. $start_time = strtotime($this->worker_time);
  371. $end_time = $start_time + 1800;
  372. $order_ext = WorkerOrderExt::find()->where(['worker_id' => $this->worker_id, 'user_revoke' => 0])
  373. ->andWhere(['AND', ['>=', 'time_start_service', $start_time], ['<', 'time_start_service', $end_time]])
  374. ->select('time_start_service, time_end_service')->one();
  375. if ($order_ext) {
  376. return [
  377. 'code' => 1,
  378. 'msg' => '当前时间不可预约'
  379. ];
  380. }
  381. }
  382. foreach ($mchListData as &$mch) {
  383. if(get_md_id() > 0 && $mch['mch_id'] > 0){
  384. return [
  385. 'code' => 1,
  386. 'msg' => '(' . $mch['name'] . ')店铺下单,需要取消门店选择',
  387. ];
  388. }
  389. // 门店营业时间判断
  390. if (get_md_id() && get_md_id() > 0 && $mch['send'] == 'shop') {
  391. $md = Md::findOne(['id' => get_md_id(), 'is_delete' => 0]);
  392. if ($md->open_status == 0) {
  393. return [
  394. 'code' => 1,
  395. 'msg' => '门店已打烊'
  396. ];
  397. }
  398. if ($md->is_time_forbid == 0 && !$this->checkTimeBeginEnd($md->start_time, $md->end_time) && $md->shop_time_type == 1) {
  399. return [
  400. 'code' => 1,
  401. 'msg' => '非营业时间禁止下单'
  402. ];
  403. }
  404. }
  405. if (isset($mch['use_integral']) && !$mch['use_integral']) {
  406. $mch['integral'] = ['forehead' => 0, 'forehead_integral' => 0];
  407. $mch['give'] = 0;
  408. }
  409. $mch_goods = $mch['goods_list'];
  410. if ($mch_goods) {
  411. $checkMchData = $this->checkMchData($mch);
  412. if ($checkMchData['code'] == 1) {
  413. $t->rollBack();
  414. return $checkMchData;
  415. }
  416. $level_price = 0;
  417. $total_price = 0;
  418. $is_have_express = false;
  419. $is_have_shop = false;
  420. $order_type = 0;
  421. $is_have_delivery = 0;
  422. $total_integral = 0;
  423. if ($mch['send'] == 'express') {
  424. $is_have_express = true;
  425. }
  426. if ($mch['send'] == 'shop') {// || get_md_id()
  427. $is_have_shop = true;
  428. if (!empty($mch['shop']) && !empty($mch['shop']['id'])) {
  429. $md_select = $mch['shop']['id'];
  430. }
  431. }
  432. $is_delivery = OfferPrice::findOne([
  433. 'store_id' => get_store_id(),
  434. 'is_delete' => 0
  435. ]);
  436. $store_data = Store::findOne(get_store_id());
  437. $delivery_rules = [];
  438. if ($mch['send'] == 'delivery') {
  439. $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, get_store_id(), 'store')['value'];
  440. $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, get_store_id(), 'pay', $local_type);
  441. $is_have_express = true;
  442. $delivery_rules = json_decode($is_delivery->delivery_rules, true);
  443. if ($is_delivery->delivery_type == 1 && !empty($delivery_rules)) {
  444. $conf = [
  445. 'shop_tag' => $store_data->coordinate,
  446. 'deliveryRules' => $delivery_rules
  447. ];
  448. $deliveryRules = $this->canDeliver($address, $conf);
  449. if (!$deliveryRules['can_deliver']) {
  450. return [
  451. 'code' => 1,
  452. 'msg' => '当前订单超出配送距离'
  453. ];
  454. }
  455. }
  456. if ($local_type['value'] == 'keloop') { //快跑者配送
  457. if (!KeloopForm::isSaasOpen()) {
  458. $t->rollBack();
  459. return [
  460. 'code' => 1,
  461. 'msg' => '商城未设置有效配送方式'
  462. ];
  463. }
  464. }
  465. if($local_type['value'] == 'maiyatian') {//麦芽田
  466. $maiyatian = MaiyatianForm::isopen($this->store_id);
  467. if (!$maiyatian) {
  468. $t->rollBack();
  469. return [
  470. 'code' => 1,
  471. 'msg' => '商城未设置有效配送方式'
  472. ];
  473. }
  474. } elseif($local_type['value'] == 'aggregate') {//聚合配送
  475. $store = Store::findOne($this->store_id);
  476. if (intval($store->wechat_delivery_type) === 0) {
  477. if ($store->delivery_type == 0) {
  478. $t->rollBack();
  479. return [
  480. 'code' => 1,
  481. 'msg' => '商城未设置有效配送方式'
  482. ];
  483. }
  484. $res = Delivery::getBindAccount();
  485. // 下单时判断是否可以同城配送
  486. if (empty($res['data']['shop_list'])) {
  487. $t->rollBack();
  488. return [
  489. 'code' => 1,
  490. 'msg' => '当前未绑定运力账号,暂不能保存选择同城配送方式'
  491. ];
  492. }
  493. $shop_list = $res['data']['shop_list'];
  494. $delivery_arr = array_column($shop_list, 'delivery_id');
  495. $delivery_arr[] = 'TEST';
  496. $delivery_arr_id = array_column($shop_list, null, 'delivery_id');
  497. if (!in_array(Delivery::$deliveryIdArr[$store->delivery_type], $delivery_arr) || $delivery_arr_id[Delivery::$deliveryIdArr[$store->delivery_type]]['audit_result'] != 0) {
  498. $t->rollBack();
  499. return [
  500. 'code' => 1,
  501. 'msg' => '当前账号未在微信后台绑定或者并未审核通过'
  502. ];
  503. }
  504. }
  505. } elseif(in_array($local_type['value'], ['self', 'self_store'])) {//平台自配
  506. if(empty($mch['delivery_time'])){
  507. $store_id = $local_type['value'] === 'self_store' ? $this->store_id : 0;
  508. $setting = json_decode(Option::get(OptionSetting::LOCAL_DELIVERY_SETTING, $store_id, '', '{}')['value'], true);
  509. $mch['delivery_time'] = date('Y-m-d H:i:s', time() + 90 * 60);
  510. if(!empty($setting['default_time']) && !empty($setting['default_time']['value'])){
  511. $mch['delivery_time'] = date('Y-m-d H:i:s', time() + ($setting['default_time']['value'] * 60));
  512. }
  513. }
  514. }
  515. $is_have_delivery = true;
  516. }
  517. $take_price = 0;
  518. $send_price = 0;
  519. foreach ($mch_goods as $v) {
  520. if ($v['product_type'] == 1) {
  521. $order_type = 1;
  522. }
  523. if ($v['product_type'] == 2) {
  524. $order_type = 2;
  525. }
  526. if ($v['product_type'] == 3) {
  527. $order_type = 4;
  528. }
  529. if ($v['product_type'] == Goods::GOODS_TYPE_ADOPT) {
  530. $order_type = 5;
  531. }
  532. if ($v['product_type'] == Goods::GOODS_TYPE_WORKER) {
  533. $order_type = 6;
  534. }
  535. if ($v['product_type'] == Goods::GOODS_TYPE_INTEGRAL) {
  536. $order_type = 7;
  537. $total_integral += isset($v['integral_price']) ? $v['integral_price'] : 0;
  538. }
  539. //普通商品没选择门店禁止选择自提方式
  540. if ($v['product_type'] == 0 && $is_have_shop && !$v['mch_id']) {
  541. if (empty(input_params('flag_id')) && empty(input_params('table_num'))) {
  542. $md_id = get_md_id();
  543. if ($md_id > 0 || ($mch['shop'] && $mch['shop']['id'])) {
  544. $md_info = Md::findOne($md_id > 0 ? $md_id : $mch['shop']['id']);
  545. if (!$md_info) {
  546. return [
  547. 'code' => 1,
  548. 'result_code' => 'select_md',
  549. 'msg' => '自提订单请选择门店'
  550. ];
  551. }
  552. } else {
  553. return [
  554. 'code' => 1,
  555. 'result_code' => 'select_md',
  556. 'msg' => '自提订单请选择门店'
  557. ];
  558. }
  559. }
  560. }
  561. // if ($v['send'] == 'shop' && empty($v['shop_id']) && empty($v['shop'])) {
  562. // return [
  563. // 'code' => 1,
  564. // 'msg' => '自提商品请选择自提点'
  565. // ];
  566. // }
  567. if ($this->buy_level_id && $order_type !== 6) {
  568. $level_price += $v['next_level_price'];
  569. } else {
  570. if ($v['payment_type']) {
  571. $level_price += $v['pre_price'];
  572. } else {
  573. $level_price += $v['level_price'];
  574. }
  575. }
  576. if ($v['payment_type']) {
  577. $order_type_ext = 1;
  578. $total_price += $v['pre_price'];
  579. } else {
  580. $total_price += isset($v['total_price']) ? $v['total_price'] : $v['price'];
  581. }
  582. $take_price += $v['take_price'] ?? 0;
  583. $send_price += $v['send_price'] ?? 0;
  584. }
  585. $mch['level_price'] = $level_price;
  586. $mch['level_diff_price'] = sprintf('%.2f',$mch['next_level']['diff_price']);
  587. $mch['total_price'] = $total_price;
  588. $mch['total_integral'] = $total_integral; //积分兑换
  589. // 是否开启配送范围设置
  590. if ($is_have_delivery) {
  591. if (get_md_id() > 0) {
  592. $md_info = Md::findOne(get_md_id());
  593. $lat = $md_info->latitude;
  594. $long = $md_info->longitude;
  595. $is_set_distance = $md_info->is_set_distance;
  596. $distance = $md_info->distance;
  597. } else {
  598. $store_info = Store::findOne(get_store_id());
  599. $is_set_distance = $store_info->is_set_distance;
  600. $distance = $store_info->distance;
  601. $coordinate = explode(',', $store_info->coordinate);
  602. $lat = $coordinate[0];
  603. $long = $coordinate[1];
  604. }
  605. if ($is_set_distance) {
  606. $distance_str = Tools::getDistance($lat, $long, $address->latitude, $address->longitude);
  607. if ($distance_str != '未知距离') {
  608. if (false !== strpos($distance_str, 'km')) {
  609. if (floatval($distance_str) > $distance) {
  610. $t->rollBack();
  611. return [
  612. 'code' => 1,
  613. 'msg' => '当前订单超出配送距离'
  614. ];
  615. }
  616. } else {
  617. if (floatval($distance_str) > $distance * 1000) {
  618. $t->rollBack();
  619. return [
  620. 'code' => 1,
  621. 'msg' => '当前订单超出配送距离'
  622. ];
  623. }
  624. }
  625. }
  626. }
  627. }
  628. //判断服务范围
  629. if ($this->is_worker) {
  630. $result = $this->travel;
  631. $setting = WorkerSetting::getByStoreId(get_store_id());
  632. if ($result['distance'] > ($setting->order_range / 1000)) {
  633. return [
  634. 'code' => 1,
  635. 'msg' => '超出服务范围,请选择附近下单'
  636. ];
  637. }
  638. }
  639. // 开启使用积分抵扣
  640. if (isset($mch['use_integral']) && $mch['use_integral'] == 1) {
  641. if (get_user()->integralPrice < $mch['integral']['forehead'] || get_user()->integral < $mch['total_integral']) {
  642. return [
  643. 'code' => 1,
  644. 'msg' => '积分可抵扣支付数量不足'
  645. ];
  646. }
  647. }
  648. if ($order_type == 1) {
  649. $bookCount = count($mch_goods[0]['book']);
  650. $mch['level_price'] *= $bookCount;
  651. $mch['total_price'] *= $bookCount;
  652. }
  653. $mch['level_price'] = $this->getBookPrice($mch['level_price'], $mch_goods);
  654. $payPrice = $this->getPayPrice($mch);
  655. if ($is_have_express && $is_delivery->delivery_type == 1 && !empty($delivery_rules)) {
  656. if ($payPrice < $deliveryRules['delivery_price']) {
  657. return [
  658. 'code' => 1,
  659. 'msg' => '同城配送订单满 ¥' . $deliveryRules['delivery_price'] . ' 起送'
  660. ];
  661. }
  662. }
  663. $order = new Order();
  664. // $verifylog = new VerifyCardLog();
  665. // $verifycardsale = new VerifyCardSale();
  666. if($mch['delivery_time']){
  667. $order->delivery_time = strtotime($mch['delivery_time']);
  668. }
  669. // 订单来源
  670. if (is_h5()) {
  671. $order->order_origin = Order::ORDER_SOURCE_WEB;
  672. }
  673. if (is_app_platform()) {
  674. $order->order_origin = Order::ORDER_SOURCE_APP;
  675. }
  676. $order->total_price = $mch['total_price'];
  677. $order->level_diff_price = $mch['level_diff_price'];
  678. $order->store_id = $this->store_id;
  679. $order->user_id = $this->user_id;
  680. // 兼容手机端自提订单 核销订单展示部分 start 修改为使用user表数据
  681. $order->name = get_user()->nickname;
  682. $order->mobile = get_user()->binding;
  683. // end
  684. $order->buy_level_id = $this->buy_level_id ?: 0;
  685. $order->level_price_json = json_encode($mch['level_price_arr']);
  686. if (!empty($this->verify_card_id)) {
  687. $vcs = VerifyCardSale::findOne($this->verify_card_id);
  688. if($vcs->status == 1){
  689. return [
  690. 'code' => 1,
  691. 'msg' => '卡券已被使用过'
  692. ];
  693. }
  694. $order->type = 1;
  695. }
  696. if ($is_have_delivery) {
  697. if($this->order_no){
  698. $order->order_no = $this->order_no;
  699. }else{
  700. $goods_id = array_column($mch['goods_list'], 'goods_id');
  701. sort($goods_id);
  702. $goods_id = implode(',', $goods_id);
  703. $goods_id = md5($goods_id);
  704. $order->order_no = cache()->get('delivery_order_no_' . $goods_id . '_' . get_user_id());
  705. }
  706. $existOrder = Order::findOne(['order_no' => $order->order_no]);
  707. if($existOrder){
  708. $t->rollBack();
  709. return [
  710. 'code' => 1,
  711. 'msg' => '单号错误1,请后退到商品页重新下单' . $order->order_no . 'aa',
  712. ];
  713. }
  714. } else {
  715. $order->order_no = OrderNo::getOrderNo(OrderNo::ORDER_MALL);
  716. }
  717. $order->pay_price = !empty($this->verify_card_id) ? 0 : $payPrice;
  718. if ($mch['rand_discount_price'] > 0) {
  719. if ($order->pay_price <= 0) {
  720. $order->rand_discount = 0;
  721. } else {
  722. $order->pay_price -= $mch['rand_discount_price'];
  723. $order->rand_discount = $mch['rand_discount_price'];
  724. }
  725. }
  726. if ($mch['integral_appreciation_price'] > 0) {
  727. if ($order->pay_price <= 0) {
  728. $order->rand_discount = 0;
  729. } else {
  730. if ($order->pay_price > $mch['integral_appreciation_price']) {
  731. $order->pay_price -= $mch['integral_appreciation_price'];
  732. } else {
  733. $mch['integral_appreciation_price'] = $order->pay_price;
  734. $order->pay_price = 0;
  735. }
  736. $order->integral_appreciation_price = $mch['integral_appreciation_price'];
  737. }
  738. }
  739. if (isset($mch['picker_coupon']) && !empty($mch['picker_coupon'])) {
  740. $order->user_coupon_id = $mch['picker_coupon']['user_coupon_id'];
  741. $order->coupon_sub_price = $mch['picker_coupon']['sub_price'];
  742. // 查找优惠券优惠的商品
  743. $this->pickerGoods($mch);
  744. }
  745. // 订单类型
  746. $order->order_type = $order_type;
  747. // 积分兑换商品
  748. if (isset($mch['total_integral']) && $mch['total_integral'] > 0 ) {
  749. if (get_user()->integral < $mch['total_integral']) {
  750. //获取商城积分抵扣规则 x积分 = 1元
  751. $integral_rule = Option::find()->where(['store_id'=>get_store_id(),'name'=>'integral'])->select('value')->asArray()->one();
  752. $difference_price = sprintf("%.2f", ($mch['total_integral'] - get_user()->integral ) / $integral_rule['value'] );
  753. $order->pay_price += $difference_price;
  754. $order->total_price += $difference_price;
  755. $order->integral_price = get_user()->integral ?? 0;
  756. $order->integral_difference_price = $difference_price;
  757. $mch['integral_type'] = 2; //积分不足
  758. $mch['integral_difference_price'] = $difference_price; //补的差额
  759. }else{
  760. $order->integral_price = $mch['total_integral'] ?? 0;
  761. $order->integral_difference_price = 0;
  762. $mch['integral_type'] = 1; //全部使用积分
  763. $mch['integral_difference_price'] = 0; //补的差额
  764. }
  765. //当用户有积分时
  766. // if(get_user()->integral > 0){
  767. // $upIntegral = get_user()->integral - $order->integral_price;
  768. // //减用户积分
  769. // if(! User::updateAll(['integral'=>$upIntegral],['id'=> get_user_id()]) ){
  770. // $t->rollBack();
  771. // return [
  772. // 'code' => 1,
  773. // 'msg' => '积分抵扣失败,稍后重试!'
  774. // ];
  775. // }
  776. // }
  777. }
  778. // 是否是平台小程序订单
  779. if (is_platform()) {
  780. $order->is_platform = 1;
  781. }
  782. if (get_md_id()) {
  783. $order->md_id = get_md_id();
  784. }
  785. if($md_select > 0){
  786. $order->md_id = $md_select;
  787. }
  788. $order->is_fugou = $this->is_fugou;
  789. // if($this->send_price){
  790. // $order->send_price = $this->send_price;
  791. // }
  792. // if($this->take_price){
  793. // $order->take_price = $this->take_price;
  794. // }
  795. $order->take_price = $take_price;
  796. if ($order->pay_price > 0) {
  797. if($order->take_price > 0) {
  798. $order->pay_price -= $order->take_price;
  799. $order->total_price -= $order->take_price;
  800. }
  801. } else {
  802. if($order->take_price > 0) {
  803. $order->take_price = 0;
  804. $order->send_price = 0;
  805. }
  806. }
  807. $order->send_price = $send_price;
  808. $order->created_at = time();
  809. $order->first_price = 0;
  810. $order->second_price = 0;
  811. $order->third_price = 0;
  812. $order->content = isset($mch['content']) ? $mch['content'] : '';
  813. $order->is_offline = $is_have_shop ? 1 : 0;
  814. $order->is_delivery = $is_have_delivery ? 1 : 0;
  815. // TODO 商品余额抵扣
  816. if (isset($mch['use_balance']) && $mch['use_balance'] == 1) {
  817. $totalBalance = array_sum(array_column($mch['goods_list'], 'balance'));
  818. $order->balance = $totalBalance ? $totalBalance : 0;
  819. $order->pay_price -= $totalBalance;
  820. }
  821. if (isset($mch['use_integral']) && $mch['use_integral'] == 1) {
  822. $order->integral = json_encode($mch['integral'], JSON_UNESCAPED_UNICODE);
  823. $order->integral_difference_price = sprintf('%.2f', $mch['integral']['forehead']);
  824. $integral_price = $mch['integral']['forehead_integral'];
  825. if ($mch['total_integral']) {
  826. $integral_price = $mch['total_integral'];
  827. }
  828. $order->integral_price = $integral_price? $integral_price : 0;
  829. } else {
  830. $order->integral = json_encode(['forehead' => 0, 'forehead_integral' => 0], JSON_UNESCAPED_UNICODE);
  831. $order->integral_difference_price = 0;
  832. }
  833. $order->version = cyy_version();
  834. $order->mch_id = $mch['mch_id'] ?? 0;
  835. $order->discount = isset($level['discount']) ? $level['discount'] : 10;
  836. $order->remark = $mch['remark'] ?? '';
  837. if ($this->payment == 2) {
  838. $order->pay_type = 2;
  839. $order->is_pay = 0;
  840. }
  841. if ($this->payment == 3) {
  842. $order->pay_type = 3;
  843. $order->is_pay = 0;
  844. }
  845. // 线下支付
  846. if ($this->payment == 6) {
  847. $order->pay_type = 6;
  848. $order->is_pay = 0;
  849. }
  850. if ((!empty(input_params('flag_id')) || !empty(input_params('table_num')))) {
  851. if (get_md_id() < 0) {
  852. if (\Yii::$app->prod_is_dandianpu() || \Yii::$app->prod_is_shangmeng() || \Yii::$app->prod_is_shangmengduli()) {
  853. $store = Store::findOne(get_store_id());
  854. if ($store->open_status == 0) {
  855. $t->rollBack();
  856. return [
  857. 'code' => 1,
  858. 'msg' => '已打烊'
  859. ];
  860. }
  861. if ($store->is_time_forbid == 0 && !$this->checkTimeBeginEnd($store->s_time, $store->e_time) && $store->shop_time_type == 1) {
  862. $t->rollBack();
  863. return [
  864. 'code' => 1,
  865. 'msg' => '非营业时间禁止下单'
  866. ];
  867. }
  868. }
  869. }
  870. if (!empty(input_params('flag_id'))) {
  871. $order->food_flag_id = input_params('flag_id');
  872. } else {
  873. $order->food_flag_id = FoodFlag::findOne(['store_id' => get_store_id(), 'md_id' => get_md_id(), 'status' => 0, 'table_num' => input_params('table_num')])->id;
  874. }
  875. $order->order_type = 3;
  876. $order->food_book_ext = $mch['food_book_ext'];
  877. }
  878. if ($is_have_express || get_md_id()) {
  879. $order->address = $address->province . $address->city . $address->district . $address->town . $address->village . $address->detail;
  880. $order->mobile = $address->mobile ?: get_user()->binding;
  881. $order->name = $address->name ?: get_user()->nickname;
  882. if ($is_have_express) {
  883. if (!preg_match('/^1[1-9]\d{9}$/', $order->mobile) || empty($order->name)) {
  884. return [
  885. 'code' => 1,
  886. 'msg' => '请前往收货地址填写收货人以及手机号信息'
  887. ];
  888. }
  889. }
  890. if ($is_have_express) {
  891. $order->province_id = $address->province_id;
  892. $order->city_id = $address->city_id;
  893. $order->district_id = $address->district_id;
  894. $order->town_id = $address->town_id ? : 0;
  895. $order->village_id = $address->village_id ? : 0;
  896. }
  897. $order->address_data = json_encode([
  898. 'province' => trim($address->province),
  899. 'city' => trim($address->city),
  900. 'district' => trim($address->district),
  901. 'detail' => trim($address->detail),
  902. 'town' => $address->town_id ? trim($address->town) : '',
  903. 'village' => $address->village_id ? trim($address->village) : '',
  904. 'latitude' => $address->latitude,
  905. 'longitude' => $address->longitude,
  906. ], JSON_UNESCAPED_UNICODE);
  907. if ($is_have_delivery) {
  908. $order->total_price = !empty($this->verify_card_id) ? 0 : $mch['total_price'];
  909. } else {
  910. if (intval($order->order_type) === 6) {
  911. $order->book_info = json_encode(['worker_id' => $this->worker_id, 'worker_time' => $this->worker_time]);
  912. $order->express_price = $mch['travel_price'];
  913. $order->total_price = !empty($this->verify_card_id) ? 0 : $mch['total_price'] + $mch['travel_price'];
  914. if ($order_type_ext) {
  915. $order->order_type_ext = 601;
  916. }
  917. } else {
  918. $order->express_price = $mch['express_price'] ?? 0;
  919. ///
  920. $order->total_price = !empty($this->verify_card_id) ? 0 : $mch['total_price'] + ($mch['express_price'] ?? 0);
  921. }
  922. }
  923. }
  924. if ($is_have_shop) {
  925. $order->total_price = !empty($this->verify_card_id) ? 0 : $mch['total_price'];
  926. $order->express_price = 0;
  927. if (get_md_id()) {
  928. $md_info = Md::findOne(get_md_id());
  929. $order->province_id = $md_info->province;
  930. $order->city_id = $md_info->city;
  931. $order->district_id = $md_info->district;
  932. $order->town_id = 0;
  933. $order->village_id = 0;
  934. $md_address_province = District::findOne($md_info->province)->name ?: '';
  935. $md_address_city = District::findOne($md_info->city)->name ?: '';
  936. $md_address_district = District::findOne($md_info->district)->name ?: '';
  937. $order->address_data = json_encode([
  938. 'province' => trim($md_address_province),
  939. 'city' => trim($md_address_city),
  940. 'district' => trim($md_address_district),
  941. 'detail' => trim($md_info->address),
  942. 'town' => '',
  943. 'village' => '',
  944. 'latitude' => $md_info->latitude,
  945. 'longitude' => $md_info->longitude,
  946. ], JSON_UNESCAPED_UNICODE);
  947. $order->address = $md_address_province . $md_address_city . $md_address_district . $md_info->address;
  948. }
  949. }
  950. if ($order->order_type == 1 || $order->order_type == 2) {
  951. $order->book_info = Json::encode($mch['book_info']);
  952. }
  953. if ($order->order_type == 2) {
  954. $order->total_price = $payPrice;
  955. }
  956. if ($order->order_type == 1) {
  957. $order->total_price = $mch['total_price'];
  958. }
  959. // 礼品卡订单
  960. if (!empty(post_params('verify_card_id'))) {
  961. $order->verify_card_id = post_params('verify_card_id');
  962. }
  963. //获取代理配置信息
  964. $store = Store::findOne($this->store_id);
  965. //支付金额 * 店铺让利比例 * 代理商分润比例
  966. // $admin_profit = Option::get('admin_profit', 0, 'saas', 0)['value'];
  967. if (!empty($store->transfer_profit)) {
  968. $order->ag_rebate = $payPrice * ($store->transfer_profit / 100);
  969. }
  970. // 配送订单预存数据
  971. if ($is_have_delivery) {
  972. // $delivery_info = new DeliveryInfo();
  973. // $delivery_info->store_id = get_store_id();
  974. // $delivery_info->order_no = $order->order_no;
  975. // $delivery_info->status = 0;
  976. // $delivery_info->created_at = time();
  977. // $delivery_info->updated_at = time();
  978. // $delivery_info->save();
  979. }
  980. $order->saas_id = 0;
  981. $order->integral_difference_price = 0;
  982. if($this->activity_cut_price_order_id){
  983. $order->activity_cut_price_order_id = $this->activity_cut_price_order_id;
  984. }
  985. if($this->activity_wechat_room_id){
  986. $order->activity_wechat_room_id = $this->activity_wechat_room_id;
  987. }
  988. if ($is_have_delivery) {
  989. $cacheK = 'is_have_delivery_' . $order->order_no;
  990. $cacheV = cache()->get($cacheK);
  991. $deliveryInfo = DeliveryInfo::find()->where(['order_no' => $order->order_no])->one();
  992. if(!$deliveryInfo){
  993. $t->rollBack();
  994. if($cacheV){
  995. return [
  996. 'code' => 1,
  997. 'msg' => '配送单不存在,请返回商品详情页重新下单。' . $cacheV . $cacheK
  998. ];
  999. }
  1000. cache()->set($cacheK, 1, 180);
  1001. $this->order_no = $order->order_no;
  1002. $preOrder = $this->preOrder();
  1003. if($preOrder['code'] != 0){
  1004. return $preOrder;
  1005. }else{
  1006. $this->order_no = '';
  1007. return $this->save();
  1008. }
  1009. } else {
  1010. if (intval($deliveryInfo->wechat_delivery_type) === 1) {
  1011. $goods_list = [];
  1012. //foreach ($mch as $mch_item) {
  1013. foreach ($mch['goods_list'] as $goods) {
  1014. $goods_list[] = [
  1015. 'name' => $goods['goods_name'],
  1016. 'price' => $goods['price'],
  1017. 'pic' => $goods['goods_pic'],
  1018. 'num' => $goods['num'],
  1019. 'weight' => $goods['weight'],
  1020. ];
  1021. }
  1022. //}
  1023. $form = new WechatNewDelivery();
  1024. $result = $form->preAddOrder([
  1025. 'address' => ArrayHelper::toArray($this->address),
  1026. 'goods_list' => $goods_list,
  1027. 'store_id' => $this->store_id,
  1028. 'md_id' => get_md_id()
  1029. ]);
  1030. // $result = $form->addOrder([
  1031. // 'address' => ArrayHelper::toArray($this->address),
  1032. // 'goods_list' => $goods_list,
  1033. // 'store_id' => $order->store_id,
  1034. // 'md_id' => $order->md_id ?: 0,
  1035. // 'order_no' => $order->order_no,
  1036. // 'store_user' => ArrayHelper::toArray(get_user()),
  1037. // 'order_seq' => $deliveryInfo->serial_num,
  1038. // 'order_detail_path' => '/order/order-detail/order-detail?id=' . $order->id,
  1039. // ]);
  1040. if ($result['code'] === 0) {
  1041. $deliveryInfo = DeliveryInfo::findOne(['order_no' => $order->order_no]);
  1042. if (floatval($deliveryInfo->fee) !== floatval(bcdiv($result['data']['fee'], 100, 2))) {
  1043. $t->rollBack();
  1044. return [
  1045. 'code' => 1,
  1046. 'msg' => '配送费错误,请重新下单'
  1047. ];
  1048. }
  1049. } else {
  1050. $t->rollBack();
  1051. return $result;
  1052. }
  1053. }
  1054. }
  1055. $order->total_price += $deliveryInfo->fee;
  1056. $order->pay_price += $deliveryInfo->fee;
  1057. }
  1058. if($this->invoiceConf){
  1059. $order->tax_price += $mch['tax_price'];
  1060. $order->total_price += $mch['tax_price'];
  1061. $order->pay_price += $mch['tax_price'];
  1062. }
  1063. // 添加到货时间 已经根据到货时间进行过拆单 取第一个商品的到货规则进行存储即可
  1064. $order->arrival_time = $mch['goods_list'][0]['delivery_rules'] ? $mch['goods_list'][0]['delivery_rules']['arrival_time'] : 0;
  1065. // 增加订单对应的门店团购轰动ID
  1066. $order->md_group_activities_id = $mch['goods_list'][0]['md_group_activities_id'] ?? 0;
  1067. if($this->is_wastore){
  1068. $order->is_wastore = 1;
  1069. }
  1070. if($order->pay_price < 0){
  1071. $t->rollBack();
  1072. return [
  1073. 'code' => 1,
  1074. 'msg' => '订单金额错误,请检查优惠信息' . $order->pay_price,
  1075. 'mch' => [$mch, $order],
  1076. ];
  1077. }
  1078. if ($order->save()) {
  1079. if($this->is_giving_gifts){
  1080. $giving_gifts = GivingGiftsForm::orderSubmit($order, $this->giving_gifts_data);
  1081. if($giving_gifts['code']){
  1082. $t->rollBack();
  1083. return $giving_gifts;
  1084. }
  1085. }
  1086. //如果客户没有设置默认地址,当客户下单一次后,自动将该地址设置为 默认地址
  1087. if ($this->address) {
  1088. $check_address = Address::find()->where([
  1089. 'user_id' => get_saas_user_id(),
  1090. 'is_default' => 1,
  1091. 'is_delete' => 0,
  1092. ])->limit(1)->one();
  1093. if (empty($check_address)) {
  1094. $edit_address = Address::findOne($this->address['id']);
  1095. if ($edit_address) {
  1096. $edit_address->is_default = 1;
  1097. $edit_address->save();
  1098. }
  1099. }
  1100. }
  1101. if($this->is_wastore && $this->traceId){
  1102. cache()->set('wastoreShopOrderAdd' . $order->id, [
  1103. 'traceId' => $this->traceId,
  1104. ], 86400 * 30);
  1105. }
  1106. //砍价订单
  1107. if($this->activity_cut_price_order_id){
  1108. $orderUsed = ActivityCutPriceForm::orderUsed($this->activity_cut_price_order_id, $order);
  1109. if ($orderUsed['code'] != 0) {
  1110. $t->rollBack();
  1111. return $orderUsed;
  1112. }
  1113. }
  1114. //开发票
  1115. if($this->invoiceConf){
  1116. $orderInvoiceSave = \app\modules\admin\models\InvoiceForm::orderInvoiceSave($order->id, $this->invoiceConf);
  1117. if ($orderInvoiceSave['code'] != 0) {
  1118. $t->rollBack();
  1119. return $orderInvoiceSave;
  1120. }
  1121. }
  1122. // //如果是余额支付
  1123. // if($order->order_type == 7){
  1124. // $log = new AccountLog();
  1125. // $log->store_id = get_store_id();
  1126. // $log->user_id = get_user_id();
  1127. // $log->type = AccountLog::TYPE_INTEGRAL;
  1128. // $log->log_type = AccountLog::LOG_TYPE_EXPEND;
  1129. // $log->amount = $order->integral_price;
  1130. // $log->desc = "订单积分抵扣支付,订单号为:{$order->order_no}。";
  1131. // $log->before = get_user()->integral;
  1132. // $log->after = get_user()->integral - $order->integral_price;
  1133. // $log->operator = '';
  1134. // $log->operator_id = 0;
  1135. // $log->operator_type = AccountLog::TYPE_OPERATOR_NORMAL;
  1136. // $log->created_at = time();
  1137. // $log->order_id = $order->id;
  1138. // $log->order_type = AccountLog::TYPE_PLATFORM_ORDER;
  1139. // if(!$log->save()){
  1140. // $t->rollBack();
  1141. // return [
  1142. // 'code' => 1,
  1143. // 'msg' => '记录积分消耗失败,请稍后再试',
  1144. // 'error' => $log->errors[0]
  1145. // ];
  1146. // }
  1147. // }
  1148. //
  1149. // try {
  1150. // $res = $this->reduceIntegral($order);
  1151. // if ($res['code'] !== 0) {
  1152. // throw new \Exception($res['msg']);
  1153. // }
  1154. // } catch (\Exception $e) {
  1155. // $t->rollBack();
  1156. // return [
  1157. // 'code' => 1,
  1158. // 'msg' => '积分抵扣失败,请稍后再试',
  1159. // ];
  1160. // }
  1161. // 绑定上下级
  1162. $user = User::findOne($this->user_id);
  1163. if ($user && $user->parent_user_id) {
  1164. CommonOrder::saveParentId($user->parent_user_id);
  1165. }
  1166. // VerifyCard::updateAll(['send_times' => $send_times], 'id='.$VerifyCardSale['verify_card_id']);
  1167. // VerifyCardSale::updateAll(['left_num' => $left_num, 'status' => 1],'id='.$this->verify_card_id);
  1168. // $verifylog->save();
  1169. // 更改点餐flag_id状态
  1170. if (!empty(input_params('flag_id'))) {
  1171. FoodCart::updateAll(['is_delete' => 1], ['flag_id' => input_params('flag_id')]);
  1172. FoodFlag::updateAll(['status' => 1], ['id' => input_params('flag_id'), 'status' => 0]);
  1173. }
  1174. // 处理订单生成之后其他相关数据
  1175. $orderRes = $this->insertData($mch, $order);
  1176. if ($orderRes['code'] == 1) {
  1177. $t->rollBack();
  1178. return $orderRes;
  1179. }
  1180. $printer_order = new PrintOrder($order->store_id, $order->id, 'order', 0, $order->md_id, 0, $order['mch_id']);
  1181. $printer_order->print_order();
  1182. // 订单提交完成发送消息
  1183. $order_type = 0;
  1184. if ($order->order_type === 6) {
  1185. $order_type = 6;
  1186. }
  1187. $mch_name = '';
  1188. if($order['mch_id']){
  1189. $mch_name = '[' . $mch['name'] . ']';
  1190. }
  1191. NoticeSend::OrderSubmit($this->user_id, $order->mobile, $order->order_no, $order->pay_price, $mch_name . $mch_goods[0]['goods_name'], $order_type, $order->store_id);
  1192. $order_id_list[] = $order->id;
  1193. } else {
  1194. $t->rollBack();
  1195. return [
  1196. 'code' => 0,
  1197. 'msg' => implode(';', array_values($order->firstErrors)),
  1198. '$order' => $order->getErrors(),
  1199. '$order1' => $order->attributes,
  1200. ];
  1201. }
  1202. }
  1203. }
  1204. if (count($order_id_list) > 0) {
  1205. $t->commit();
  1206. $store = Store::findOne($this->store_id);
  1207. if (count($order_id_list) > 1) {//多个订单合并
  1208. return [
  1209. 'code' => 0,
  1210. 'msg' => '订单提交成功',
  1211. 'data' => (object)[
  1212. 'order_id_list' => $order_id_list,
  1213. 'add_time' => $order->created_at,
  1214. 'douyin_url' => $store->douyin_url,
  1215. ],
  1216. ];
  1217. } else {//单个订单
  1218. $order_id = $order_id_list[0];
  1219. // if ($order->pay_price > 0) {
  1220. // if($order->take_price > 0) {
  1221. // $order->pay_price -= $order->take_price;
  1222. // $order->total_price -= $order->take_price;
  1223. // }
  1224. // } else {
  1225. // if($order->take_price > 0) {
  1226. // $order->take_price = 0;
  1227. // $order->send_price = 0;
  1228. // }
  1229. // }
  1230. // $order->save();
  1231. $returnData = [
  1232. 'order_id' => $order_id_list[0],
  1233. 'add_time' => $order->created_at,
  1234. 'order_price'=> $order->pay_price,
  1235. 'douyin_url' => $store->douyin_url,
  1236. ];
  1237. // if ($mch['rand_discount_price'] > 0) {
  1238. // $randDiscountCache = cache()->get('rand_discount_cache2_' . $this->user_id);
  1239. // if ($randDiscountCache && $randDiscountCache['rand'] != $mch['rand_discount_price']) {
  1240. // return [
  1241. // 'code' => 1,
  1242. // 'msg' => '非法请求!',
  1243. // ];
  1244. // }
  1245. // $returnData['old_price'] = $order->pay_price;
  1246. // if ($order->pay_price <= 0) {
  1247. // $order->rand_discount = 0;
  1248. // $order->save();
  1249. // } else {
  1250. // $order->pay_price -= $mch['rand_discount_price'];
  1251. // $order->rand_discount = $mch['rand_discount_price'];
  1252. // $order->save();
  1253. // }
  1254. //
  1255. // $returnData['order_price'] = $order->pay_price;
  1256. // $returnData['rand_discount_price'] = $mch['rand_discount_price'];
  1257. // }
  1258. CloudPrint::doPrint($order_id, 0, $this->store_id);
  1259. return [
  1260. 'code' => 0,
  1261. 'msg' => '订单提交成功',
  1262. 'data' => (object)$returnData,
  1263. ];
  1264. }
  1265. } else {
  1266. $t->rollBack();
  1267. return [
  1268. 'order_list' => $order_id_list,
  1269. 'order_price'=> $order->pay_price
  1270. ];
  1271. }
  1272. }
  1273. /**
  1274. * 判断是否可以配送并计算费用
  1275. */
  1276. private function canDeliver($address, $conf)
  1277. {
  1278. // 解析商家地址的经纬度
  1279. list($shopLon, $shopLat) = explode(',', $conf['shop_tag']);
  1280. // 计算距离
  1281. $distance = Tools::getDistance((float)$shopLat, (float)$shopLon, $address->latitude ?: $address['latitude'], $address->longitude ?: $address['longitude']);
  1282. if (strpos($distance, 'km') !== false) {
  1283. $distance = floatval(explode('km', $distance)[0]);
  1284. } elseif (strpos($distance, 'm') !== false) {
  1285. $distance = floatval(explode('m', $distance)[0]) / 1000;
  1286. }
  1287. foreach ($conf['deliveryRules'] as $rule) {
  1288. if ($rule['start'] <= $distance && $distance <= $rule['end']) {
  1289. return [
  1290. 'can_deliver' => true,
  1291. 'distance' => $distance,
  1292. 'delivery_price' => $rule['price'],
  1293. 'delivery_range' => [$rule['start'], $rule['end']]
  1294. ];
  1295. }
  1296. }
  1297. return ['can_deliver' => false, 'distance' => $distance, 'delivery_price' => null, 'delivery_range' => null];
  1298. }
  1299. private function reduceIntegral($order)
  1300. {
  1301. try {
  1302. $integral = Json::decode($order->integral);
  1303. // 减去当前用户账户积分
  1304. if ($integral['forehead_integral'] > 0) {
  1305. $user = User::findOne($order->user_id);
  1306. $before = $user->integral;
  1307. if ($before < $integral['forehead_integral']) {
  1308. throw new \Exception('积分不足,抵扣失败');
  1309. }
  1310. $user->integral -= $integral['forehead_integral'];
  1311. if ($user->save()) {
  1312. $log = new AccountLog();
  1313. $log->store_id = $order->store_id;
  1314. $log->user_id = $user->id;
  1315. $log->type = AccountLog::TYPE_INTEGRAL;
  1316. $log->log_type = AccountLog::LOG_TYPE_EXPEND;
  1317. $log->amount = $integral['forehead_integral'];
  1318. $log->desc = "订单积分抵扣支付,订单号为:{$order->order_no}。";
  1319. $log->before = $before;
  1320. $log->after = $user->integral;
  1321. $log->operator = '';
  1322. $log->operator_id = 0;
  1323. $log->operator_type = AccountLog::TYPE_OPERATOR_NORMAL;
  1324. $log->created_at = time();
  1325. $log->order_id = $order->id;
  1326. $log->order_type = AccountLog::TYPE_PLATFORM_ORDER;
  1327. $log->save();
  1328. }
  1329. }
  1330. return [
  1331. 'code' => 0,
  1332. 'msg' => 'success'
  1333. ];
  1334. } catch (\Exception $e) {
  1335. return [
  1336. 'code' => 1,
  1337. 'msg' => $e->getMessage()
  1338. ];
  1339. }
  1340. }
  1341. public function getNo($attrStr, $searchAttrIds)
  1342. {
  1343. $attr = json_decode($attrStr, true);
  1344. foreach ($attr as $item) {
  1345. $attrIds = array_column($item['attr_list'], 'attr_id');
  1346. if ($attrIds == $searchAttrIds) {
  1347. return $item['no'];
  1348. }
  1349. }
  1350. }
  1351. // 获得实际支付金额
  1352. private function getPayPrice($mch)
  1353. {
  1354. $goods_list = $mch['goods_list'];
  1355. $payPrice = $mch['level_price'];
  1356. if (isset($mch['use_integral']) && $mch['use_integral']) {
  1357. $payPrice -= $mch['integral']['forehead'];
  1358. }
  1359. if (isset($mch['picker_coupon'])) {
  1360. $pickerCoupon = $mch['picker_coupon'];
  1361. if ($pickerCoupon['sub_price'] > 0) {
  1362. $coupon_price = 0;
  1363. if ($pickerCoupon['appoint_type'] == 1 && $pickerCoupon['cat_id_list'] != null) {
  1364. foreach ($goods_list as $goods) {
  1365. foreach ($goods['cat_id'] as $v1) {
  1366. if (in_array($v1, $pickerCoupon['cat_id_list'])) {
  1367. $coupon_price += floatval($goods['level_price']);
  1368. break;
  1369. };
  1370. };
  1371. }
  1372. } else if ($pickerCoupon['appoint_type'] == 2 && $pickerCoupon['goods_id_list'] != null) {
  1373. foreach ($goods_list as $goods) {
  1374. if (in_array($goods['goods_id'], $pickerCoupon['goods_id_list'])) {
  1375. $coupon_price += floatval($goods['level_price']);
  1376. };
  1377. }
  1378. };
  1379. if ($pickerCoupon['sub_price'] > $coupon_price && $coupon_price > 0) {
  1380. $payPrice -= $coupon_price;
  1381. } else {
  1382. $payPrice -= $pickerCoupon['sub_price'];
  1383. }
  1384. }
  1385. }
  1386. // Todo 此处有待确认算法是否正确 by Syan
  1387. // $payPrice = $payPrice > 0 ? $payPrice : 0.01;
  1388. if ($mch['express_price'] > 0) {
  1389. if (isset($mch['send']) && $mch['send'] == 'express') {
  1390. $payPrice += $mch['express_price'];
  1391. } else {
  1392. foreach ($goods_list as $goods) {
  1393. if (isset($goods['send']) && $goods['send'] == 'express') {
  1394. $payPrice += $mch['express_price'];
  1395. break;
  1396. }
  1397. }
  1398. }
  1399. }
  1400. if ($mch['travel_price'] > 0) {
  1401. $payPrice += $mch['travel_price'];
  1402. }
  1403. if ($this->buy_level_id) {
  1404. $level = Level::findOne($this->buy_level_id);
  1405. $payPrice += ($level->price * 1);
  1406. }
  1407. return $payPrice > 0 ? $payPrice : 0;
  1408. }
  1409. // 检查数据
  1410. private function checkMchData($mch)
  1411. {
  1412. if (empty($mch['goods_list'])) {
  1413. return [
  1414. 'code' => 1,
  1415. 'msg' => '商品不存在或已删除'
  1416. ];
  1417. }
  1418. $checkFormData = $this->checkFormData($mch);
  1419. if ($checkFormData['code'] == 1) {
  1420. return $checkFormData;
  1421. }
  1422. $checkSendType = $this->checkSendType($mch);
  1423. if ($checkSendType['code'] == 1) {
  1424. return $checkSendType;
  1425. }
  1426. $checkCoupon = $this->checkCoupon($mch);
  1427. if ($checkCoupon['code'] == 1) {
  1428. return $checkCoupon;
  1429. }
  1430. $checkGoods = $this->checkGoods($mch);
  1431. if ($checkGoods['code'] == 1) {
  1432. return $checkGoods;
  1433. }
  1434. $checkStbzOrder = $this->checkCloudOrder($mch);
  1435. if ($checkStbzOrder['code'] == 1) {
  1436. return $checkStbzOrder;
  1437. }
  1438. $checkMdFrontBind = $this->checkMdFrontBind($mch);
  1439. if ($checkMdFrontBind['code'] == 1) {
  1440. return $checkMdFrontBind;
  1441. }
  1442. return ['code' => 0, 'msg' => 'success'];
  1443. }
  1444. public function checkCloudOrder($mch)
  1445. {
  1446. try {
  1447. $address = (object)($this->address);
  1448. //胜天半子订单预下单
  1449. $spu = [];
  1450. foreach ($mch['goods_list'] as $arr) {
  1451. if ((int)$arr['cloud_goods_id'] > 0) {
  1452. $goods = Goods::findOne($arr['goods_id']);
  1453. $cloud_url = "/goods/getGoodsInfo";
  1454. $cloud_data = [];
  1455. $cloud_data['goods_id'] = $arr['cloud_goods_id'];
  1456. $domain = (new OptionSetting)->getCloudDomainName();
  1457. $cloud_info = cloud_post($domain . $cloud_url, $cloud_data);
  1458. $cloud_info = json_decode($cloud_info, true);
  1459. if($cloud_info['code'] != 0){
  1460. return $cloud_info;
  1461. }else{
  1462. $cloud_goods = $cloud_info['data']['goods'];
  1463. //获取云仓产品
  1464. if (intval($cloud_goods['stbz_goods_id']) !== 0) {
  1465. $attr_list = $arr['attr_list'];
  1466. $attr_id = array_column($attr_list, 'attr_id');
  1467. sort($attr_id);
  1468. $attr = json_decode($goods->attr, true);
  1469. foreach ($attr as $item) {
  1470. $attr_id_ = array_column($item['attr_list'], 'attr_id');
  1471. sort($attr_id_);
  1472. if (!array_diff($attr_id_, $attr_id)) {
  1473. $spu[] = [
  1474. 'number' => $arr['num'],
  1475. 'sku' => $item['no'],
  1476. ];
  1477. }
  1478. }
  1479. } else {
  1480. //检测其他类型商品
  1481. if (in_array($cloud_goods['send_type'], [5, 6])) {
  1482. //获取商城供货商
  1483. $supplier = Supplier::findOne(['cloud_supplier_id' => $cloud_goods['supplier_id'], 'is_delete' => 0]);
  1484. $supplierAgentFrontBind = AgentFrontBind::find()->where([
  1485. 'is_delete' => 0,
  1486. 'status' => 1,
  1487. 'type' => AgentFrontBind::TYPE_SUPPLIER,
  1488. 'type_id' => $supplier->id
  1489. ])->select('front_agent_admin_id')->column();
  1490. $md_id = get_md_id();
  1491. if ($md_id <= 0 || $mch['send'] == 'express') {
  1492. $mdAgentFrontBind = AgentFrontBind::find()->where([
  1493. 'type' => AgentFrontBind::TYPE_STORE,
  1494. 'type_id' => get_store_id(),
  1495. 'is_delete' => 0,
  1496. 'status' => 1,
  1497. 'front_agent_admin_id' => $supplierAgentFrontBind,
  1498. 'is_cloud_delivery' => AgentFrontBind::IS_CLOUD_DELIVERY_TRUE
  1499. ])->select('md_id, front_agent_admin_id')
  1500. ->orderBy('md_id ASC')->asArray()->one();
  1501. if (!$mdAgentFrontBind) {
  1502. $mdAgentFrontBind = AgentFrontBind::find()->where([
  1503. 'type' => AgentFrontBind::TYPE_STORE,
  1504. 'type_id' => get_store_id(),
  1505. 'is_delete' => 0,
  1506. 'status' => 1,
  1507. 'front_agent_admin_id' => $supplierAgentFrontBind
  1508. ])->select('md_id, front_agent_admin_id')
  1509. ->orderBy('md_id ASC')->asArray()->one();
  1510. }
  1511. } else {
  1512. $mdAgentFrontBind = AgentFrontBind::find()->where([
  1513. 'md_id' => $md_id,
  1514. 'is_delete' => 0,
  1515. 'status' => 1,
  1516. 'front_agent_admin_id' => $supplierAgentFrontBind
  1517. ])->select('md_id, front_agent_admin_id')
  1518. ->orderBy('md_id ASC')->asArray()->one();
  1519. }
  1520. if (!$mdAgentFrontBind) {
  1521. return ['code' => 1, 'msg' => '云仓商品类型绑定参数错误 请联系客服进行处理'];
  1522. }
  1523. $erpInventoryArray = AgentFrontErpInventory::find()->where(['goods_id' => $arr['cloud_goods_id'], 'front_agent_admin_id' => $mdAgentFrontBind['front_agent_admin_id']])
  1524. ->asArray()->one();
  1525. if (empty($erpInventoryArray)) {
  1526. return ['code' => 1, 'msg' => '云仓商品绑定参数错误 请联系客服进行处理'];
  1527. }
  1528. }
  1529. }
  1530. }
  1531. }
  1532. }
  1533. //胜天半子下单前检测
  1534. if ($spu) {
  1535. $params = [
  1536. 'spu' => $spu,
  1537. 'address' => [
  1538. 'consignee' => $address->name,
  1539. 'phone' => $address->mobile,
  1540. 'province' => trim($address->province),
  1541. 'city' => trim($address->city),
  1542. 'area' => trim($address->district),
  1543. 'street' => '',
  1544. 'description' => trim($address->detail),
  1545. ]
  1546. ];
  1547. debug_log('胜天半子商品信息' . json_encode($params));
  1548. $checkData = \stbz_client()->getApiResponse('post', '/v2/order/beforeCheck', $params);
  1549. $checkData = \json_decode($checkData, true);
  1550. debug_log('胜天半子下单检测' . json_encode($checkData));
  1551. if ($checkData['code'] != 1) {
  1552. throw new \Exception($checkData['msg']);
  1553. }
  1554. }
  1555. return [
  1556. 'code' => 0,
  1557. 'msg' => '下单检测成功'
  1558. ];
  1559. } catch (\Exception $e) {
  1560. return [
  1561. 'code' => 1,
  1562. 'msg' => $e->getMessage()
  1563. ];
  1564. }
  1565. }
  1566. //如果下单的产品的供货商绑定的仓库和门店是否绑定
  1567. private function checkMdFrontBind($mch)
  1568. {
  1569. $md_id = get_md_id();
  1570. return OrderTransit::checkMdFrontBind($mch, $md_id);
  1571. }
  1572. // 检测优惠券是否可使用
  1573. private function checkCoupon($mch)
  1574. {
  1575. if (empty($mch['picker_coupon'])) {
  1576. return [
  1577. 'code' => 0,
  1578. 'msg' => ''
  1579. ];
  1580. }
  1581. $ok = false;
  1582. foreach ($mch['coupon_list'] as $item) {
  1583. if ($item['user_coupon_id'] == $mch['picker_coupon']['user_coupon_id']) {
  1584. $ok = true;
  1585. }
  1586. }
  1587. if (!$ok) {
  1588. return [
  1589. 'code' => 1,
  1590. 'msg' => '该优惠券已过期'
  1591. ];
  1592. } else {
  1593. return [
  1594. 'code' => 0,
  1595. 'msg' => ''
  1596. ];
  1597. }
  1598. }
  1599. // 检测发货方式
  1600. private function checkSendType($mch)
  1601. {
  1602. if ($mch['mch_id'] == 0) {
  1603. if (isset($mch['is_offline']) && $mch['is_offline'] == 1) {
  1604. if (isset($mch['shop']) == false) {
  1605. return [
  1606. 'code' => 1,
  1607. 'msg' => '请选择自提门店'
  1608. ];
  1609. }
  1610. if (!(isset($mch['offline_name']) && $mch['offline_name']) || !(isset($mch['offline_mobile']) && $mch['offline_mobile'])) {
  1611. return [
  1612. 'code' => 1,
  1613. 'msg' => '请输入自提信息'
  1614. ];
  1615. }
  1616. if (!preg_match("/^1\d{10}$/", $mch['offline_mobile'])) {
  1617. return [
  1618. 'code' => 1,
  1619. 'msg' => '请输入正确的手机号'
  1620. ];
  1621. }
  1622. } else {
  1623. if (!$this->address) {
  1624. return [
  1625. 'coe' => 1,
  1626. 'msg' => '收货地址不存在'
  1627. ];
  1628. }
  1629. if ($mch['offer_rule'] && $mch['offer_rule']['is_allowed'] == 1 && $mch['send'] != 'delivery') {
  1630. return [
  1631. 'code' => 1,
  1632. 'msg' => $mch['offer_rule']['msg']
  1633. ];
  1634. }
  1635. if ($mch['is_area'] == 1 && $mch['send'] == 'express') {
  1636. return [
  1637. 'code' => 1,
  1638. 'msg' => '所选地区自营商品暂时无货'
  1639. ];
  1640. }
  1641. }
  1642. } else {
  1643. if (!$this->address) {
  1644. return [
  1645. 'coe' => 1,
  1646. 'msg' => '收货地址不存在'
  1647. ];
  1648. }
  1649. }
  1650. return ['code' => 0, 'msg' => ''];
  1651. }
  1652. // 检测自定义表单
  1653. private function checkFormData($mch)
  1654. {
  1655. foreach ($mch['goods_list'] as $goods) {
  1656. if (isset($goods['form']['code'])) {
  1657. return $goods['form'];
  1658. }
  1659. if (!isset($goods['form'])) {
  1660. continue;
  1661. }
  1662. $form = $goods['form'];
  1663. if ($form['is_form'] == 1) {
  1664. $form_list = $form['list'];
  1665. foreach ($form_list as $index => $value) {
  1666. if ($value['required'] == 1) {
  1667. if (in_array($value['type'], ['radio', 'checkbox'])) {
  1668. $is_true = false;
  1669. foreach ($value['default_list'] as $k => $v) {
  1670. if ($v['checked'] == true) {
  1671. $is_true = true;
  1672. }
  1673. }
  1674. if (!$is_true) {
  1675. return [
  1676. 'code' => 1,
  1677. 'msg' => '请填写' . $form['name'] . ',加“*”为必填项',
  1678. 'name' => $value['name']
  1679. ];
  1680. }
  1681. } else {
  1682. if (empty($value['default']) && strlen($value['default']) == 0) {
  1683. return [
  1684. 'code' => 1,
  1685. 'msg' => '请填写' . $form['name'] . ',加“*”为必填项',
  1686. 'name' => $value['name']
  1687. ];
  1688. }
  1689. }
  1690. }
  1691. }
  1692. }
  1693. }
  1694. return [
  1695. 'code' => 0,
  1696. 'msg' => ''
  1697. ];
  1698. }
  1699. // 检测商品相关
  1700. private function checkGoods($mch)
  1701. {
  1702. \Yii::warning($mch);
  1703. foreach ($mch['goods_list'] as $goods) {
  1704. $attr_id_list = [];
  1705. foreach ($goods['attr_list'] as $item) {
  1706. array_push($attr_id_list, $item['attr_id']);
  1707. }
  1708. $_goods = Goods::find()->where('id = ' . $goods['goods_id'] . ' for update')->one();
  1709. if($_goods->product_type == Goods::GOODS_TYPE_WORKER){
  1710. return [
  1711. 'code' => 0
  1712. ];
  1713. }
  1714. if (get_md_id() && empty(input_params('flag_id'))) {
  1715. $md = Md::findOne(get_md_id());
  1716. if ($md->is_single) {
  1717. $md_goods = MdGoods::findOne(['goods_id' => $_goods->id, 'md_id' => get_md_id()]);
  1718. if (!$md_goods) {
  1719. return [
  1720. 'code' => 1,
  1721. 'msg' => '订单提交失败,商品“' . $_goods->name . '”在当前门店无售卖权限',
  1722. ];
  1723. }
  1724. }
  1725. }
  1726. //2砍价商品6当面付
  1727. if ($_goods->type != 2 && $_goods->type != 6 && $_goods->product_type == Goods::GOODS_TYPE_NORMAL || $_goods->product_type == Goods::GOODS_TYPE_ADOPT) {
  1728. if (!$_goods->numSub($attr_id_list, $goods['num'])) {
  1729. return [
  1730. 'code' => 1,
  1731. 'msg' => '订单提交失败,商品“' . $_goods->name . '”库存不足',
  1732. 'attr_id_list' => $attr_id_list,
  1733. 'attr_list' => $goods['attr_list'],
  1734. ];
  1735. }
  1736. }
  1737. if($_goods->product_type == Goods::GOODS_TYPE_DATE){
  1738. $num = Goods::getGoodsNum($_goods)['data'];
  1739. $attr = $goods['book'];
  1740. foreach ($attr as $iattr) {
  1741. $idate = $iattr['date'];
  1742. foreach ($num as $inum) {
  1743. $indate = $inum['date'];
  1744. if(($idate == $indate) && ($inum['num'] < $goods['num'])){
  1745. return ['code' => 1, 'msg' => $idate.'库存不足'];
  1746. }
  1747. }
  1748. }
  1749. }
  1750. //加价保护start
  1751. $riskResult = Goods::getRiskStatus($goods['goods_id']);
  1752. if (!$riskResult) {
  1753. return ['code' => 1,'msg' => '商品状态异常 请尝试重新下单'];
  1754. }
  1755. $form = new MerchantForm();
  1756. $is_install = $form->goodsIsInstall($goods['goods_id']);
  1757. if ($is_install !== 2) {
  1758. $store = Store::findOne(get_store_id());
  1759. $store_address = [
  1760. 'province_id' => $store->province_id,
  1761. 'city_id' => $store->city_id,
  1762. 'district_id' => $store->district_id,
  1763. ];
  1764. if ($is_install !== 1) {
  1765. $md_id = get_md_id();
  1766. $md = Md::findOne($md_id);
  1767. $store_address = [
  1768. 'province_id' => $md->province,
  1769. 'city_id' => $md->city,
  1770. 'district_id' => $md->district,
  1771. ];
  1772. }
  1773. $address = $is_install === 1 ? $this->address : $store_address;
  1774. $result = $this->goodsIsGoodsAgent($address, $goods['goods_id']);
  1775. if ($result['code'] !== 0) {
  1776. return $result;
  1777. }
  1778. }
  1779. }
  1780. return ['code' => 0, 'msg' => ''];
  1781. }
  1782. public function getOrderNo()
  1783. {
  1784. $order_no = null;
  1785. while (true) {
  1786. $order_no = date('YmdHis') . mt_rand(100000, 999999);
  1787. $exist_order_no = Order::find()->where(['order_no' => $order_no])->exists();
  1788. if (!$exist_order_no) {
  1789. break;
  1790. }
  1791. }
  1792. return $order_no;
  1793. }
  1794. // 优惠券可优惠的商品总额计算
  1795. private function pickerGoods(&$mch)
  1796. {
  1797. $totalPrice = 0;
  1798. $pickerCoupon = $mch['picker_coupon'];
  1799. if (empty($pickerCoupon)) {
  1800. return;
  1801. }
  1802. foreach ($mch['goods_list'] as $item) {
  1803. if ($pickerCoupon['appoint_type'] == 1) {
  1804. if (!empty($pickerCoupon['cat_id_list'])) {
  1805. $catIdList = $pickerCoupon['cat_id_list'];
  1806. if (array_intersect($item['cat_id'], $catIdList)) {
  1807. $totalPrice += $item['price'];
  1808. $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
  1809. }
  1810. } else {
  1811. $totalPrice += $item['price'];
  1812. $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
  1813. }
  1814. } else if ($pickerCoupon['appoint_type'] == 2) {
  1815. if (!empty($pickerCoupon['goods_id_list'])) {
  1816. $goodsIdList = $pickerCoupon['goods_id_list'];
  1817. if (in_array($item['goods_id'], $goodsIdList)) {
  1818. $totalPrice += $item['price'];
  1819. $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
  1820. }
  1821. } else {
  1822. $totalPrice += $item['price'];
  1823. $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
  1824. }
  1825. } else {
  1826. $totalPrice += $item['price'];
  1827. $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
  1828. }
  1829. }
  1830. $mch['picker_coupon']['total_price'] = $totalPrice;
  1831. }
  1832. /**
  1833. * @param $mch
  1834. * @param $order Order
  1835. * @return array
  1836. */
  1837. private function insertData($mch, $order)
  1838. {
  1839. // 计算商品相关
  1840. $goods_list = $mch['goods_list'];
  1841. $goodsPrice = 0;
  1842. // 计算商品分润
  1843. $goods_profit = 0;
  1844. $chain_goods_profit = 0;
  1845. $chainGoodsList = [];
  1846. foreach ($goods_list as $goods) {
  1847. $i++ || MochatForm::sendMsg(1, get_store_id(), MochatForm::MSG_TYPE_SUBMIT_ORDER, get_saas_user_id(), ['goods_id' => $goods['id']]);
  1848. if ($goods['product_type'] == Goods::GOODS_TYPE_ADOPT) {
  1849. $adopt_order_info = new AdoptOrderInfo();
  1850. $adopt_order_info->name = $this->adopt_name;
  1851. $adopt_order_info->mobile = $this->adopt_mobile;
  1852. $adopt_order_info->order_id = $order->id;
  1853. $adopt_order_info->store_id = $this->store_id;
  1854. $adopt_goods = AdoptGoods::find()->where(['goods_id' => $goods['id']])->one();
  1855. $adopt_order_info->mature_time = time() + $adopt_goods->growth_cycle * 86400;
  1856. if (!$adopt_order_info->save()) {
  1857. return [
  1858. 'code' => 1,
  1859. 'msg' => '订单提交失败,请稍后再重试',
  1860. 'error' => $adopt_order_info->errors
  1861. ];
  1862. }
  1863. }
  1864. // 存入下单表单
  1865. if ($goods['form'] && $goods['form']['is_form'] == 1) {
  1866. foreach ($goods['form']['list'] as $index => $value) {
  1867. $order_form = new \app\models\OrderForm();
  1868. $order_form->store_id = $this->store_id;
  1869. $order_form->order_id = $order->id;
  1870. $order_form->goods_id = $goods['id'];
  1871. $order_form->key = $value['name'];
  1872. $order_form->value = $value['default'];
  1873. $order_form->type = $value['type'];
  1874. $order_form->is_delete = 0;
  1875. $order_form->save();
  1876. }
  1877. }
  1878. // 删除购物车
  1879. if (isset($goods['cart_id'])) {
  1880. Cart::updateAll(['is_delete' => 1], ['id' => $goods['cart_id']]);
  1881. }
  1882. Goods::updateAll(['updated_at' => time()], ['id' => $goods['goods_id']]);
  1883. $order_detail = new OrderDetail();
  1884. $order_detail->order_id = $order->id;
  1885. $order_detail->goods_id = $goods['goods_id'];
  1886. $order_detail->num = $goods['num'];
  1887. if (isset($goods['cost_price'])) {
  1888. $order_detail->cost_price = $goods['cost_price'];
  1889. }
  1890. // if ($goods['is_level'] && $goods['is_level'] == 1) {
  1891. // $order_detail->is_level = (int)$goods['is_level'];
  1892. // } else {
  1893. $order_detail->is_level = 1;
  1894. // }
  1895. if ($this->buy_level_id) {
  1896. $payPrice = $goods['next_level_price'];
  1897. } else {
  1898. $payPrice = $goods['level_price'];
  1899. if ($goods['payment_type']) {
  1900. $order_detail->pre_price = $goods['pre_price'];
  1901. }
  1902. }
  1903. //使用优惠券
  1904. if (isset($mch['picker_coupon']) && $mch['picker_coupon'] && !empty($mch['picker_coupon'])) {
  1905. if (is_string($mch['picker_coupon']['goods_id_list'])) {
  1906. $mch['picker_coupon']['goods_id_list'] = json_decode($mch['picker_coupon']['goods_id_list'], true);
  1907. }
  1908. // 这里要考虑优惠券不设置指定商品或者指定商品分类的情况
  1909. // 三种情况 1.优惠券未指定商品分类 同时 也没有指定商品
  1910. // 2.优惠券指定了商品分类 且 商品所属分类在指定的分类中
  1911. // 3.优惠券指定了商品 且购买商品在指定商品中
  1912. if(((empty($mch['picker_coupon']['goods_id_list']) && empty($mch['picker_coupon']['cat_id_list'])) || (!empty($mch['picker_coupon']['goods_id_list']) && in_array($goods['goods_id'], $mch['picker_coupon']['goods_id_list'])) || (!empty($mch['picker_coupon']['cat_id_list'] && array_intersect($goods['cat_id'], $mch['picker_coupon']['cat_id_list'])))) && $mch['picker_coupon']['total_price'] > 0){
  1913. $pickerCouponSubPrice = doubleval($mch['picker_coupon']['sub_price'] * doubleval($goods['price']) / $mch['picker_coupon']['total_price']);
  1914. $payPrice -= $pickerCouponSubPrice;
  1915. }
  1916. // 删除优惠券
  1917. UserCoupon::updateAll(['is_use' => 1], ['id' => $mch['picker_coupon']['user_coupon_id']]);
  1918. }
  1919. //使用积分
  1920. if (isset($mch['use_integral']) && $mch['use_integral']) {
  1921. if ($goods['resIntegral'] && $goods['resIntegral']['forehead'] > 0) {
  1922. $payPrice -= $goods['resIntegral']['forehead'];
  1923. }
  1924. }
  1925. //使用联盟券抵扣
  1926. if ($goods['take_price'] > 0) {
  1927. $payPrice -= $goods['take_price'];
  1928. }
  1929. //使用余额抵扣
  1930. if ($goods['balance'] > 0) {
  1931. $payPrice -= $goods['balance'];
  1932. }
  1933. //随机立减
  1934. if ($goods['rand_discount_price'] > 0) {
  1935. $payPrice -= $goods['rand_discount_price'];
  1936. }
  1937. //增值积分
  1938. if ($goods['integral_appreciation_price'] > 0) {
  1939. if ($payPrice > $goods['integral_appreciation_price']) {
  1940. $payPrice -= $goods['integral_appreciation_price'];
  1941. } else {
  1942. $goods['integral_appreciation_price'] = $payPrice;
  1943. $payPrice = 0;
  1944. }
  1945. }
  1946. $payPrice = $payPrice >= 0 ? sprintf('%.2f', $payPrice) : 0;
  1947. $goodsPrice += $payPrice;
  1948. $orderPrice = floatval($order->pay_price) - floatval($order->express_price);
  1949. if ($goodsPrice > $orderPrice) {
  1950. $payPrice = $payPrice - ($goodsPrice - $orderPrice);
  1951. $goodsPrice = $orderPrice;
  1952. }
  1953. $payPrice = $this->getBookPrice($payPrice, $goods_list);
  1954. // $order_detail->supplier_price = $goods['supplier_price'];
  1955. if ($goods['payment_type']) {
  1956. $payPrice = $goods['level_price'];
  1957. }
  1958. $order_detail->total_price = $payPrice;
  1959. $order_detail->integral_appreciation_price = $goods['integral_appreciation_price'] ?: '0.00';
  1960. $order_detail->integral_appreciation_amount = $goods['integral_appreciation_amount'] ?: '0.00';
  1961. // 计算单个商品可分红金额
  1962. $profit = $goods['rate_type'] == 0 ? floatval($payPrice * $goods['rate'] / 100) : floatval($goods['rate']) * $goods['num'];
  1963. $goods_profit += $profit;
  1964. $order_detail->profit = $profit;
  1965. // 链动
  1966. $chain_profit = $goods['chain_rate_type'] == 0 ? floatval($payPrice * $goods['chain_rate'] / 100) : floatval($goods['chain_rate']) * $goods['num'];
  1967. $chain_goods_profit += $chain_profit;
  1968. $order_detail->chain_profit = $chain_profit;
  1969. $order_detail->is_delete = 0;
  1970. $chainGoodsList[] = [
  1971. 'id' => $goods['id'],
  1972. 'num' => $goods['num'],
  1973. 'pay_price' => $payPrice,
  1974. ];
  1975. $shareHolderRepeatProfitSwitch = (int)Option::get('shareHolderRepeatProfitSwitch', $order->store_id, 'bonus_pool', 0)['value'];
  1976. //判断是否是升级产品
  1977. $open = false;
  1978. $shareHolderLevelList = ShareHolderLevel::find()->where(['store_id' => $order->store_id, 'status' => 1, 'is_delete' => 0])->select('condition, id, level, member_level')->asArray()->all();
  1979. foreach ($shareHolderLevelList as $item) {
  1980. $condition = json_decode($item['condition'], true);
  1981. if ((int)$condition['goods']['is_open'] === 1 && !empty($condition['goods']['value']['id']) && in_array($goods['id'], $condition['goods']['value']['id'])) {
  1982. $open = true;
  1983. break;
  1984. }
  1985. }
  1986. //如果是分红产品或者是升级产品则添加记录
  1987. if (floatval(sprintf("%.2f", ($profit / $goods['num']))) > 0 || $open) {
  1988. if ($shareHolderRepeatProfitSwitch) {
  1989. $profitGoodsLog = new ShareHolderProfitGoodsLog();
  1990. $profitGoodsLog->user_id = get_user_id();
  1991. $profitGoodsLog->goods_id = $goods['id'];
  1992. $profitGoodsLog->order_id = $order->id;
  1993. $profitGoodsLog->goods_price = floatval(sprintf("%.2f", ($payPrice / $goods['num'])));
  1994. $profitGoodsLog->goods_profit = floatval(sprintf("%.2f", ($profit / $goods['num'])));
  1995. $profitGoodsLog->is_switch = intval($shareHolderRepeatProfitSwitch);
  1996. if (!$profitGoodsLog->save()) {
  1997. return [
  1998. 'code' => 1,
  1999. 'msg' => implode(';', array_values($profitGoodsLog->firstErrors))
  2000. ];
  2001. };
  2002. // }
  2003. }
  2004. }
  2005. //
  2006. if ($goods['product_type'] == 1) {
  2007. $order_detail->attr = json_encode($goods['book'], JSON_UNESCAPED_UNICODE);
  2008. } elseif ($goods['product_type'] == 2) {
  2009. //$order_detail->attr = json_encode($goods['service'], JSON_UNESCAPED_UNICODE);
  2010. $service = $goods['service'];
  2011. $time = explode('-', $service['time']);
  2012. $order_detail->attr = json_encode([
  2013. 'start_date' => $service['date'] . ' ' . $time[0],
  2014. 'end_date' => $service['date'] . ' ' . $time[1],
  2015. 'time' => $service['time'],
  2016. 'date' => $service['date'],
  2017. 'price' => $service['price'],
  2018. ], JSON_UNESCAPED_UNICODE);
  2019. } else {
  2020. $order_detail->attr = json_encode($goods['attr_list'], JSON_UNESCAPED_UNICODE);
  2021. $order_detail->food_ext_goods = json_encode($goods['food_ext_goods'], JSON_UNESCAPED_UNICODE);
  2022. }
  2023. $goods_info = Goods::findOne($goods['goods_id']);
  2024. $order_detail->pic = $goods['goods_pic'] ? $goods['goods_pic'] : $goods_info->cover_pic;
  2025. $order_detail->goods_name = $goods_info ? $goods_info->name : $goods['goods_name'];
  2026. if (!empty($goods_info)) {
  2027. //在添加下单商品信息时增加链动等级记录 为了实现小推大功能
  2028. $goods_info = $goods_info->toArray();
  2029. $goods_info['goods_chain_level'] = GoodsChainLevel::find()->where(['goods_id' => $goods_info['id']])->asArray()->one();
  2030. }
  2031. $order_detail->goods_info = $goods_info ? Json::encode($goods_info) : Json::encode([]);
  2032. $order_detail->delivery_type = $mch['send'] == 'express' ? OrderDetail::GOODS_DELIVERY_EXPRESS : ($mch['send'] == 'delivery' ? OrderDetail::GOODS_DELIVERY_IM : OrderDetail::GOODS_DELIVERY_SHOP);
  2033. if ($mch['send'] == 'shop' && empty(input_params('flag_id'))) {
  2034. if(isset($goods['shop_id']) && $goods['shop_id'] > 0){
  2035. $order_detail->shop_id = $goods['shop_id'];
  2036. }else{
  2037. $order_detail->shop_id = 0;
  2038. }
  2039. }
  2040. if ($goods['give'] > 0) {
  2041. $order_detail->integral = $goods['give'];
  2042. } else {
  2043. $order_detail->integral = 0;
  2044. }
  2045. $attr_id_list = [];
  2046. foreach ($goods['attr_list'] as $item) {
  2047. array_push($attr_id_list, $item['attr_id']);
  2048. }
  2049. $order_detail->batch_price_tips = $goods['current_batch_price_tips'];
  2050. // 存入点餐的user_id
  2051. if (!empty($goods['user_id'])) {
  2052. $order_detail->user_id = $goods['user_id'];
  2053. }
  2054. // 积分兑换商品 1次只能兑换1个
  2055. if ($order->order_type == 7){
  2056. $order_detail->total_price = $order->total_price;
  2057. $order_detail->integral_price = $order->integral_price;
  2058. $order_detail->integral_difference_price = $order->integral_difference_price;
  2059. }
  2060. //增值积分下单扣减用户积分
  2061. $integralAppreciationGoods = IntegralAppreciationGoods::findOne(['goods_id' => $goods['id'], 'is_delete' => 0]);
  2062. if ($integralAppreciationGoods && $integralAppreciationGoods->integral_amount > 0) {
  2063. $integral_appreciation_setting = Option::get('integral_appreciation_setting', $order->store_id, 'integral_appreciation')['value'];
  2064. $integral_appreciation_setting = json_decode($integral_appreciation_setting ?? '', true);
  2065. $integral_custom_name = $integral_appreciation_setting['integral_custom_name'] ?: '增值积分';
  2066. $integralAppreciationUser = IntegralAppreciationUser::findOne(['user_id' => $this->user_id]);
  2067. if (!$integralAppreciationUser) {
  2068. return [
  2069. 'code' => 1,
  2070. 'msg' => "用户{$integral_custom_name}数量不足"
  2071. ];
  2072. }
  2073. $integral_amount = bcmul($integralAppreciationGoods->integral_amount, $goods['num'], 2);
  2074. if ($integral_amount > $integralAppreciationUser->integral) {
  2075. return [
  2076. 'code' => 1,
  2077. 'msg' => "用户{$integral_custom_name}数量不足"
  2078. ];
  2079. }
  2080. $integralAppreciationUser->integral = bcsub($integralAppreciationUser->integral, $integral_amount, 2);
  2081. $integralAppreciationUser->save();
  2082. $result = IntegralAppreciationUserIntegralLog::saveIntegralLog(
  2083. $integralAppreciationUser->id,
  2084. $integral_amount,
  2085. IntegralAppreciationUserIntegralLog::TYPE_EXPEND,
  2086. IntegralAppreciationUserIntegralLog::SOURCE_TYPE_BUY_GOODS, "购买商品 订单号{$order->order_no}",
  2087. $order->id);
  2088. if ($result['code']) {
  2089. return $result;
  2090. }
  2091. }
  2092. if (!$order_detail->save()) {
  2093. return [
  2094. 'code' => 1,
  2095. 'msg' => '订单提交失败,请稍后再重试',
  2096. 'error' => $order_detail->errors[0]
  2097. ];
  2098. }
  2099. if ($this->is_seckill) {
  2100. $seckill_activity_goods = SeckillActivityGoods::find()->alias('sag')->where(['sag.goods_id' => $goods['goods_id']])
  2101. ->leftJoin(['sg' => SeckillActivity::tableName()], 'sg.id = sag.activity_id')
  2102. ->andWhere(['AND', ['>', 'sg.end_time', time()], ['<', 'sg.start_time', time()], ['sg.is_delete' => 0, 'sag.is_delete' => 0, 'sg.store_id' => get_store_id()]])
  2103. ->select('sag.id sag_id, sg.id, sg.end_time, sag.attr, sag.use_attr, sag.seckill_num, sag.seckill_price, sag.sale_num, sg.order_limit_num, sg.self_limit_num')->asArray()->one();
  2104. if ($seckill_activity_goods) {
  2105. $activity_order_log = new SeckillActivityOrderLog();
  2106. $activity_order_log->order_id = $order->id;
  2107. $activity_order_log->order_detail_id = $order_detail->id;
  2108. $activity_order_log->user_id = get_user_id();
  2109. $activity_order_log->sale_price = $goods['level_price'];
  2110. $activity_order_log->activity_id = $seckill_activity_goods['id'];
  2111. $activity_order_log->activity_goods_id = $seckill_activity_goods['sag_id'];
  2112. $activity_order_log->goods_id = $goods['goods_id'];
  2113. $activity_order_log->num = $goods['num'];
  2114. $activity_order_log->store_id = get_store_id();
  2115. if (!$activity_order_log->save()) {
  2116. debug_log("秒杀信息保存" . json_encode($activity_order_log->errors));
  2117. }
  2118. $order->seckill_order_id = $activity_order_log->id;
  2119. }
  2120. }
  2121. if (!empty($goods['videoId'])) {
  2122. //获取抖品信息
  2123. $video_goods = VideoGoodsList::findOne($goods['videoId']);
  2124. //获取抖品配置信息
  2125. $setting = VideoGoodsSetting::findOne(['store_id' => get_store_id()]);
  2126. //获取商品配置信息
  2127. $goods_info = Goods::findOne($goods['goods_id']);
  2128. $profit = ($setting->profit / 100);
  2129. if ($profit > 0 && $video_goods && $goods_info) {
  2130. $video_share = new VideoGoodsShare();
  2131. $video_share->order_id = $order->id;
  2132. $video_share->goods_id = $goods['goods_id'];
  2133. $video_share->num = $goods['num'];
  2134. $video_share->order_detail = $order_detail->id;
  2135. $video_share->video_goods_id = $goods['videoId'];
  2136. $video_share->store_id = get_store_id();
  2137. $video_share->author_user_id = $video_goods->user_id;
  2138. $video_share->created_at = time();
  2139. $video_share->profit = $setting->profit;
  2140. $video_share->proportion = ($goods['level_price'] * $profit);
  2141. if (!$video_share->save()) {
  2142. return [
  2143. 'code' => 1,
  2144. 'msg' => implode(';', array_values($video_share->firstErrors))
  2145. ];
  2146. }
  2147. }
  2148. }
  2149. }
  2150. if ($this->buy_level_id) {
  2151. $level = Level::findOne($this->buy_level_id);
  2152. $orderLevel = new LevelOrder();
  2153. $orderLevel->store_id = get_store_id();
  2154. $orderLevel->user_id = get_user_id();
  2155. $orderLevel->current_level = get_user()->level;
  2156. $orderLevel->after_level = $level->level;
  2157. $orderLevel->order_no = OrderNo::getOrderNo(OrderNo::ORDER_LEVEL);
  2158. $orderLevel->is_pay = 0;
  2159. $orderLevel->is_delete = 0;
  2160. $orderLevel->created_at = time();
  2161. $orderLevel->pay_price = $level->price;
  2162. if ($orderLevel->save()) {
  2163. $order->level_order_id = $orderLevel->id;
  2164. }
  2165. }
  2166. // goods_profit 计算之后存入订单表中
  2167. $order->profit = $goods_profit;
  2168. $order->chain_profit = $chain_goods_profit;
  2169. $orderChainLevelProfit = \app\utils\Share\BonusPool::getOrderLevelProfit(get_store_id(), $chainGoodsList);
  2170. $order->chain_level_value = json_encode($orderChainLevelProfit);
  2171. $order->save();
  2172. // 计算门店收益
  2173. if (get_md_id() > 0 && !in_array($order->order_type, [1, 2])) {
  2174. $result = OrderForm::findPrice($order->id);
  2175. MdProfit::handleProfit($order->id, $result['original_price'], $result['md_price'], $order->md_id);
  2176. }else{
  2177. if ($order->is_offline || in_array($order->order_type, [1, 2])) {
  2178. MdProfit::handleProfit($order->id, $order->total_price, $order->total_price, $order->md_id);
  2179. }
  2180. }
  2181. if (!empty($this->worker)) {
  2182. $order_ext = WorkerOrderExt::findOne(['order_id' => $order->id]);
  2183. $order_ext->worker_id = $this->worker['id'];
  2184. if (!empty($this->travel)) {
  2185. $order_ext->dis = $this->travel['distance'];
  2186. }
  2187. $order_ext->save();
  2188. }
  2189. $order->afterOtherDataSave();
  2190. return [
  2191. 'code' => 0,
  2192. 'msg' => ''
  2193. ];
  2194. }
  2195. public function getBookPrice($payPrice, $mch_goods)
  2196. {
  2197. $price = $payPrice;
  2198. foreach ($mch_goods as $goods) {
  2199. if ($goods['product_type'] == 1) {
  2200. $price = 0;
  2201. $goods_id = $goods['goods_id'];
  2202. $goodsInfoObj = Goods::findOne($goods_id);
  2203. if ($goodsInfoObj) {
  2204. $service_book_desc = json_decode($goodsInfoObj->service_book_desc ?: '', true);
  2205. }
  2206. if (!empty($service_book_desc)) {
  2207. if (empty($goods['book'])) {
  2208. return [
  2209. 'code' => 1,
  2210. 'msg' => '预约日期数据为空'
  2211. ];
  2212. }
  2213. foreach ($goods['book'] as $value) {
  2214. $book_date = strtotime($value['date']);
  2215. foreach ($service_book_desc as $service_book_item) {
  2216. $service_book_date = strtotime($service_book_item['date']);
  2217. if ($book_date === $service_book_date) {
  2218. $price += $service_book_item['price'];
  2219. }
  2220. }
  2221. }
  2222. $price = $price * $goods['num'];
  2223. }
  2224. }
  2225. if ($goods['product_type'] == 2) {
  2226. $price = 0;
  2227. $goods_book = GoodsBook::findOne(['goods_id' => $goods['id']]);
  2228. $service_book = Json::decode($goods_book->service_book);
  2229. //$service_book = $service_book['data'];
  2230. $date_data = $this->getDateByInterval(7);
  2231. $new_arr = [
  2232. 'data' => []
  2233. ];
  2234. foreach ($date_data as $index => $datum) {
  2235. $new_arr['data'][$index]['date'] = $datum;
  2236. $new_arr['data'][$index]['time'] = $service_book['data'][0]['time'];
  2237. }
  2238. if (!$new_arr) {
  2239. return [
  2240. 'code' => 1,
  2241. 'msg' => '数据异常'
  2242. ];
  2243. }
  2244. $price = 0;
  2245. $service_book = $new_arr['data'];
  2246. $service_book_date = array_column($service_book, NULL, 'date');
  2247. $service_book_time = $service_book_date[$goods['service']['date']]['time'];
  2248. foreach ($service_book_time as $m) {
  2249. foreach ($m['times'] as $n) {
  2250. if ($n['time'] == $goods['service']['time']) {
  2251. $price = $goods['service']['price'] * $goods['num'];
  2252. break;
  2253. }
  2254. }
  2255. if ($price > 0) {
  2256. break;
  2257. }
  2258. }
  2259. }
  2260. }
  2261. \Yii::error($price);
  2262. return $price;
  2263. }
  2264. /**
  2265. * 检查当前时间是否为指定时间范围内
  2266. * @param $begin 20:00:00
  2267. * @param $end 08:00:00
  2268. * @param $date
  2269. * @return bool true 时间范围内
  2270. */
  2271. private function checkTimeBeginEnd ($begin, $end, $date = null)
  2272. {
  2273. if (empty($begin) && empty($end)) {
  2274. return true;//
  2275. }
  2276. $date = is_null ($date) ? date ('H:i:s') : $date;
  2277. $curTime = strtotime ($date); // 当前时分
  2278. $assignTime1 = strtotime ($begin); // 获得指定分钟时间戳,00:00
  2279. $assignTime2 = strtotime ($end); // 获得指定分钟时间戳,01:00
  2280. $result = false;
  2281. if ($assignTime1 > $assignTime2) {
  2282. //跨24点
  2283. if ($curTime > $assignTime1 || $curTime < $assignTime2) {
  2284. $result = true;
  2285. }
  2286. }
  2287. if ($curTime > $assignTime1 && $curTime < $assignTime2) {
  2288. $result = true;
  2289. }
  2290. if ($assignTime1 == $assignTime2) {
  2291. $result = true;
  2292. }
  2293. return $result;
  2294. }
  2295. public function giftsReceivedAddr($param) {
  2296. $orderId = $param['order_id'];
  2297. try{
  2298. $order = Order::findOne($orderId);
  2299. if(GivingGiftsForm::isReceivedTimeout($order) > 0){
  2300. throw new \Exception('超出礼物领取时效');
  2301. }
  2302. if($order->giving_gifts_received_user_id > 0){
  2303. throw new \Exception('礼物已领取');
  2304. }
  2305. $order->giving_gifts_received_user_id = $this->user_id;
  2306. $address = (object)($this->getAddressData());
  2307. $order->address = $address->province . $address->city . $address->district . $address->town . $address->village . $address->detail;
  2308. $order->mobile = $address->mobile ?: get_user()->binding;
  2309. $order->name = $address->name ?: get_user()->nickname;
  2310. $order->province_id = $address->province_id;
  2311. $order->city_id = $address->city_id;
  2312. $order->district_id = $address->district_id;
  2313. $order->town_id = $address->town_id ? : 0;
  2314. $order->village_id = $address->village_id ? : 0;
  2315. $order->address_data = json_encode([
  2316. 'province' => trim($address->province),
  2317. 'city' => trim($address->city),
  2318. 'district' => trim($address->district),
  2319. 'detail' => trim($address->detail),
  2320. 'town' => $address->town_id ? trim($address->town) : '',
  2321. 'village' => $address->village_id ? trim($address->village) : '',
  2322. 'latitude' => $address->latitude,
  2323. 'longitude' => $address->longitude,
  2324. ], JSON_UNESCAPED_UNICODE);
  2325. if (!$order->save()) {
  2326. throw new \Exception(array_shift($order->getFirstErrors()));
  2327. }
  2328. } catch (\Exception $ex) {
  2329. \Yii::error($ex);
  2330. debug_log([__METHOD__, __LINE__, $orderId, $this->address, $ex->getMessage()], __CLASS__ . '.log');
  2331. return [
  2332. 'code' => 1,
  2333. 'msg' => $ex->getMessage(),
  2334. ];
  2335. }
  2336. return [
  2337. 'code' => 0,
  2338. 'msg' => 'ok',
  2339. ];
  2340. }
  2341. }