OrderForm.php 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\plugins\scanCodePay\models\form;
  8. use app\constants\OptionSetting;
  9. use app\models\Address;
  10. use app\models\Attr;
  11. use app\models\AttrGroup;
  12. use app\models\Cart;
  13. use app\models\Cat;
  14. use app\models\Coupon;
  15. use app\models\CouponAutoSend;
  16. use app\models\FreeDeliveryRules;
  17. use app\models\Goods;
  18. use app\models\GoodsCat;
  19. use app\models\GoodsFullMinus;
  20. use app\models\Level;
  21. use app\models\Mch;
  22. use app\models\MchGoodsCat;
  23. use app\models\OfferPrice;
  24. use app\models\Option;
  25. use app\models\Order;
  26. use app\models\PostageRules;
  27. use app\models\Shop;
  28. use app\models\TerritorialLimitation;
  29. use app\models\User;
  30. use app\models\UserCoupon;
  31. use app\models\CartOffline;
  32. use app\models\District;
  33. use Yii;
  34. use yii\base\Model;
  35. use yii\helpers\Json;
  36. class OrderForm extends Model
  37. {
  38. public $mch_list;
  39. public $address_id;
  40. public $_from;
  41. public $longitude;
  42. public $latitude;
  43. public $store_id;
  44. public $store;
  45. public $user_id;
  46. /** @var User $user */
  47. protected $user;
  48. protected $address;
  49. protected $level;
  50. protected $integral;
  51. protected $keyword;
  52. public function rules()
  53. {
  54. $rules = [
  55. ['mch_list', 'required'],
  56. ['address_id', 'integer'],
  57. ['mch_list', function ($attr, $params) {
  58. $data = Json::decode($this->mch_list);
  59. if (!$data) {
  60. $this->addError($attr, "{$attr}数据格式错误。");
  61. }
  62. $this->mch_list = $data;
  63. }],
  64. ['mch_list', function ($attr, $params) {
  65. foreach ($this->mch_list as $i => &$mch) {
  66. if (!is_array($mch['goods_list'])) {
  67. $this->addError($attr, "{$attr}[{$i}]['goods_list']必须是一个数组。");
  68. return;
  69. }
  70. }
  71. }],
  72. [['longitude', 'latitude', '_from'], 'trim'],
  73. [['_from'], 'in', 'range' => ['app', 'mini']],
  74. ];
  75. return $rules;
  76. }
  77. public function afterValidate()
  78. {
  79. $this->user = User::findOne($this->user_id);
  80. $this->level = $this->getLevelData();
  81. $this->address = $this->getAddressData();
  82. $this->integral = [
  83. 'forehead' => 0,
  84. 'forehead_integral' => 0,
  85. 'integration' => Option::get(OptionSetting::STORE_INTEGRATION,get_store_id(), 'gift', Option::get(OptionSetting::STORE_INTEGRATION,get_store_id(), 'store')['value'])
  86. ];
  87. parent::afterValidate();
  88. }
  89. protected function getMchListData($submit = false)
  90. {
  91. foreach ($this->mch_list as $i => &$mch) {
  92. $mch['goods_list'] = $this->getGoodsList($mch['goods_list']);
  93. if (empty($mch['goods_list'])) {
  94. throw new \Exception('商品不存在', 1);
  95. }
  96. $this->getCouponList($mch);
  97. }
  98. return $this->mch_list;
  99. }
  100. protected function getGoodsList($goods_list)
  101. {
  102. $goodsIds = [];
  103. foreach ($goods_list as $i => &$item) {
  104. if (isset($item['cart_id'])) {
  105. $cart = Cart::findOne([
  106. 'store_id' => get_store_id(),
  107. 'id' => $item['cart_id'],
  108. 'is_delete' => 0
  109. ]);
  110. if (!$cart) {
  111. unset($goods_list[$i]);
  112. continue;
  113. }
  114. $item['num'] = $cart->num;
  115. $attr_id_list = (array)Json::decode($cart->attr);
  116. $goods = Goods::findOne($cart->goods_id);
  117. } elseif ($item['goods_id']) {
  118. $attr_id_list = [];
  119. foreach ($item['attr'] as $_a) {
  120. array_push($attr_id_list, $_a['attr_id']);
  121. }
  122. $goods = Goods::findOne([
  123. 'store_id' => get_store_id(),
  124. 'id' => $item['goods_id'],
  125. ]);
  126. } else {
  127. unset($goods_list[$i]);
  128. continue;
  129. }
  130. if (!$goods) {
  131. unset($goods_list[$i]);
  132. continue;
  133. }
  134. if (($goods->confine_count && $goods->confine_count > 0)) {
  135. $goodsNum = Goods::getBuyNum($this->user, $goods->id);
  136. if ($goodsNum) {
  137. } else {
  138. $goodsNum = 0;
  139. }
  140. $goodsTotalNum = intval($goodsNum + $item['num']);
  141. if ($goodsTotalNum > $goods->confine_count) {
  142. throw new \Exception('商品:' . $goods->name . ' 超出购买数量', 1);
  143. }
  144. }
  145. $attr_info = $goods->getAttrInfo($attr_id_list);
  146. // 排除当面付检测库存
  147. if ((in_array($goods->type, [2, 6]) == false && $item['num'] > $attr_info['num']) || $item['num'] <= 0) { //库存不足
  148. unset($goods_list[$i]);
  149. continue;
  150. }
  151. $attr_list = Attr::find()->alias('a')
  152. ->select('ag.id AS attr_group_id,ag.attr_group_name,a.id AS attr_id,a.attr_name')
  153. ->leftJoin(['ag' => AttrGroup::tableName()], 'a.attr_group_id=ag.id')
  154. ->where(['a.id' => $attr_id_list, 'ag.store_id' => get_store_id(),])
  155. ->asArray()->all();
  156. $item['attr_list'] = $attr_list;
  157. $item['goods_id'] = $goods->id;
  158. $item['mch_id'] = $goods->mch_id;
  159. $item['goods_name'] = $goods->name;
  160. $item['goods_pic'] = $attr_info['pic'] ? $attr_info['pic'] : $goods->cover_pic;
  161. $item['price'] = sprintf('%.2f', ($attr_info['price'] * $item['num']));
  162. $item['single_price'] = sprintf('%.2f', $attr_info['price']);
  163. $item['weight'] = $goods->weight;
  164. $item['integral'] = $goods->integral ? $goods->integral : 0;
  165. $item['freight'] = $goods->freight;
  166. $item['full_cut'] = $goods->full_cut;
  167. $item['goods_cat_id'] = $goods->cat_id;
  168. $item['id'] = $goods->id;
  169. $item['type'] = $goods->type;
  170. $item['delivery_type'] = Json::decode($goods->delivery_type);
  171. // 当前选择的规格
  172. // $attrIdArr = [];
  173. // foreach ($item['attr_list'] as $attrListItem) {
  174. // $attrIdArr[] = $attrListItem['attr_id'];
  175. // }
  176. // $GoodsFullMinus = GoodsFullMinus::find()
  177. // ->select('*')
  178. // ->where(['store_id' => get_store_id(),'goods_id' => $goods['id']])
  179. // ->orderBy('full_minus_num ASC')->asArray()->all();
  180. $res = \app\modules\client\models\v1\common\CommonGoods::currentGoodsAttr([
  181. 'attr' => $goods['attr'],
  182. 'price' => $goods->type == 2 ? $item['price'] : $goods['price'],
  183. 'is_level' => $goods['is_level'],
  184. 'mch_id' => $goods['mch_id'],
  185. // 'full_minus' => $GoodsFullMinus,
  186. 'unit' => $goods['unit'],
  187. ], [1], [], $item['num']);
  188. // \Yii::error();
  189. // $item['batch_price_tips'] = $res['batch_price_tips'];
  190. // $item['current_batch_price_tips'] = $res['current_batch_price_tips'];
  191. $item['price'] = sprintf('%.2f', ($res['price'] * $item['num']));
  192. $item['level_price'] = sprintf('%.2f', ($res['level_price'] * $item['num']));
  193. $item['is_level'] = $res['is_level'];
  194. // 砍价不享受会员折扣
  195. if(isset($item['bargain_price'])) {
  196. $item['level_price'] = $item['price'];
  197. $item['is_level'] = 0;
  198. }
  199. $integralArr = $this->getIntegral((object)$item, Option::get(OptionSetting::STORE_INTEGRAL,get_store_id(), 'gift', Option::get(OptionSetting::STORE_INTEGRAL,get_store_id(), 'store')['value'])['value'], $goodsIds);
  200. $item['give'] = $integralArr['give'];
  201. $item['resIntegral'] = $integralArr['resIntegral'];
  202. $goodsIds[] = $goods->id;
  203. $item['goods_card_list'] = Goods::getGoodsCard($goods->id);
  204. }
  205. // 和空数组合并重建索引,避免出现因索引key间断导致客户端显示问题
  206. return array_merge($goods_list, []);
  207. }
  208. //自定义表单
  209. protected function getFormData()
  210. {
  211. $new_list = [];
  212. $new_list['is_form'] = Option::get('is_form', $this->store_id, 'admin', 0);
  213. $form_list = [];
  214. if ($new_list['is_form'] == 1) {
  215. $new_list['name'] = Option::get('form_name', $this->store_id, 'admin', '表单信息');
  216. $form_list = Form::find()->where([
  217. 'store_id' => $this->store_id, 'is_delete' => 0,
  218. ])->orderBy(['sort' => SORT_ASC])->asArray()->all();
  219. foreach ($form_list as $index => $value) {
  220. if (in_array($value['type'], ['radio', 'checkbox'])) {
  221. $default = str_replace(",", ",", $value['default']);
  222. $list = explode(',', $default);
  223. $default_list = [];
  224. foreach ($list as $k => $v) {
  225. $default_list[$k]['name'] = $v;
  226. if ($k == 0) {
  227. $default_list[$k]['is_selected'] = 1;
  228. } else {
  229. $default_list[$k]['is_selected'] = 0;
  230. }
  231. }
  232. $form_list[$index]['default_list'] = $default_list;
  233. }
  234. }
  235. }
  236. $new_list['list'] = $form_list;
  237. return $new_list;
  238. }
  239. protected function getAddress()
  240. {
  241. if (!$this->address) {
  242. if ($this->address_id) {
  243. $this->address = Address::findOne(['id' => $this->address_id, 'user_id' => $this->user_id, 'is_delete' => 0]);
  244. } else {
  245. $this->address = Address::find()->where([
  246. 'user_id' => $this->user_id,
  247. 'is_default' => 1,
  248. 'is_delete' => 0,
  249. ])->limit(1)->one();
  250. }
  251. }
  252. return (object)$this->address;
  253. }
  254. //获取收货地址,有address_id优先获取,没有则获取默认地址
  255. protected function getAddressData()
  256. {
  257. $address = $this->getAddress();
  258. if (isset($address->id)) {
  259. return [
  260. 'id' => $address->id,
  261. 'name' => $address->name,
  262. 'mobile' => $address->mobile,
  263. 'province_id' => $address->province_id,
  264. 'province' => $address->province,
  265. 'city_id' => $address->city_id,
  266. 'city' => $address->city,
  267. 'district_id' => $address->district_id,
  268. 'district' => $address->district,
  269. 'detail' => $address->detail,
  270. 'is_default' => $address->is_default,
  271. 'latitude' => $address->latitude,
  272. 'longitude' => $address->longitude,
  273. ];
  274. } else {
  275. return null;
  276. }
  277. }
  278. //获取支付方式
  279. protected function getPayTypeList()
  280. {
  281. $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']);
  282. $pay_type_list = Json::decode($pay_type_list_json['value']);
  283. $new_list = [];
  284. $ok = true;
  285. foreach ($this->mch_list as $mch) {
  286. if ($mch['mch_id'] == 0) {
  287. continue;
  288. } else {
  289. $ok = false;
  290. break;
  291. }
  292. }
  293. if (is_wechat_platform()) {
  294. $new_list[] = [
  295. 'name' => '微信支付',
  296. 'payment' => 1,
  297. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/v1/statics/images/recharge/icon-online.png'
  298. ];
  299. }
  300. if (is_alipay_platform()) {
  301. $new_list[] = [
  302. 'name' => '支付宝支付',
  303. 'payment' => 4,
  304. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/statics/images/recharge/icon-alipay.png'
  305. ];
  306. }
  307. foreach ($pay_type_list as $index => $value) {
  308. if ($index == 'huodao' && $value['value'] == 1 && $ok) {
  309. $new_list[] = [
  310. 'name' => '货到付款',
  311. 'payment' => 2,
  312. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/v1/statics/images/recharge/icon-huodao.png'
  313. ];
  314. }
  315. }
  316. return $new_list;
  317. }
  318. /**
  319. * 支付方式
  320. * @param array $is_payment //支付方式
  321. * @param array $ignore //忽略的支付方式
  322. * @return array
  323. */
  324. public static function getPayType($is_payment = array(), $ignore = array())
  325. {
  326. if (!$is_payment || empty($is_payment)) {
  327. $pay_str = Option::get(OptionSetting::STORE_PAYMENT, get_store_id(), 'pay', Option::get(OptionSetting::STORE_PAYMENT, get_store_id(), 'store', '{"wechat":{"value":1}}')['value']);
  328. $is_payment = Json::decode($pay_str['value']);
  329. }
  330. $pay_type_list = [];
  331. foreach ($is_payment as $index => $value) {
  332. if (in_array($index, $ignore)) {
  333. continue;
  334. }
  335. if ($index == 'wechat' && $value['value'] == 1) {
  336. $pay_type_list[] = [
  337. 'name' => '微信支付',
  338. 'payment' => 1,
  339. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/v1/statics/wxapp/images/icon-payment-online.png'
  340. ];
  341. }
  342. if ($index == 'huodao' && $value['value'] == 1) {
  343. $pay_type_list[] = [
  344. 'name' => '货到付款',
  345. 'payment' => 2,
  346. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/v1/statics/wxapp/images/icon-payment-huodao.png'
  347. ];
  348. }
  349. if (get_params('_from') == OrderPayDataForm::PAY_FROM_APP) {
  350. if ($index == 'alipay' && $value['value'] == 1) {
  351. $pay_type_list[] = [
  352. 'name' => '支付宝支付',
  353. 'payment' => 4,
  354. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/statics/images/recharge/icon-alipay.png'
  355. ];
  356. }
  357. }
  358. if ($index == 'balance' && $value['value'] == 1) {
  359. $pay_type_list[] = [
  360. 'name' => '账户余额支付',
  361. 'payment' => 3,
  362. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/v1/statics/wxapp/images/icon-payment-balance.png'
  363. ];
  364. }
  365. }
  366. if (!$pay_type_list) {
  367. $pay_type_list[] = [
  368. 'name' => '微信支付',
  369. 'payment' => 1,
  370. 'icon' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/v1/statics/images/recharge/icon-online.png'
  371. ];
  372. }
  373. return $pay_type_list;
  374. }
  375. protected function getCouponList(&$mch)
  376. {
  377. if (!isset($mch['mch_id'])) {
  378. $mch['mch_id'] = 0;
  379. }
  380. $goods_total_price = isset($mch['total_price']) ? $mch['total_price'] : 0;
  381. $cat_ids = $this->getCatIdList($mch['goods_list'], $mch['mch_id']);
  382. $coupon_goods_id = $this->getGoodsIdList($mch['goods_list']);
  383. // Yii::error([$goods_total_price, $this->user_id, $this->store_id]);
  384. $list = UserCoupon::find()->alias('uc')
  385. ->leftJoin(['c' => Coupon::tableName()], 'uc.coupon_id=c.id')
  386. ->leftJoin(['cas' => CouponAutoSend::tableName()], 'uc.coupon_auto_send_id=cas.id')
  387. ->where([
  388. 'AND',
  389. ['uc.store_id' => $this->store_id],
  390. ['uc.is_delete' => 0],
  391. ['uc.is_use' => 0],
  392. ['uc.is_expire' => 0],
  393. ['uc.user_id' => $this->user_id],
  394. ['<=', 'c.min_price', $goods_total_price],
  395. ])
  396. ->select('uc.id user_coupon_id,c.mch_id,uc.is_use,uc.is_expire,c.sub_price,c.min_price,cas.event,uc.begin_time,uc.end_time,uc.type,c.appoint_type,c.cat_id_list,c.goods_id_list')
  397. ->asArray()->all();
  398. $events = [
  399. 0 => '平台发放',
  400. 1 => '分享红包',
  401. 2 => '购物返券',
  402. 3 => '领券中心',
  403. ];
  404. $max_price = isset($mch['total_price']) ? $mch['total_price'] : 0;
  405. $new_list = [];
  406. foreach ($list as $i => $item) {
  407. if ($item['begin_time'] > (strtotime(date('Y-M-d')) + 86400) || $item['end_time'] < time()) {
  408. continue;
  409. }
  410. $list[$i]['status'] = 0;
  411. if ($item['is_use']) {
  412. $list[$i]['status'] = 1;
  413. }
  414. if ($item['is_expire']) {
  415. $list[$i]['status'] = 2;
  416. }
  417. $list[$i]['min_price_desc'] = $item['min_price'] == 0 ? '无门槛' : '满' . $item['min_price'] . '元可用';
  418. $list[$i]['begin_time'] = date('Y.m.d H:i', (int)$item['begin_time']);
  419. $list[$i]['end_time'] = date('Y.m.d H:i', (int)$item['end_time']);
  420. if (!$item['event']) {
  421. if ($item['type'] == 2) {
  422. $list[$i]['event'] = $item['event'] = 3;
  423. } else {
  424. $list[$i]['event'] = $item['event'] = 0;
  425. }
  426. }
  427. if ($list[$i]['mch_id'] > 0) {
  428. $list[$i]['event_desc'] = Mch::findOne($list[$i]['mch_id'])->name;
  429. }else {
  430. $list[$i]['event_desc'] = $events[$item['event']];
  431. }
  432. $list[$i]['min_price'] = doubleval($item['min_price']);
  433. $list[$i]['sub_price'] = doubleval($item['sub_price']);
  434. if ($list[$i]['appoint_type'] == 1) {
  435. $list[$i]['cat_id_list'] = json_decode($list[$i]['cat_id_list']);
  436. if ($list[$i]['cat_id_list'] != null) {
  437. $goodsAdd = [];
  438. foreach ($mch['goods_list'] as $v2) {
  439. if (!in_array($v2['goods_id'], $goodsAdd)) {
  440. array_push($goodsAdd, $v2['goods_id']);
  441. }
  442. };
  443. if ($mch['price'] < $list[$i]['min_price']) {
  444. unset($list[$i]);
  445. continue;
  446. }
  447. }
  448. } elseif ($list[$i]['appoint_type'] == 2) {
  449. $list[$i]['goods_id_list'] = json_decode($list[$i]['goods_id_list']);
  450. if ($list[$i]['goods_id_list'] != null) {
  451. $current = array_intersect($list[$i]['goods_id_list'], $coupon_goods_id);
  452. if ($current) {
  453. } else {
  454. unset($list[$i]);
  455. continue;
  456. }
  457. }
  458. } else {
  459. if ($max_price < $list[$i]['min_price']) {
  460. unset($list[$i]);
  461. continue;
  462. }
  463. }
  464. $new_list[] = $list[$i];
  465. }
  466. $mch['coupon_list'] = $new_list;
  467. }
  468. protected function getCatIdList(&$goods_list, $mch_id = 0)
  469. {
  470. $cat_id_list = [];
  471. foreach ($goods_list as &$goods) {
  472. $goods['cat_id'] = [];
  473. if ($goods['goods_cat_id'] == 0) {
  474. if ($mch_id > 0) {
  475. $goods_cat_list = MchGoodsCat::find()
  476. ->select('cat_id')->where([
  477. 'goods_id' => $goods['goods_id'],
  478. ])->all();
  479. } else {
  480. $goods_cat_list = GoodsCat::find()
  481. ->select('cat_id')->where([
  482. 'goods_id' => $goods['goods_id'],
  483. 'is_delete' => 0,
  484. ])->all();
  485. }
  486. foreach ($goods_cat_list as $goods_cat) {
  487. $cat_id_list[] = $goods_cat->cat_id;
  488. $goods['cat_id'][] = $goods_cat->cat_id;
  489. }
  490. } else {
  491. $cat_id_list[] = $goods['goods_cat_id'];
  492. $goods['cat_id'][] = $goods['goods_cat_id'];
  493. }
  494. $cat_parent_list = Cat::find()->select('parent_id')
  495. ->andWhere(['id' => $goods['cat_id'], 'store_id' => $this->store_id, 'is_delete' => 0])->andWhere(['>', 'parent_id', 0])
  496. ->column();
  497. $cat_id_list = array_merge($cat_parent_list, $cat_id_list);
  498. $goods['cat_id'] = array_merge($cat_parent_list, is_array($goods['cat_id']) ? $goods['cat_id'] : []);
  499. }
  500. unset($goods);
  501. return array_unique($cat_id_list);
  502. }
  503. protected function getGoodsIdList($goods_list)
  504. {
  505. $goods_id_list = [];
  506. foreach ($goods_list as $goods) {
  507. $goods_id_list[] = $goods['goods_id'];
  508. }
  509. return $goods_id_list;
  510. }
  511. protected function getLevelData()
  512. {
  513. $level = Level::find()->select([
  514. 'name', 'level', 'discount',
  515. ])->where(['level' => $this->user->level, 'store_id' => $this->store_id, 'is_delete' => 0])
  516. ->asArray()->one();
  517. return $level;
  518. }
  519. //积分计算
  520. /**
  521. * @param $goods_item object 重新编写的goods_item
  522. * @param $store_integral int 商城设置的积分规则
  523. * @param $goods_id array 已设置积分的商品id数组
  524. * @return array
  525. */
  526. protected function getIntegral($goods_item, $store_integral, $goods_id = array())
  527. {
  528. $integral = json_decode($goods_item->integral, true);
  529. $resIntegral = [
  530. 'forehead' => 0,
  531. 'forehead_integral' => 0,
  532. ];
  533. if ($integral) {
  534. //赠送积分计算
  535. $give = $integral['give'];
  536. if (strpos($give, '%') !== false) {
  537. // 百分比
  538. $give = trim($give, '%');
  539. $goods_item->give = (int)($goods_item->price * ($give / 100));
  540. } else {
  541. // 固定积分
  542. $goods_item->give = (int)($give * $goods_item->num);
  543. }
  544. //抵扣积分计算
  545. $forehead = $integral['forehead'];
  546. if ($forehead) {
  547. if (strpos($forehead, '%') !== false) {//百分比积分抵扣计算
  548. if ($forehead >= 100) {
  549. $forehead = 100;
  550. }
  551. if ($integral['more'] == '1') {//多件累计计算
  552. $resIntegral['forehead_integral'] = (int)(($forehead / 100) * $goods_item->price * $store_integral);
  553. } else {
  554. if (!in_array($goods_item->id, $goods_id)) { //不允许多件累计 同id商品值计算一次积分抵扣
  555. $resIntegral['forehead_integral'] = (int)(($forehead / 100) * $goods_item->single_price * $store_integral);
  556. }
  557. }
  558. } else {
  559. if ($integral['more'] == '1') {
  560. $resIntegral['forehead_integral'] = (int)($store_integral * $goods_item->price);
  561. if ($goods_item->price > ($forehead * $goods_item->num)) {
  562. $resIntegral['forehead_integral'] = (int)($forehead * $goods_item->num * $store_integral);
  563. }
  564. } else {
  565. if (!in_array($goods_item->id, $goods_id)) {
  566. $goodsPrice = $goods_item->single_price;
  567. $resIntegral['forehead_integral'] = (int)($store_integral * $goodsPrice);
  568. if ($goodsPrice > $forehead) {
  569. if ($forehead > 0) {
  570. $resIntegral['forehead_integral'] = (int)($forehead * $store_integral);
  571. } else {
  572. $resIntegral['forehead_integral'] = 0;
  573. }
  574. }
  575. }
  576. }
  577. }
  578. }
  579. if ($this->integral['forehead_integral'] < $this->user->integral) {
  580. $resetIntegral = $this->user->integral - $this->integral['forehead_integral'];
  581. $resIntegral['forehead_integral'] = $resIntegral['forehead_integral'] >= $resetIntegral ? $resetIntegral : $resIntegral['forehead_integral'];
  582. $resIntegral['forehead'] = $store_integral > 0 ? sprintf("%.2f", ($resIntegral['forehead_integral'] / $store_integral)) : 0;
  583. $this->integral['forehead_integral'] += $resIntegral['forehead_integral'];
  584. $this->integral['forehead'] += $resIntegral['forehead'];
  585. } else {
  586. $resIntegral['forehead_integral'] = 0;
  587. $resIntegral['forehead'] = 0;
  588. }
  589. }
  590. return [
  591. 'resIntegral' => $resIntegral,
  592. 'give' => $goods_item->give
  593. ];
  594. }
  595. protected function getExpressPrice($mch)
  596. {
  597. $expressPrice = 0;
  598. if ($this->address) {
  599. $address = $this->address;
  600. //先计算单品满件包邮和满额包邮
  601. $resGoodsList = Goods::cutFull($mch['goods_list']);
  602. //再通过运费规则计算运费
  603. $expressPrice = PostageRules::getExpressPriceMore($this->store_id, $address['city_id'], $resGoodsList, $address['province_id']);
  604. }
  605. $expressPrice = $this->getFreeDeliveryRules($mch, $expressPrice);
  606. return $expressPrice >= 0 ? $expressPrice : 0;
  607. }
  608. /**
  609. * 计算打包费
  610. * @param $mch
  611. * @return int
  612. */
  613. protected function getDabaoPrice($mch)
  614. {
  615. $goods_list = $mch['goods_list'];
  616. $dabao_price = 0;
  617. foreach ($goods_list as $value) {
  618. $dabao_price += $value['dabao_price'];
  619. }
  620. return $dabao_price >= 0 ? $dabao_price : 0;
  621. }
  622. // 获取门店列表
  623. protected function getShopList()
  624. {
  625. $start = 0;
  626. $shop_table_name = Shop::tableName();
  627. $user_table_name = User::tableName();
  628. $address = Address::findOne($this->address['id']);
  629. $latitude = $address->latitude ? $address->latitude : 0;
  630. $longitude = $address->longitude ? $address->longitude : 0;
  631. $sql = "SELECT `s`.*, `u`.`nickname`, acos(cos({$latitude}*pi()/180 )*cos(s.latitude*pi()/180)*cos({$longitude}*pi()/180 -s.longitude*pi()/180)+sin({$latitude}*pi()/180 )*sin(s.latitude*pi()/180))*6370996.81 as
  632. distance FROM {$shop_table_name} `s` LEFT JOIN {$user_table_name} `u`
  633. ON s.id=u.shop_id WHERE ((`s`.`store_id`={$this->store_id}) AND (`s`.`is_delete`=0)) AND (`s`.`user_id` > 0) ";
  634. if ($this->keyword) {
  635. $sql .= " AND (`s`.`name` like '%{$this->keyword}%') ";
  636. }
  637. $sql .= "ORDER BY `distance` LIMIT {$start},30";
  638. $list = \Yii::$app->db->createCommand($sql)->queryAll();
  639. $shop = null;
  640. foreach ($list as $index => $item) {
  641. if ($item['is_default'] == 1) {
  642. $shop = $item;
  643. }
  644. $list[$index]['distance'] = round($item['distance']/1000, 2).'km';
  645. }
  646. return [
  647. 'list' => $list,
  648. 'shop' => $shop
  649. ];
  650. }
  651. // 获取起送规则
  652. protected function getOfferRule($mch)
  653. {
  654. $res = [
  655. 'is_allowed' => 0,
  656. 'total_price' => 0,
  657. 'msg' => ''
  658. ];
  659. if ($mch['mch_id'] > 0) {
  660. $res['msg'] = '商户不支持起送规则';
  661. return $res;
  662. }
  663. if ($mch['plugin_type'] == 2) {
  664. $res['msg'] = '砍价不支持起送规则';
  665. return $res;
  666. }
  667. if (!$this->address) {
  668. $res['msg'] = '请选择收货地址';
  669. return $res;
  670. }
  671. $offerRule = OfferPrice::findOne(['store_id' => get_store_id(),'is_delete' => 0]);
  672. if (!$offerRule) {
  673. $res['msg'] = '起送规则不存在';
  674. return $res;
  675. }
  676. if ($offerRule->is_enable == 0) {
  677. $res['msg'] = '起送规则未开启';
  678. return $res;
  679. }
  680. $ruleList = Json::decode($offerRule->detail);
  681. $res['total_price'] = $offerRule->price;
  682. if (is_array($ruleList)) {
  683. foreach ($ruleList as $value) {
  684. foreach ($value['province_list'] as $item) {
  685. if ($item['id'] == $this->address['city_id']) {
  686. $res['total_price'] = $value['offer_price'];
  687. }
  688. }
  689. }
  690. }
  691. if ($mch['total_price'] >= $res['total_price']) {
  692. $res['is_allowed'] = 0;
  693. } else {
  694. $res['is_allowed'] = 1;
  695. }
  696. $value = round($res['total_price'] - $mch['total_price'], 2);
  697. $res['msg'] = "自营商品,还差{$value}元起送";
  698. return $res;
  699. }
  700. protected function getTerritorialLimitation($mch)
  701. {
  702. $isArea = 0;
  703. if ($mch['mch_id'] > 0) {
  704. return $isArea;
  705. }
  706. if ($this->address) {
  707. $area = TerritorialLimitation::findOne([
  708. 'store_id' => $this->store_id,
  709. 'is_delete' => 0,
  710. 'is_enable' => 1,
  711. ]);
  712. if ($area) {
  713. $city_id = []; //限制的地区ID
  714. $detail = json_decode($area->detail);
  715. if (!is_array($detail)) {
  716. $detail = [];
  717. }
  718. foreach ($detail as $key => $value) {
  719. foreach ($value->province_list as $key2 => $value2) {
  720. $city_id[] = $value2->id;
  721. }
  722. }
  723. $addressArr = [
  724. $this->address['province_id'],
  725. $this->address['city_id'],
  726. $this->address['district_id']
  727. ];
  728. $addressArray = array_intersect($addressArr, $city_id);
  729. if (empty($addressArray)) {
  730. $isArea = 1;
  731. }
  732. }
  733. }
  734. return $isArea;
  735. }
  736. // 包邮规则
  737. protected function getFreeDeliveryRules($mch, $expressPrice)
  738. {
  739. if ($expressPrice == 0) {
  740. return $expressPrice;
  741. }
  742. if ($mch['mch_id'] == 0) {
  743. $free = FreeDeliveryRules::find()->where(['store_id' => $this->store_id, 'is_delete' => 0, 'mch_id' => 0])->asArray()->all();
  744. foreach ($free as $k => $v) {
  745. $city = json_decode($v['city'], true);
  746. foreach ($city as $v1) {
  747. if ($this->address['district_id'] == $v1['id'] && $mch['total_price'] >= $v['price']) {
  748. $expressPrice = 0;
  749. break;
  750. }
  751. }
  752. }
  753. } else {
  754. $free = FreeDeliveryRules::find()->where(['store_id' => $this->store_id, 'mch_id' => $mch['mch_id'], 'is_delete' => 0])->asArray()->all();
  755. foreach ($free as $k => $v) {
  756. $city = json_decode($v['city'], true);
  757. foreach ($city as $v1) {
  758. if ($this->address['district_id'] == $v1['id'] && $mch['total_price'] >= $v['price']) {
  759. $expressPrice = 0;
  760. break;
  761. }
  762. }
  763. }
  764. }
  765. return $expressPrice;
  766. }
  767. // 获取用户填写的自定义表单
  768. protected function getForm(&$form)
  769. {
  770. if ($form['is_form'] == 1) {
  771. $formList = &$form['list'];
  772. foreach ($formList as $index => $value) {
  773. if ($value['required'] == 1) {
  774. if (in_array($value['type'], ['radio', 'checkbox'])) {
  775. $is_true = false;
  776. foreach ($value['default_list'] as $k => $v) {
  777. if ($v['is_selected'] == 1) {
  778. $is_true = true;
  779. }
  780. }
  781. if (!$is_true) {
  782. return [
  783. 'code' => 1,
  784. 'msg' => '请填写' . $form['name'] . ',加“*”为必填项',
  785. 'name' => $value['name']
  786. ];
  787. }
  788. } else {
  789. if (!$value['default'] && $value['default'] != 0) {
  790. return [
  791. 'code' => 1,
  792. 'msg' => '请填写' . $form['name'] . ',加“*”为必填项',
  793. 'name' => $value['name']
  794. ];
  795. }
  796. }
  797. }
  798. if (in_array($value['type'], ['radio', 'checkbox'])) {
  799. $d = [];
  800. foreach ($value['default_list'] as $k => $v) {
  801. if ($v['is_selected'] == 1) {
  802. $d[] = $v['name'];
  803. }
  804. }
  805. $formList[$index]['default'] = implode(',', $d);
  806. }
  807. }
  808. }
  809. return $form;
  810. }
  811. protected function goodsCardList()
  812. {
  813. $list = [];
  814. foreach ($this->mch_list as $mch) {
  815. if($mch['mch_id'] == 0) {
  816. foreach ($mch['goods_list'] as $goods) {
  817. if(!$goods['goods_card_list']) {
  818. $goods['goods_card_list'] = [];
  819. }
  820. $list = array_merge($list, $goods['goods_card_list']);
  821. }
  822. }
  823. }
  824. return $list;
  825. }
  826. }