Express.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace app\model\express;
  11. use app\model\BaseModel;
  12. /**
  13. * 物流配送
  14. */
  15. class Express extends BaseModel
  16. {
  17. const express_type = [
  18. 'express' => [ 'name' => 'express', 'title' => '物流配送' ],
  19. 'store' => [ 'name' => 'store', 'title' => '门店自提' ],
  20. 'local' => [ 'name' => 'local', 'title' => '外卖配送' ],
  21. ];
  22. /**
  23. * 计算费用
  24. * @param array $shop_goods
  25. * @param array $data
  26. */
  27. public function calculate($shop_goods, $data)
  28. {
  29. //模板分组
  30. $template_array = [];
  31. foreach ($shop_goods[ 'goods_list' ] as $k => $v) {
  32. if ($v[ 'is_free_shipping' ] == 1) {
  33. continue;
  34. }
  35. if (isset($template_array[ $v[ 'shipping_template' ] ])) {
  36. $template_array[ $v[ 'shipping_template' ] ] = [
  37. 'num' => $template_array[ $v[ 'shipping_template' ] ][ 'num' ] + $v[ 'num' ],
  38. 'weight' => $template_array[ $v[ 'shipping_template' ] ][ 'weight' ] + $v[ 'weight' ] * $v[ 'num' ],
  39. 'volume' => $template_array[ $v[ 'shipping_template' ] ][ 'volume' ] + $v[ 'volume' ] * $v[ 'num' ],
  40. 'goods_money' => $template_array[ $v[ 'shipping_template' ] ][ 'goods_money' ] + $v[ 'goods_money' ],
  41. ];
  42. } else {
  43. $template_array[ $v[ 'shipping_template' ] ] = [
  44. 'num' => $v[ 'num' ],
  45. 'weight' => $v[ 'weight' ] * $v[ 'num' ],
  46. 'volume' => $v[ 'volume' ] * $v[ 'num' ],
  47. 'goods_money' => $v[ 'goods_money' ]
  48. ];
  49. }
  50. }
  51. $express_template = new ExpressTemplate();
  52. $price = 0;
  53. foreach ($template_array as $k_template => $v_template) {
  54. if ($k_template == 0) {
  55. //默认模板
  56. $template_info = $express_template->getDefaultTemplate($shop_goods[ 'site_id' ]);
  57. } else {
  58. //如果选择的模板已经不存在(可能不存在),
  59. //默认模板
  60. $template_info = $express_template->getExpressTemplateInfo($k_template, $shop_goods[ 'site_id' ]);
  61. }
  62. //判断模板是否配置完善
  63. if (empty($template_info[ 'data' ])) {
  64. // continue;
  65. return $this->error([], 'TEMPLATE_EMPTY');
  66. }
  67. $template_info = $template_info[ 'data' ];
  68. $appoint_free_shipping = $template_info[ 'appoint_free_shipping' ] ?? 0;
  69. $is_exist_free = false;
  70. if ($appoint_free_shipping == 1) {
  71. $item_num = $v_template[ 'num' ];
  72. $item_goods_money = $v_template[ 'goods_money' ];
  73. //免邮区域模板
  74. $free_template_list = $template_info[ 'shipping_template_item' ];
  75. foreach ($free_template_list as $free_k => $free_v) {
  76. //判断是否有适配的区域模板
  77. if (strpos($free_v[ 'area_ids' ], '"' . $data[ 'member_address' ][ 'district_id' ] . '"') !== false) {
  78. $item_snum = $free_v[ 'snum' ];//条件(件数)
  79. $item_sprice = $free_v[ 'sprice' ];//条件 商品总额
  80. if ($item_sprice <= $item_goods_money && $item_snum <= $item_num) {//满足包邮条件,免邮
  81. $is_exist_free = true;
  82. // continue 2;
  83. }
  84. }
  85. }
  86. }
  87. if (!$is_exist_free) {
  88. //开始计算
  89. $is_exist_template = false;
  90. foreach ($template_info[ 'template_item' ] as $k_item => $v_item) {
  91. if (strpos($v_item[ 'area_ids' ], '"' . $data[ 'member_address' ][ 'district_id' ] . '"') !== false) {
  92. $is_exist_template = true;
  93. //运算方式
  94. switch ( $template_info[ 'fee_type' ] ) {
  95. case 1:
  96. $tag = $v_template[ 'weight' ];
  97. break;
  98. case 2:
  99. $tag = $v_template[ 'volume' ];
  100. break;
  101. case 3:
  102. $tag = $v_template[ 'num' ];
  103. break;
  104. default:
  105. break;
  106. }
  107. //开始计算
  108. if ($template_info[ 'fee_type' ] == 1 && $tag == 0) {
  109. $price += 0.0;
  110. } else {
  111. if ($tag <= $v_item[ 'snum' ]) {
  112. $price += $v_item[ 'sprice' ];
  113. } else {
  114. $ext_tag = $tag - $v_item[ 'snum' ];
  115. if ($v_item[ 'xnum' ] == 0) {
  116. $v_item[ 'xnum' ] = 1;
  117. }
  118. if (( $ext_tag * 100 ) % ( $v_item[ 'xnum' ] * 100 ) == 0) {
  119. $ext_data = $ext_tag / $v_item[ 'xnum' ];
  120. } else {
  121. $ext_data = floor($ext_tag / $v_item[ 'xnum' ]) + 1;
  122. }
  123. $price += $v_item[ 'sprice' ] + $ext_data * $v_item[ 'xprice' ];
  124. }
  125. }
  126. break;
  127. }
  128. }
  129. if ($is_exist_template == false) {
  130. return $this->error('', 'TEMPLATE_AREA_EXIST');
  131. }
  132. }
  133. }
  134. return $this->success([ 'delivery_fee' => $price ]);
  135. }
  136. /**
  137. * 区域是否支持配送
  138. * @param $condition
  139. */
  140. public function isSupportDelivery($area_id, $site_id)
  141. {
  142. $condition = array (
  143. [ 'ati.area_ids', 'like', '"' . $area_id . '"' ],
  144. [ 'et.site_id', '=', $site_id ]
  145. );
  146. $alias = 'ati';
  147. $join = [
  148. [
  149. 'express_template et',
  150. 'et.template_id = ati.template_id',
  151. 'left'
  152. ]
  153. ];
  154. $field = 'ati.template_id';
  155. $list = model('express_template_item')->getList($condition, $field, '', $alias, $join);
  156. if (empty($list)) {
  157. return $this->error('', 'TEMPLATE_AREA_EXIST');
  158. } else {
  159. return $this->success();
  160. }
  161. }
  162. /**
  163. * 积分兑换计算费用
  164. * @param $goods_info
  165. * @param $data
  166. * @return array
  167. */
  168. public function pointExchangeCalculate($goods_info, $data)
  169. {
  170. $num = $data[ 'num' ];
  171. if ($goods_info[ 'is_free_shipping' ] == 1) {
  172. return $this->success([ 'delivery_fee' => 0 ]);
  173. }
  174. $template_data = [
  175. 'num' => $num,
  176. 'weight' => $goods_info[ 'weight' ] * $num,
  177. 'volume' => $goods_info[ 'volume' ] * $num
  178. ];
  179. $express_template = new ExpressTemplate();
  180. $price = 0;
  181. if ($goods_info[ 'shipping_template' ] == 0) {
  182. //默认模板
  183. $template_info = $express_template->getDefaultTemplate($data[ 'site_id' ]);
  184. } else {
  185. //默认模板
  186. $template_info = $express_template->getExpressTemplateInfo($goods_info[ 'shipping_template' ], $data[ 'site_id' ]);
  187. }
  188. //判断模板是否配置完善
  189. if (empty($template_info[ 'data' ])) {
  190. return $this->error([], 'TEMPLATE_EMPTY');
  191. }
  192. $template_info = $template_info[ 'data' ];
  193. //开始计算
  194. $is_exist_template = false;
  195. foreach ($template_info[ 'template_item' ] as $k_item => $v_item) {
  196. if (strpos($v_item[ 'area_ids' ], '"' . $data[ 'member_address' ][ 'district_id' ] . '"') !== false) {
  197. $is_exist_template = true;
  198. //运算方式
  199. switch ( $template_info[ 'fee_type' ] ) {
  200. case 1:
  201. $tag = $template_data[ 'weight' ];
  202. break;
  203. case 2:
  204. $tag = $template_data[ 'volume' ];
  205. break;
  206. case 3:
  207. $tag = $template_data[ 'num' ];
  208. break;
  209. default:
  210. break;
  211. }
  212. //开始计算
  213. if ($tag <= $v_item[ 'snum' ]) {
  214. $price += $v_item[ 'sprice' ];
  215. } else {
  216. $ext_tag = $tag - $v_item[ 'snum' ];
  217. if ($v_item[ 'xnum' ] == 0) {
  218. $v_item[ 'xnum' ] = 1;
  219. }
  220. if (( $ext_tag * 100 ) % ( $v_item[ 'xnum' ] * 100 ) == 0) {
  221. $ext_data = $ext_tag / $v_item[ 'xnum' ];
  222. } else {
  223. $ext_data = floor($ext_tag / $v_item[ 'xnum' ]) + 1;
  224. }
  225. $price += $v_item[ 'sprice' ] + $ext_data * $v_item[ 'xprice' ];
  226. }
  227. break;
  228. }
  229. }
  230. if ($is_exist_template == false) {
  231. return $this->error('', 'TEMPLATE_AREA_EXIST');
  232. }
  233. return $this->success([ 'delivery_fee' => $price ]);
  234. }
  235. }