OrderForm.php 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\alliance\models\pt\order;
  8. use app\constants\OptionSetting;
  9. use app\models\Address;
  10. use app\models\Admin;
  11. use app\models\AgentGoodsBindGoods;
  12. use app\models\Attr;
  13. use app\models\AttrGroup;
  14. use app\models\Cat;
  15. use app\models\Coupon;
  16. use app\models\CouponAutoSend;
  17. use app\models\Form;
  18. use app\models\FreeDeliveryRules;
  19. use app\models\Goods;
  20. use app\models\GoodsBook;
  21. use app\models\GoodsCat;
  22. use app\models\Level;
  23. use app\models\Mch;
  24. use app\models\MchGoodsCat;
  25. use app\models\MdGoods;
  26. use app\models\OfferPrice;
  27. use app\models\Option;
  28. use app\models\Order;
  29. use app\models\OrderDetail;
  30. use app\models\PostageRules;
  31. use app\models\PtActivity;
  32. use app\models\PtActivityGoods;
  33. use app\models\PtActivityOrder;
  34. use app\models\PtActivityOrderDetail;
  35. use app\models\SeckillActivity;
  36. use app\models\SeckillActivityGoods;
  37. use app\models\SeckillActivityOrderLog;
  38. use app\models\Shop;
  39. use app\models\Store;
  40. use app\models\TerritorialLimitation;
  41. use app\models\User;
  42. use app\models\UserCoupon;
  43. use app\utils\Delivery\Delivery;
  44. use app\utils\Delivery\Alipay\ADelivery;
  45. use Yii;
  46. use yii\base\Model;
  47. use yii\helpers\Json;
  48. class OrderForm extends Model
  49. {
  50. public $mch_list;
  51. public $address_id;
  52. public $_from;
  53. public $longitude;
  54. public $latitude;
  55. public $send_price;
  56. public $take_price;
  57. public $store_id;
  58. public $store;
  59. public $user_id;
  60. public $verify_card_id;
  61. /** @var User $user */
  62. protected $user;
  63. protected $address;
  64. protected $level;
  65. protected $integral;
  66. protected $keyword;
  67. public $order_type; //1认养商品
  68. public $goods_count_activity_new_user = [];
  69. public $pt_activity_id;
  70. public $pt_number;
  71. public $head_integral;
  72. public $store_list;
  73. public $saas_id;
  74. public $saas_user;
  75. public function rules()
  76. {
  77. $rules = [
  78. ['store_list', 'required'],
  79. ['address_id', 'integer'],
  80. ['verify_card_id', 'integer'],
  81. ['order_type', 'integer'],
  82. [['order_type',], 'default', 'value' => 0],
  83. ['store_list', function ($attr, $params) {
  84. if (!is_array($this->store_list)) {
  85. $data = Json::decode($this->store_list);
  86. if (!$data) {
  87. $this->addError($attr, "{$attr}数据格式错误。");
  88. }
  89. $this->store_list = $data;
  90. }
  91. }],
  92. ['store_list', function ($attr, $params) {
  93. foreach ($this->store_list as $i => &$store) {
  94. if (!is_array($store['goods_list'])) {
  95. $this->addError($attr, "{$attr}[{$i}]['goods_list']必须是一个数组。");
  96. return;
  97. }
  98. }
  99. }],
  100. [['longitude', 'latitude', '_from'], 'trim'],
  101. [['_from'], 'in', 'range' => ['app', 'mini']],
  102. [['pt_activity_id', 'pt_number'], 'integer']
  103. ];
  104. return $rules;
  105. }
  106. public function afterValidate()
  107. {
  108. //$this->user = User::findOne($this->user_id);
  109. $saas_user = get_saas_user();
  110. $this->user = User::findOne(['binding'=>$saas_user->mobile,'store_id'=>get_store_id(),'is_delete'=>0]);
  111. //$this->level = $this->getLevelData();
  112. $this->address = $this->getAddressData();
  113. $this->integral = [
  114. 'forehead' => 0,
  115. 'forehead_integral' => 0,
  116. 'integration' => Option::get(OptionSetting::STORE_INTEGRATION, get_store_id(), 'gift', Option::get(OptionSetting::STORE_INTEGRATION, get_store_id(), 'store')['value'])['value']
  117. ];
  118. parent::afterValidate();
  119. }
  120. /**
  121. * @throws \Exception
  122. */
  123. protected function getStoreListData($submit = false)
  124. {
  125. foreach ($this->store_list as $i => &$mch) {
  126. $mch['pt_number'] = $mch['pt_number'] ?? $this->pt_number;
  127. $mch['goods_list'] = $this->getGoodsList($this->store_list[0]['goods_list'], $submit);
  128. if (empty($mch['goods_list'])) {
  129. throw new \Exception($mch['goods_list']['msg'], 1);
  130. }
  131. if ($mch['goods_list']['code'] === 1) {
  132. throw new \Exception($mch['goods_list']['msg'], 1);
  133. }
  134. //拼团信息检测
  135. $pt_activity = PtActivity::findOne($this->pt_activity_id);
  136. if (!$pt_activity) {
  137. throw new \Exception("活动不存在或已结束");
  138. }
  139. if ($this->store_list[0]['store_id']) {
  140. $storeInfo = Store::find()->where(['id'=>$this->store_list[0]['store_id'],'is_delete'=>0])->asArray()->one();
  141. if(!$storeInfo){
  142. throw new \Exception('商城信息有误', 1);
  143. }
  144. } else {
  145. $storeInfo['name'] = '平台';
  146. }
  147. $mch['name'] = $storeInfo['name'];
  148. $this->head_integral = 0;
  149. if (!empty($mch['pt_number'])) {
  150. $pt_order = PtActivityOrder::findOne($mch['pt_number']);
  151. if ($pt_order) {
  152. if ((int)$pt_order->is_pay === 0) {
  153. throw new \Exception("当前团暂未开放");
  154. }
  155. //error
  156. $check_pt_order = PtActivityOrder::find()->where(['trade_status' => 0, 'is_pay' => 1])
  157. ->andWhere(['OR', ['id' => $mch['pt_number']], ['pt_number' => $mch['pt_number']]])
  158. ->select('id, is_winner, user_id')->asArray()->all();
  159. //判断是否到解散时间
  160. $end_time = (($pt_activity->split_time * 60 * 60) + ($pt_order->pay_time));
  161. if ($end_time <= time()) {
  162. throw new \Exception("当前团已解散");
  163. }
  164. //判断是否开奖
  165. $open = false;
  166. foreach ($check_pt_order as $item) {
  167. if ((int)$item['is_winner'] > 0) {
  168. $open = true;
  169. }
  170. if($pt_activity->party_type == 0){
  171. if ((int)$item['user_id'] === get_user_id()) {
  172. throw new \Exception("已加入,不可重复操作");
  173. }
  174. }
  175. }
  176. if ($open) {
  177. throw new \Exception("当前团已开奖");
  178. }
  179. if($pt_activity->party_type == 0){
  180. if ($pt_activity->party_size <= (count($check_pt_order))) {
  181. throw new \Exception("当前团已达上限");
  182. }
  183. }
  184. if($pt_activity->party_type == 1){
  185. $goodsCountQuery = PtActivityOrderDetail::find()->alias('pod')
  186. ->leftJoin(['po' => PtActivityOrder::tableName()], 'pod.order_id = po.id')
  187. ->where(['po.is_pay' => 1, 'pod.is_delete' => 0])
  188. ->andWhere(['OR' , ['po.id' => $mch['pt_number']], ['po.pt_number' => $mch['pt_number']]]);
  189. $goodsCount = $goodsCountQuery->sum('pod.num');
  190. if ($pt_activity->party_goods_count <= (int)$goodsCount) {
  191. throw new \Exception("当前团商品数量已达上限");
  192. }
  193. $buyCount = 0;
  194. foreach ($mch['goods_list'] as $_goods) {
  195. $buyCount += (int)$_goods['num'];
  196. if ($pt_activity->party_goods_count < ((int)$goodsCount + $buyCount)) {
  197. throw new \Exception("当前购买商品数量已超活动限制");
  198. }
  199. }
  200. }
  201. } else {
  202. //判断团长是否积分充足
  203. $head_integral = $pt_activity->head_integral;
  204. if ($head_integral > 0) {
  205. if ($head_integral > get_user()->integral) {
  206. throw new \Exception("开团积分不足");
  207. }
  208. $this->head_integral = $head_integral;
  209. }
  210. }
  211. } else {
  212. //判断团长是否积分充足
  213. $head_integral = $pt_activity->head_integral;
  214. if ($head_integral > 0) {
  215. if ($head_integral > get_user()->integral) {
  216. throw new \Exception("开团积分不足");
  217. }
  218. $this->head_integral = $head_integral;
  219. }
  220. }
  221. if($pt_activity->party_type == 1){
  222. $buyCount = 0;
  223. foreach ($mch['goods_list'] as $_goods) {
  224. $buyCount += (int)$_goods['num'];
  225. if ($pt_activity->party_goods_count < $buyCount) {
  226. throw new \Exception("当前购买商品数量已超活动限制" . $pt_activity->party_goods_count);
  227. }
  228. }
  229. } else {
  230. $buyCount = 0;
  231. foreach ($mch['goods_list'] as $_goods) {
  232. $buyCount += (int)$_goods['num'];
  233. if ($pt_activity->order_goods_limit < $buyCount) {
  234. throw new \Exception("当前购买商品数量已超活动限制" . $pt_activity->order_goods_limit);
  235. }
  236. }
  237. }
  238. // if ($submit == false) {
  239. // $mch['form'] = $this->getFormData();
  240. // } else {
  241. // $mch['form'] = $this->getForm($mch['form']);
  242. // }
  243. $send_type_arr = Order::getSendTypeArr($this->store_id, $submit, $mch['goods_list'], ['mini_id' => get_mini_id()]);
  244. $mch['send_type'] = $send_type_arr;
  245. if (in_array('shop', $send_type_arr)) {
  246. $shopArr = $this->getShopList();
  247. $mch['is_shop'] = $shopArr['shop'];
  248. $mch['shop_list'] = $shopArr['list'];
  249. } else {
  250. $mch['shop_list'] = [];
  251. $mch['is_shop'] = '';
  252. }
  253. $total_price = 0;
  254. $level_price = 0;
  255. $next_level_price = 0;
  256. $integral = [
  257. 'forehead' => 0,
  258. 'forehead_integral' => 0
  259. ];
  260. $mch['plugin_type'] = isset($mch['plugin_type']) ? $mch['plugin_type'] : 0;
  261. $open = false;
  262. foreach ($mch['goods_list'] as &$_goods) {
  263. if ($submit == false) {
  264. $_goods = array_merge($_goods, [
  265. 'form' => []
  266. ]);
  267. $_goods['form'] = $this->getNewFormData($_goods);
  268. } else {
  269. $_goods['form'] = $this->getForm($_goods['form']);
  270. }
  271. $total_price += doubleval($_goods['price']);
  272. if ((int)$_goods['product_type'] === 2) {
  273. $_goods['level_price'] = sprintf('%.2f', $mch['list']['price']);
  274. $_goods['price'] = $mch['list']['price'];
  275. }
  276. $level_price += doubleval($_goods['level_price']) > 0 ? doubleval($_goods['level_price']) : doubleval($_goods['price']);
  277. $_goods['integral'] = [
  278. 'forehead' => 0,
  279. 'forehead_integral' => 0
  280. ];
  281. $integral['forehead'] = 0;
  282. $integral['forehead_integral'] = 0;
  283. unset($_goods['is_form']);
  284. unset($_goods['form_name']);
  285. }
  286. // $integral['forehead'] = round($integral['forehead'], 2);
  287. $mch['total_price'] = sprintf('%.2f', $total_price);
  288. $mch['level_price'] = sprintf('%.2f', $level_price);
  289. $mch['diy_send_type'] = [
  290. [
  291. 'key' => 'express',
  292. 'name' => Option::get(OptionSetting::DIY_EXPRESS_NAME, get_store_id(), 'pay', Option::get(OptionSetting::DIY_EXPRESS_NAME, get_store_id(), 'store', '快递配送')['value'] ?: '快递配送')['value']
  293. ],
  294. [
  295. 'key' => 'shop',
  296. 'name' => Option::get(OptionSetting::DIY_SHOP_NAME, get_store_id(), 'pay', Option::get(OptionSetting::DIY_SHOP_NAME, get_store_id(), 'store', '自提配送')['value'] ?: '自提配送')['value']
  297. ],
  298. [
  299. 'key' => 'delivery',
  300. 'name' => Option::get(OptionSetting::DIY_DELIVERY_NAME, get_store_id(), 'pay', Option::get(OptionSetting::DIY_DELIVERY_NAME, get_store_id(), 'store', '同城配送')['value'] ?: '同城配送')['value']
  301. ]
  302. ];
  303. $mch['integral'] = [
  304. "forehead" => 0,
  305. "forehead_integral" => 0
  306. ];
  307. $mch['coupon_list'] = [];
  308. $mch['express_price'] = $this->getExpressPrice($mch);
  309. $mch['offer_rule'] = null;
  310. $mch['is_area'] = 0;
  311. }
  312. return $this->store_list;
  313. }
  314. protected function getGoodsList($goods_list)
  315. {
  316. $goodsIds = [];
  317. // $cards = [];
  318. foreach ($goods_list as $i => &$item) {
  319. $food_ext_goods = [];
  320. if ($item['goods_id']) {
  321. $attr_id_list = [];
  322. foreach ($item['attr'] as $_a) {
  323. array_push($attr_id_list, $_a['attr_id']);
  324. }
  325. $goods = Goods::findOne([
  326. 'id' => $item['goods_id'],
  327. ]);
  328. } else {
  329. unset($goods_list[$i]);
  330. continue;
  331. }
  332. if (!$goods) {
  333. unset($goods_list[$i]);
  334. continue;
  335. }
  336. foreach ($attr_id_list as $index => $value) {
  337. if ($value < 0) {
  338. unset($attr_id_list[$index]);
  339. }
  340. }
  341. $cat_id_arr = GoodsCat::find()->where(['goods_id' => $goods->id, 'is_delete' => 0])->select('cat_id')->column();
  342. $shop_count = Cat::find()->where(['id' => $cat_id_arr])->andWhere(['>', 'shop_count', 0])->select('shop_count')->min('shop_count') ?: 0;
  343. if ($shop_count > 0 && $shop_count > $item['num']) {
  344. return [
  345. 'code' => 1,
  346. 'msg' => $goods->name . "起购数量为" . $shop_count,
  347. ];
  348. }
  349. $attr = json_decode($goods->attr, true);
  350. $attr_info = $goods->getAttrInfo($attr_id_list);
  351. //获取拼团价格
  352. $pt_activity_goods = PtActivityGoods::find()->alias('pag')->where(['pag.goods_id' => $goods->id])
  353. ->leftJoin(['pa' => PtActivity::tableName()], 'pag.activity_id = pa.id')
  354. ->andWhere(['AND', ['pa.is_delete' => 0], ['>', 'pa.end_time', time()], ['<', 'start_time', time()], ['pag.is_delete' => 0]])
  355. ->select('pa.id, pa.party_size, pa.party_type, pa.party_goods_count, pa.join_num, pa.start_time, pa.end_time, pag.attr, pag.pt_price, pag.use_attr, pag.sale_num, pag.virtual_sales, pag.activity_id, pa.store_id')->asArray()->one();
  356. if ($pt_activity_goods) {
  357. $this->store_id = $pt_activity_goods['store_id'];
  358. $pt_goods_attr = json_decode($pt_activity_goods['attr'], true);
  359. foreach ($pt_goods_attr as $pt_attr) {
  360. $pt_attr_id = array_column($pt_attr['attr_list'], 'attr_id');
  361. sort($pt_attr_id);
  362. sort($attr_id_list);
  363. if (empty(array_diff($pt_attr_id, $attr_id_list))) {
  364. $attr_info['price'] = $pt_attr['pt_price'];
  365. $goods->price = $pt_activity_goods['pt_price'] = $pt_attr['pt_price'];
  366. }
  367. foreach ($attr as &$g_attr) {
  368. $g_attr_id = array_column($g_attr['attr_list'], 'attr_id');
  369. sort($g_attr_id);
  370. if (empty(array_diff($pt_attr_id, $g_attr_id))) {
  371. $g_attr['price'] = $pt_attr['pt_price'];
  372. }
  373. }
  374. }
  375. $attr = json_encode($attr);
  376. $this->pt_activity_id = $pt_activity_goods['activity_id'];
  377. $join_num = $pt_activity_goods['join_num'];
  378. if($pt_activity_goods['party_type'] == 0){
  379. $user_id = 0;
  380. $saas_user = get_saas_user();
  381. $user = User::findOne(['binding' => $saas_user->mobile, 'is_delete' => 0, 'store_id' => $pt_activity_goods['store_id']]);
  382. if ($user) {
  383. $user_id = $user->id;
  384. }
  385. $s_today_time = strtotime(date('Y-m-d'));
  386. $e_today_time = (strtotime(date('Y-m-d')) + 3600 * 24);
  387. $join_count = PtActivityOrderDetail::find()->alias('od')
  388. ->leftJoin(['o' => PtActivityOrder::tableName()], 'od.order_id = o.id')
  389. ->where(['od.goods_id' => $goods->id, 'o.user_id' => $user_id, 'is_pay' => 1])
  390. ->andWhere(['AND', ['>', 'od.created_at', $s_today_time], ['<', 'od.created_at', $e_today_time]])->select('od.id')->count();
  391. if ($join_num > 0 && $join_count >= $join_num) {
  392. return [
  393. 'code' => 1,
  394. 'msg' => "今日参加此商品的拼团次数已达上限"
  395. ];
  396. }
  397. }
  398. } else {
  399. return [
  400. 'code' => 1,
  401. 'msg' => "拼团活动不存在"
  402. ];
  403. }
  404. $attr_list = Attr::find()->alias('a')
  405. ->select('ag.id AS attr_group_id,ag.attr_group_name,a.id AS attr_id,a.attr_name')
  406. ->leftJoin(['ag' => AttrGroup::tableName()], 'a.attr_group_id=ag.id')
  407. ->where(['a.id' => $attr_id_list, 'ag.store_id' => $this->store_id])->asArray()->all();
  408. $item['user_id'] = !empty($user_id) ? $user_id : 0;
  409. $item['attr_list'] = $attr_list;
  410. $item['goods_id'] = $goods->id;
  411. $item['mch_id'] = $goods->mch_id;
  412. $item['rate'] = $goods->rate;
  413. $item['rate_type'] = $goods->rate_type;
  414. $item['goods_name'] = $goods->name;
  415. $item['goods_pic'] = $attr_info['pic'] ? $attr_info['pic'] : $goods->cover_pic;
  416. //如果没有使用规格,则使用商品售价 否则使用规格售价
  417. $item['price'] = sprintf('%.2f', (($goods->use_attr ? $attr_info['price'] : $goods->price) * $item['num']));
  418. $item['single_price'] = sprintf('%.2f', $attr_info['price']);
  419. $item['weight'] = $goods->weight;
  420. $item['integral'] = 0;
  421. $item['integral'] = $goods->integral ? $goods->integral : 0;
  422. $item['freight'] = 0;
  423. $item['full_cut'] = "";
  424. $item['goods_cat_id'] = $goods->cat_id;
  425. $item['id'] = $goods->id;
  426. $item['verify_card_id'] = 0;
  427. $item['type'] = $goods->type;
  428. $item['delivery_type'] = Json::decode($goods->delivery_type);
  429. // 当前选择的规格
  430. $attrIdArr = [];
  431. foreach ($item['attr_list'] as $attrListItem) {
  432. $attrIdArr[] = $attrListItem['attr_id'];
  433. }
  434. // $GoodsFullMinus = GoodsFullMinus::find()
  435. // ->select('*')
  436. // ->where(['store_id' => get_store_id(), 'goods_id' => $goods->id, 'is_delete' => 0])
  437. // ->orderBy('full_minus_num ASC')->asArray()->all();
  438. // 门店逻辑
  439. $price = $goods->price;
  440. if ($pt_activity_goods) {
  441. $price = $pt_activity_goods['pt_price'];
  442. }
  443. // var_dump($price);die;
  444. // if (get_md_id() && empty(input_params('flag_id'))) {
  445. // $md_goods = MdGoods::findOne(['goods_id' => $goods->id, 'md_id' => get_md_id()]);
  446. // if ($md_goods) {
  447. // $attr = $md_goods->attr;
  448. // $price = $md_goods->price;
  449. // }
  450. // }
  451. $res = \app\modules\client\models\v1\common\CommonGoods::currentGoodsAttr([
  452. 'attr' => $attr,
  453. 'price' => $price,
  454. 'is_level' => 0,
  455. 'mch_id' => $goods->mch_id,
  456. 'unit' => $goods->unit,
  457. 'use_attr' => $goods->use_attr,
  458. 'food_ext_goods' => $food_ext_goods,
  459. ], $attrIdArr, [], $item['num']);
  460. $item['batch_price_tips'] = $res['batch_price_tips'];
  461. $item['current_batch_price_tips'] = $res['current_batch_price_tips'];
  462. $item['price'] = sprintf('%.2f', ($res['price'] * $item['num']));
  463. $item['level_price'] = sprintf('%.2f', ($res['level_price'] * $item['num']));
  464. $item['next_level_price'] = sprintf('%.2f', ($res['next_level_price'] * $item['num']));
  465. $item['is_level'] = $res['is_level'];
  466. $item['give'] = 0;
  467. $item['resIntegral'] = 0;
  468. $goodsIds[] = $goods->id;
  469. $item['goods_card_list'] = null;
  470. $item['is_form'] = $goods->is_form;
  471. $item['form_name'] = $goods->form_name;
  472. $item['product_type'] = $goods->product_type;
  473. // $res_acnu = $this->getActivityNewUserGoodsPrice($res, $goods, $attr_id_list, $submit, $item['num']);
  474. // if ($res_acnu['code'] === 0) {
  475. // $item['is_level'] = 0;
  476. // if ($res_acnu['price'] > 0) {
  477. // $item['price'] = $item['level_price'] = sprintf('%.2f', ($res_acnu['price']));
  478. // $item['price_str'] = $res_acnu['price_str'];
  479. // }
  480. // } else {
  481. // return $res_acnu;
  482. // }
  483. // $res = $this->getSceKillGoodsPrice($goods, $attr_id_list, $submit, $item['num']);
  484. // if ($res['code'] === 0) {
  485. // $item['is_level'] = 0;
  486. // if ($res['data'] > 0) {
  487. // $item['price'] = $item['level_price'] = sprintf('%.2f', ($res['data'] * $item['num']));
  488. // }
  489. // } else {
  490. // return $res;
  491. // }
  492. // if ($goods->product_type == Goods::GOODS_TYPE_ADOPT) {
  493. // $adopt_goods = AdoptGoods::find()->where(['goods_id' => $goods->id,'is_delete' => 0])->one();
  494. // $item['desc'] = $adopt_goods->desc;
  495. // }
  496. }
  497. // 和空数组合并重建索引,避免出现因索引key间断导致客户端显示问题
  498. return array_merge($goods_list, []);
  499. }
  500. //新人专享商品处理
  501. // public function getActivityNewUserGoodsPrice($res, $goods, $attr, $submit, $num)
  502. // {
  503. // try {
  504. // $price = 0;
  505. // $price_str = [];
  506. // $activity = ActivityNewUser::activityAt($goods->store_id);
  507. // if($activity){
  508. // $goods_ext = ActivityNewUserGoods::findOne(['activity_id' => $activity->id, 'goods_id' => $goods->id, 'is_delete' => 0]);
  509. // if($goods_ext){
  510. // $ext_attrs = json_decode($goods_ext['attr'], true);
  511. // foreach ($ext_attrs as $ext_attr) {
  512. // $ext_attr_id = array_column($ext_attr['attr_list'], 'attr_id');
  513. // //与购物车添加的规格id数组比较
  514. // if (empty(array_diff($ext_attr_id, $attr))) {
  515. // $ext_price = $ext_attr['price'];
  516. // $id = $goods_ext['id'];
  517. // }
  518. // }
  519. // $buy_limit = $activity->buy_limit;
  520. // if (($buy_limit && $buy_limit > 0)) {
  521. // //部分享受优惠
  522. // $goodsNum = intval(Goods::getBuyNum($this->user, $goods->id));
  523. // $goodsNum = 0;
  524. // for($i=$goodsNum+$this->goods_count_activity_new_user[$goods->id]; $i<$num; $i++){
  525. // if($i < $buy_limit){
  526. // $price += $ext_price;
  527. // $price_str[] = '新人专享¥' . sprintf('%.2f', $ext_price);
  528. // $this->goods_count_activity_new_user[$goods->id]++;
  529. // }else{
  530. // $price += sprintf('%.2f', $res['level_price']);
  531. // $price_str[] = sprintf('%.2f', $res['level_price']);
  532. // }
  533. // }
  534. // }else{
  535. // //全部享受优惠
  536. // $price = $ext_price * $num;
  537. // $price_str[] = '新人专享¥' . sprintf('%.2f', $ext_price) . '×' . $num;
  538. // }
  539. // }
  540. // }
  541. // return [
  542. // 'code' => 0,
  543. // 'msg' => '获取成功',
  544. // 'price' => $price,
  545. // 'price_str' => implode('+', $price_str),
  546. // 'id' => $id
  547. // ];
  548. // } catch (\Exception $e) {
  549. // return [
  550. // 'code' => 1,
  551. // 'msg' => $e->getMessage()
  552. // ];
  553. // }
  554. // }
  555. //自定义表单
  556. protected function getFormData()
  557. {
  558. $new_list = [];
  559. $new_list['is_form'] = Option::get('is_form', $this->store_id, 'store', 0)['value'];
  560. $form_list = [];
  561. if ($new_list['is_form'] == 1) {
  562. $new_list['name'] = Option::get('form_name', $this->store_id, 'store', '表单信息')['value'];
  563. $form_list = Form::find()->where([
  564. 'store_id' => $this->store_id, 'is_delete' => 0,
  565. ])->orderBy(['sort' => SORT_ASC])->asArray()->all();
  566. foreach ($form_list as $index => $value) {
  567. if (in_array($value['type'], ['radio', 'checkbox'])) {
  568. $default = str_replace(",", ",", $value['default']);
  569. $list = explode(',', $default);
  570. $default_list = [];
  571. foreach ($list as $k => $v) {
  572. $default_list[$k]['name'] = $v;
  573. if ($k == 0) {
  574. if ($value['type'] == 'radio') {
  575. $form_list[$index]['default'] = $v;
  576. } else {
  577. $form_list[$index]['default'] = [$v];
  578. }
  579. $default_list[$k]['checked'] = true;
  580. } else {
  581. $default_list[$k]['checked'] = false;
  582. }
  583. }
  584. $form_list[$index]['default_list'] = $default_list;
  585. }
  586. }
  587. }
  588. $new_list['list'] = $form_list;
  589. return $new_list;
  590. }
  591. //自定义表单
  592. protected function getNewFormData($goods)
  593. {
  594. $new_list = [];
  595. $new_list['is_form'] = $goods['is_form'];
  596. $form_list = [];
  597. if ($new_list['is_form'] == 1) {
  598. $new_list['name'] = $goods['form_name'];
  599. $form_list = Form::find()->where([
  600. 'store_id' => $this->store_id, 'is_delete' => 0, 'goods_id' => $goods['id']
  601. ])->orderBy(['sort' => SORT_ASC])->asArray()->all();
  602. foreach ($form_list as $index => $value) {
  603. if (in_array($value['type'], ['radio', 'checkbox'])) {
  604. $default = str_replace(",", ",", $value['default']);
  605. $list = explode(',', $default);
  606. $default_list = [];
  607. foreach ($list as $k => $v) {
  608. $default_list[$k]['name'] = $v;
  609. if ($k == 0) {
  610. if ($value['type'] == 'radio') {
  611. $form_list[$index]['default'] = $v;
  612. } else {
  613. $form_list[$index]['default'] = [$v];
  614. }
  615. $default_list[$k]['checked'] = true;
  616. } else {
  617. $default_list[$k]['checked'] = false;
  618. }
  619. }
  620. $form_list[$index]['default_list'] = $default_list;
  621. }
  622. }
  623. }
  624. $new_list['list'] = $form_list;
  625. return $new_list;
  626. }
  627. protected function getAddress()
  628. {
  629. if (!$this->address) {
  630. if ($this->address_id) {
  631. $this->address = Address::findOne(['id' => $this->address_id, 'user_id' => get_saas_user_id(), 'is_delete' => 0]);
  632. } else {
  633. $this->address = Address::find()->where([
  634. 'user_id' => get_saas_user_id(),
  635. 'is_default' => 1,
  636. 'is_delete' => 0,
  637. ])->limit(1)->one();
  638. }
  639. }
  640. return (object)$this->address;
  641. }
  642. //获取收货地址,有address_id优先获取,没有则获取默认地址
  643. protected function getAddressData()
  644. {
  645. $address = $this->getAddress();
  646. if (isset($address->id)) {
  647. return [
  648. 'id' => $address->id,
  649. 'name' => $address->name,
  650. 'mobile' => $address->mobile,
  651. 'province_id' => $address->province_id,
  652. 'province' => $address->province,
  653. 'city_id' => $address->city_id,
  654. 'city' => $address->city,
  655. 'district_id' => $address->district_id,
  656. 'district' => $address->district,
  657. 'detail' => $address->detail,
  658. 'is_default' => $address->is_default,
  659. 'latitude' => $address->latitude,
  660. 'longitude' => $address->longitude,
  661. ];
  662. } else {
  663. return null;
  664. }
  665. }
  666. //获取支付方式
  667. public function getPayTypeList()
  668. {
  669. $pay_type_list_json = Option::get(OptionSetting::STORE_PAYMENT, get_store_id(), 'pay', Option::get(OptionSetting::STORE_PAYMENT, get_store_id(), 'store', '{"wechat":{"value":1}}')['value']);
  670. $pay_type_list = Json::decode($pay_type_list_json['value']);
  671. $new_list = [];
  672. if (is_wechat_platform() || $this->_from == 'app') {
  673. $new_list[] = [
  674. 'name' => '微信支付',
  675. 'payment' => 1,
  676. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/v1/statics/images/recharge/icon-online.png'
  677. ];
  678. }
  679. if (is_alipay_platform() || $this->_from == 'app') {
  680. $new_list[] = [
  681. 'name' => '支付宝支付',
  682. 'payment' => 4,
  683. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/v1/statics/images/recharge/icon-alipay.png'
  684. ];
  685. }
  686. //如果是微信且商城已配置通联支付进件数据
  687. if (is_wechat_platform()) {
  688. $store = Store::findOne(get_store_id());
  689. if (!empty($store->cusid)) {
  690. $new_list[] = [
  691. 'name' => '通联支付',
  692. 'payment' => Order::PAY_TYPE_YUNST_WECHAT_PAY,
  693. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/v1/statics/images/recharge/icon-online.png'
  694. ];
  695. }
  696. }
  697. if (is_toutiao_platform()) {
  698. $new_list[] = [
  699. 'name' => '线上支付',
  700. 'payment' => 5,
  701. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/v1/statics/images/recharge/icon-online.png'
  702. ];
  703. }
  704. foreach ($new_list as $index => $item) {
  705. foreach ($pay_type_list as $pay_type_index => $pay_type_item) {
  706. if ($item['payment'] === 1 && $pay_type_index === 'wechat') {
  707. if (intval($pay_type_item['value']) === 0) {
  708. unset($new_list[$index]);
  709. }
  710. }
  711. if ($item['payment'] === 4 && $pay_type_index === 'alipay') {
  712. if (intval($pay_type_item['value']) === 0) {
  713. unset($new_list[$index]);
  714. }
  715. }
  716. }
  717. }
  718. return array_values($new_list);
  719. }
  720. /**
  721. * 支付方式
  722. * @param array $is_payment //支付方式
  723. * @param array $ignore //忽略的支付方式
  724. * @return array
  725. */
  726. public static function getPayType($is_payment = array(), $ignore = array())
  727. {
  728. if (!$is_payment || empty($is_payment)) {
  729. $default = '{"wechat":{"value":1}}';
  730. if (is_alipay_platform()) {
  731. $default = '{"alipay":{"value":1}}';
  732. }
  733. if (is_toutiao_platform()) {
  734. $default = '{"toutiao":{"value":1}}';
  735. }
  736. $pay_str = Option::get(OptionSetting::STORE_PAYMENT, get_store_id(), 'pay', Option::get(OptionSetting::STORE_PAYMENT, get_store_id(), 'store', $default)['value']);
  737. $is_payment = Json::decode($pay_str['value']);
  738. }
  739. $pay_type_list = [];
  740. foreach ($is_payment as $index => $value) {
  741. if (in_array($index, $ignore)) {
  742. continue;
  743. }
  744. if ($index == 'wechat' && $value['value'] == 1 && is_wechat_platform()) {
  745. $pay_type_list[] = [
  746. 'name' => '微信支付',
  747. 'payment' => 1,
  748. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/v1/statics/wxapp/images/icon-payment-online.png'
  749. ];
  750. }
  751. if ($index == 'toutiao' && $value['value'] == 1 && is_toutiao_platform()) {
  752. $pay_type_list[] = [
  753. 'name' => '线上支付',
  754. 'payment' => 5,
  755. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/v1/statics/wxapp/images/icon-payment-online.png'
  756. ];
  757. }
  758. // if ($index == 'huodao' && $value['value'] == 1) {
  759. // $pay_type_list[] = [
  760. // 'name' => '货到付款',
  761. // 'payment' => 2,
  762. // 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/v1/statics/wxapp/images/icon-payment-huodao.png'
  763. // ];
  764. // }
  765. if (get_params('_from') == OrderPayDataForm::PAY_FROM_APP || is_alipay_platform()) {
  766. if ($index == 'alipay' && $value['value'] == 1) {
  767. $pay_type_list[] = [
  768. 'name' => '支付宝支付',
  769. 'payment' => 4,
  770. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/statics/images/recharge/icon-alipay.png'
  771. ];
  772. }
  773. }
  774. if ($index == 'balance' && $value['value'] == 1) {
  775. $pay_type_list[] = [
  776. 'name' => '账户余额支付',
  777. 'payment' => 3,
  778. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/v1/statics/wxapp/images/icon-payment-balance.png'
  779. ];
  780. }
  781. }
  782. if (!$pay_type_list) {
  783. if (is_wechat_platform()) {
  784. $pay_type_list[] = [
  785. 'name' => '微信支付',
  786. 'payment' => 1,
  787. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/v1/statics/images/recharge/icon-online.png'
  788. ];
  789. }
  790. if (is_toutiao_platform()) {
  791. $pay_type_list[] = [
  792. 'name' => '线上支付',
  793. 'payment' => 5,
  794. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/v1/statics/images/recharge/icon-online.png'
  795. ];
  796. }
  797. }
  798. return $pay_type_list;
  799. }
  800. protected function getLevelData()
  801. {
  802. $level = Level::find()->select([
  803. 'name', 'level', 'discount',
  804. ])->where(['level' => $this->user->level, 'store_id' => $this->store_id, 'is_delete' => 0])
  805. ->asArray()->one();
  806. return $level;
  807. }
  808. //积分计算
  809. protected function getExpressPrice($mch)
  810. {
  811. $expressPrice = 0;
  812. if ($this->address) {
  813. $address = $this->address;
  814. //先计算单品满件包邮和满额包邮
  815. $resGoodsList = Goods::cutFull($mch['goods_list']);
  816. //再通过运费规则计算运费
  817. $expressPrice = PostageRules::getExpressPriceMore($this->store_id, $address['city_id'], $resGoodsList, $address['province_id']);
  818. }
  819. $expressPrice = $this->getFreeDeliveryRules($mch, $expressPrice);
  820. return $expressPrice >= 0 ? $expressPrice : 0;
  821. }
  822. // 获取门店列表
  823. protected function getShopList()
  824. {
  825. $start = 0;
  826. $shop_table_name = Shop::tableName();
  827. $latitude = 0;
  828. $longitude = 0;
  829. if ($this->address && isset($this->address['id'])) {
  830. $address = Address::findOne($this->address['id']);
  831. if ($address) {
  832. $latitude = $address->latitude ? $address->latitude : 0;
  833. $longitude = $address->longitude ? $address->longitude : 0;
  834. }
  835. }
  836. $sql = "SELECT *, acos(cos({$latitude}*pi()/180 )*cos(latitude*pi()/180)*cos({$longitude}*pi()/180 -longitude*pi()/180)+sin({$latitude}*pi()/180 )*sin(latitude*pi()/180))*6370996.81 as
  837. distance FROM {$shop_table_name} WHERE ((`store_id`={$this->store_id}) AND (`is_delete`=0)) ";
  838. if ($this->keyword) {
  839. $sql .= " AND (`name` like '%{$this->keyword}%') ";
  840. }
  841. $sql .= "ORDER BY `distance` LIMIT {$start},30";
  842. $list = \Yii::$app->db->createCommand($sql)->queryAll();
  843. $shop = null;
  844. foreach ($list as $index => $item) {
  845. if ($item['is_default'] == 1) {
  846. $shop = $item;
  847. }
  848. $list[$index]['distance'] = round($item['distance']/1000, 2).'km';
  849. }
  850. return [
  851. 'list' => $list,
  852. 'shop' => $shop
  853. ];
  854. }
  855. protected function getTerritorialLimitation($mch)
  856. {
  857. $isArea = 0;
  858. if ($mch['mch_id'] > 0) {
  859. return $isArea;
  860. }
  861. if ($this->address) {
  862. $area = TerritorialLimitation::findOne([
  863. 'store_id' => $this->store_id,
  864. 'is_delete' => 0,
  865. 'is_enable' => 1,
  866. ]);
  867. if ($area) {
  868. $city_id = []; //限制的地区ID
  869. $detail = json_decode($area->detail);
  870. if (!is_array($detail)) {
  871. $detail = [];
  872. }
  873. foreach ($detail as $key => $value) {
  874. foreach ($value->province_list as $key2 => $value2) {
  875. $city_id[] = $value2->id;
  876. }
  877. }
  878. $addressArr = [
  879. $this->address['province_id'],
  880. $this->address['city_id'],
  881. $this->address['district_id']
  882. ];
  883. $addressArray = array_intersect($addressArr, $city_id);
  884. if (empty($addressArray)) {
  885. $isArea = 1;
  886. }
  887. }
  888. }
  889. return $isArea;
  890. }
  891. // 包邮规则
  892. protected function getFreeDeliveryRules($mch, $expressPrice)
  893. {
  894. if ($expressPrice == 0) {
  895. return $expressPrice;
  896. }
  897. if ($mch['mch_id'] == 0) {
  898. $free = FreeDeliveryRules::find()->where(['store_id' => $this->store_id, 'is_delete' => 0, 'mch_id' => 0])->asArray()->all();
  899. foreach ($free as $k => $v) {
  900. $city = json_decode($v['city'], true);
  901. foreach ($city as $v1) {
  902. if ($this->address['district_id'] == $v1['id'] && $mch['total_price'] >= $v['price']) {
  903. $expressPrice = 0;
  904. break;
  905. }
  906. }
  907. }
  908. } else {
  909. $free = FreeDeliveryRules::find()->where(['store_id' => $this->store_id, 'mch_id' => $mch['mch_id'], 'is_delete' => 0])->asArray()->all();
  910. foreach ($free as $k => $v) {
  911. $city = json_decode($v['city'], true);
  912. foreach ($city as $v1) {
  913. if ($this->address['district_id'] == $v1['id'] && $mch['total_price'] >= $v['price']) {
  914. $expressPrice = 0;
  915. break;
  916. }
  917. }
  918. }
  919. }
  920. return $expressPrice;
  921. }
  922. // 获取用户填写的自定义表单
  923. protected function getForm(&$form)
  924. {
  925. if ($form['is_form'] == 1) {
  926. $formList = &$form['list'];
  927. foreach ($formList as $index => $value) {
  928. if ($value['required'] == 1) {
  929. if (in_array($value['type'], ['radio', 'checkbox'])) {
  930. $is_true = false;
  931. foreach ($value['default_list'] as $k => $v) {
  932. if ($v['checked'] == true) {
  933. $is_true = true;
  934. }
  935. }
  936. if (!$is_true) {
  937. return [
  938. 'code' => 1,
  939. 'msg' => '请填写' . $form['name'] . ',加“*”为必填项',
  940. 'name' => $value['name']
  941. ];
  942. }
  943. } else {
  944. if (empty($value['default']) && strlen($value['default']) == 0) {
  945. return [
  946. 'code' => 1,
  947. 'msg' => '请填写' . $form['name'] . ',加“*”为必填项',
  948. 'name' => $value['name']
  949. ];
  950. }
  951. }
  952. }
  953. if ($value['type'] == 'checkbox') {
  954. $formList[$index]['default'] = is_array($value['default']) ? implode(',', $value['default']) : $value['default'];
  955. }
  956. }
  957. }
  958. return $form;
  959. }
  960. protected function goodsCardList()
  961. {
  962. $list = [];
  963. foreach ($this->mch_list as $mch) {
  964. if($mch['mch_id'] == 0) {
  965. foreach ($mch['goods_list'] as $goods) {
  966. if (!empty($goods['goods_list'])) {
  967. foreach ($goods['goods_list'] as $val) {
  968. if(!$val['goods_card_list']) {
  969. $val['goods_card_list'] = [];
  970. }
  971. $list = array_merge($list, $val['goods_card_list']);
  972. }
  973. }
  974. }
  975. }
  976. }
  977. return $list;
  978. }
  979. /**
  980. * @param $goods
  981. * @param $type
  982. */
  983. public function bookCheckGoodsNum($goods, $type) {
  984. // 酒店预约
  985. if ($type == 1) {
  986. // $date_book = GoodsBook::findOne(['goods_id' => $goods['id']])->date_book;
  987. // $date_book = Json::decode($date_book);
  988. // if (!$date_book) {
  989. // return [
  990. // 'code' => 1,
  991. // 'msg' => '数据异常'
  992. // ];
  993. // }
  994. // $data_config = array_combine(array_column($date_book, 'date'), array_column($date_book, 'num'));
  995. //
  996. // foreach ($goods['book'] as $value) {
  997. // if ($data_config[$value['date']] < $goods['num']) {
  998. // return [
  999. // 'code' => 1,
  1000. // 'msg' => '选中日期' . $value['date'] . '内暂无房源'
  1001. // ];
  1002. // }
  1003. // }
  1004. }
  1005. // 服务预约
  1006. if ($type == 2) {
  1007. $service_book = GoodsBook::findOne(['goods_id' => $goods['id']])->service_book;
  1008. $service_book = Json::decode($service_book);
  1009. if (!$service_book) {
  1010. return [
  1011. 'code' => 1,
  1012. 'msg' => '数据异常'
  1013. ];
  1014. }
  1015. $date_data = $this->getDateByInterval(7);
  1016. $count = 0;
  1017. $new_arr = [
  1018. 'data' => []
  1019. ];
  1020. $order = Order::find()->alias('o')
  1021. ->leftJoin(['od' => OrderDetail::tableName()], 'o.id = od.order_id')
  1022. ->where(['o.trade_status' => [0, 2, 3], 'o.is_delete' => 0, 'o.order_type' => 2, 'goods_id' => $goods['id']])
  1023. ->andWhere(['>', 'o.created_at', strtotime(date("Y-m-d"))])
  1024. ->select('od.attr, od.num')->asArray()->all();
  1025. foreach ($date_data as $index => $datum) {
  1026. $new_arr['data'][$index]['date'] = $datum;
  1027. $new_arr['data'][$index]['time'] = $service_book['data'][0]['time'];
  1028. }
  1029. if (!$new_arr) {
  1030. return [
  1031. 'code' => 1,
  1032. 'msg' => '数据异常'
  1033. ];
  1034. }
  1035. $service_book = $new_arr['data'];
  1036. $service_book_date = array_column($service_book, NULL, 'date');
  1037. $service_book_time = $service_book_date[$goods['service']['date']]['time'];
  1038. $num = 0;
  1039. $price = 0;
  1040. foreach ($order as $item) {
  1041. $item['attr'] = json_decode($item['attr'], true);
  1042. if ($item['attr']['date'] === $goods['service']['date']) {
  1043. if ($goods['service']['time'] === $item['attr']['time']) {
  1044. $num += $item['num'];
  1045. }
  1046. }
  1047. }
  1048. foreach ($service_book_time as $m) {
  1049. foreach ($m['times'] as $n) {
  1050. if ($n['time'] == $goods['service']['time']) {
  1051. if (($goods['num'] + $num) > $n['num']) {
  1052. return [
  1053. 'code' => 1,
  1054. 'msg' => $n['time'] . '时间段内暂不可预约'
  1055. ];
  1056. }
  1057. }
  1058. }
  1059. }
  1060. }
  1061. return [
  1062. 'code' => 0,
  1063. 'msg' => 'success',
  1064. 'data' => [
  1065. 'price' => $price
  1066. ]
  1067. ];
  1068. }
  1069. /**
  1070. * 计算初始价格
  1071. * @param $order_id
  1072. * @return array
  1073. */
  1074. public static function findPrice($order_id) {
  1075. $order_detail = OrderDetail::findAll(['order_id' => $order_id]);
  1076. $original_price = 0;
  1077. $md_price = 0;
  1078. foreach ($order_detail as $detail) {
  1079. $goods = Goods::findOne($detail['goods_id']);
  1080. if ($goods->use_attr > 0) {
  1081. $attrs = Json::decode($goods->attr);
  1082. // 当前选择的规格
  1083. $attrIdArr = [];
  1084. foreach (Json::decode($detail['attr']) as $attrListItem) {
  1085. $attrIdArr[] = $attrListItem['attr_id'];
  1086. }
  1087. foreach ($attrs as $attr) {
  1088. $attrIds = [];
  1089. foreach ($attr['attr_list'] as $item) {
  1090. $attrIds[] = $item['attr_id'];
  1091. }
  1092. sort($attrIds);
  1093. sort($attrIdArr);
  1094. // 找出当前规格信息
  1095. if (implode($attrIds) === implode($attrIdArr)) {
  1096. $original_price += $attr['price'];
  1097. }
  1098. }
  1099. } else {
  1100. $original_price += $goods->price;
  1101. }
  1102. }
  1103. foreach ($order_detail as $detail) {
  1104. $md_goods = MdGoods::findOne(['goods_id' => $detail['goods_id'], 'md_id' => get_md_id()]);
  1105. $goods = Goods::findOne($detail['goods_id']);
  1106. $goods_attr = $goods->attr;
  1107. if ($md_goods) {
  1108. $goods_attr = $md_goods->attr;
  1109. }
  1110. if ($goods->use_attr == 1) {
  1111. $attrs = Json::decode($goods_attr);
  1112. // 当前选择的规格
  1113. $attrIdArr = [];
  1114. foreach (Json::decode($detail['attr']) as $attrListItem) {
  1115. $attrIdArr[] = $attrListItem['attr_id'];
  1116. }
  1117. foreach ($attrs as $attr) {
  1118. $attrIds = [];
  1119. foreach ($attr['attr_list'] as $item) {
  1120. $attrIds[] = $item['attr_id'];
  1121. }
  1122. sort($attrIds);
  1123. sort($attrIdArr);
  1124. // 找出当前规格信息
  1125. if (implode($attrIds) === implode($attrIdArr)) {
  1126. $md_price += $attr['price'];
  1127. }
  1128. }
  1129. } else {
  1130. if ($md_goods) {
  1131. $md_price += $md_goods->price;
  1132. } else {
  1133. $md_price += $goods->price;
  1134. }
  1135. }
  1136. }
  1137. return [
  1138. 'original_price' => $original_price > 0 ? $original_price : $md_price,
  1139. 'md_price' => $md_price
  1140. ];
  1141. }
  1142. public function getDateByInterval(int $num) :array
  1143. {
  1144. //var_dump($st, $et);die;
  1145. $returnData = [];
  1146. $i = 0;
  1147. do {
  1148. $temp = date('Y-m-d', strtotime('+' . $i . ' day', strtotime(date('Y-m-d'))));
  1149. $returnData[] = $temp;
  1150. $i++;
  1151. } while ($i < $num);
  1152. return $returnData;
  1153. }
  1154. //判断是否需为代理配送且要上门安装
  1155. public function goodsIsInstall($goods_id) {
  1156. try {
  1157. $goods = Goods::findOne($goods_id);
  1158. $goods_url = "/goods/getAttrParams";
  1159. $param = [
  1160. 'id' => $goods->cloud_goods_id
  1161. ];
  1162. //请求接口
  1163. $domain = (new OptionSetting)->getCloudDomainName();
  1164. $goodsInfo = cloud_post($domain . $goods_url, $param);
  1165. $goodsInfo = json_decode($goodsInfo, true);
  1166. if ((int)$goodsInfo['code'] === 0) {
  1167. $goodsInfo = $goodsInfo['data'];
  1168. //需要安装
  1169. if ((int)$goodsInfo['send_type'] === 3 && (int)$goodsInfo['is_need_install'] === 1) {
  1170. return 1;
  1171. }
  1172. //不需要安装
  1173. if ((int)$goodsInfo['send_type'] === 3) {
  1174. return 3;
  1175. }
  1176. }
  1177. return 2;
  1178. } catch (\Exception $e) {
  1179. return 2;
  1180. }
  1181. }
  1182. //判断是否存在代理
  1183. public function goodsIsGoodsAgent($address, $goods_id) {
  1184. try {
  1185. if (empty($address) || !is_array($address)) {
  1186. throw new \Exception('缺少地址信息');
  1187. }
  1188. $goods = Goods::findOne(['id' => $goods_id, 'is_delete' => 0]);
  1189. if ((!empty($goods) && empty($goods->cloud_goods_id) || empty($goods) )) {
  1190. return [
  1191. 'code' => 0,
  1192. 'msg' => '非云仓商品'
  1193. ];
  1194. }
  1195. $goods_agent_admin = AgentGoodsBindGoods::find()->where(['cloud_goods_id' => $goods->cloud_goods_id, 'status' => 1, 'is_delete' => 0])
  1196. ->select('goods_agent_admin_id')->column();
  1197. $where = [
  1198. 'province_id' => $address['province_id'],
  1199. 'type' => 'goods_agent',
  1200. 'is_delete' => 0,
  1201. 'id' => $goods_agent_admin
  1202. ];
  1203. $admin = Admin::findOne(array_merge(
  1204. [
  1205. 'area_level' => 1,
  1206. 'city_id' => $address['city_id'],
  1207. 'district_id' => $address['district_id'],
  1208. ], $where));
  1209. if (!empty($admin)) {
  1210. return [
  1211. 'code' => 0,
  1212. 'msg' => 'success',
  1213. 'data' => $admin
  1214. ];
  1215. }
  1216. $admin = Admin::findOne(array_merge(
  1217. [
  1218. 'area_level' => 2,
  1219. 'city_id' => $address['city_id'],
  1220. ], $where));
  1221. if (!empty($admin)) {
  1222. return [
  1223. 'code' => 0,
  1224. 'msg' => 'success',
  1225. 'data' => $admin
  1226. ];
  1227. }
  1228. $admin = Admin::findOne(array_merge(
  1229. [
  1230. 'area_level' => 3,
  1231. ], $where));
  1232. if (!empty($admin)) {
  1233. return [
  1234. 'code' => 0,
  1235. 'msg' => 'success',
  1236. 'data' => $admin
  1237. ];
  1238. }
  1239. return [
  1240. 'code' => 1,
  1241. 'msg' => '该区域未存在产品代理,无法下单'
  1242. ];
  1243. } catch (\Exception $e) {
  1244. return [
  1245. 'code' => 1,
  1246. 'msg' => $e->getMessage()
  1247. ];
  1248. }
  1249. }
  1250. // 检测拼团信息
  1251. public function checkPtActivity($pt_number)
  1252. {
  1253. $pt_order = PtActivityOrder::findOne(['id' => $pt_number]);
  1254. if ($pt_order) {
  1255. if ((int)$pt_order->is_pay === 0) {
  1256. return [
  1257. 'code' => 1,
  1258. 'msg' => "当前团暂未开放"
  1259. ];
  1260. }
  1261. //error
  1262. $check_pt_order = PtActivityOrder::find()->where(['trade_status' => 0, 'is_pay' => 1])
  1263. ->andWhere(['OR', ['id' => $pt_number], ['pt_number' => $pt_number]])
  1264. ->select('id')->column();
  1265. $pt_activity = PtActivity::findOne($this->pt_activity_id);
  1266. if (!$this->pt_activity_id) {
  1267. return [
  1268. 'code' => 1,
  1269. 'msg' => "活动信息不存在或已结束"
  1270. ];
  1271. }
  1272. if($pt_activity->party_type == 0){
  1273. if ($pt_activity->party_size <= (count($check_pt_order))) {
  1274. return [
  1275. 'code' => 1,
  1276. 'msg' => "当前团已达上限"
  1277. ];
  1278. }
  1279. }
  1280. if($pt_activity->party_type == 1){
  1281. $goodsCountQuery = PtActivityOrderDetail::find()->alias('pod')
  1282. ->leftJoin(['po' => PtActivityOrder::tableName()], 'pod.order_id = po.id')
  1283. ->where(['po.is_pay' => 1, 'pod.is_delete' => 0])
  1284. ->andWhere(['OR' , ['po.id' => $pt_number], ['po.pt_number' => $pt_number]]);
  1285. $goodsCount = $goodsCountQuery->sum('pod.num');
  1286. if($pt_activity->party_goods_count <= (int)$goodsCount){
  1287. return [
  1288. 'code' => 1,
  1289. 'msg' => "当前团商品数量已达上限"
  1290. ];
  1291. }
  1292. }
  1293. }
  1294. return ['code' => 0, 'msg' => ''];
  1295. }
  1296. }