| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- <?php
- namespace api\services;
- use common\models\order\Order;
- use common\enums\AppEnum;
- use common\enums\GoodsTypeEnum;
- use common\enums\OrderStatusEnum;
- use common\enums\PreviewTypeEnum;
- use common\enums\ShippingTypeEnum;
- use common\enums\StatusEnum;
- use common\events\order\OrderChangeAddressEvent;
- use common\logic\order\OrderFormLogic;
- use common\logic\order\OrderInitDataLogic;
- use common\logic\order\OrderMarketingLogic;
- use common\models\order\OrderExtra;
- use common\models\order\OrderModifyShippingAddressLog;
- use common\models\user\UserAddress;
- use Exception;
- use yii\helpers\Json;
- class OrderService
- {
- protected $order;
- # 订单留言模型
- protected $order_extra;
- public function __construct(Order $order, OrderExtra $order_extra)
- {
- $this->order = $order;
- $this->order_extra = $order_extra;
- }
- /**
- * 订单留言列表
- * @param $order_id
- * @param $mall_id
- * @return array|\yii\db\ActiveRecord[]
- * @throws \Exception
- */
- public function leave($order_id, $mall_id): array
- {
- $where = ['order_id' => $order_id, 'mall_id' => $mall_id];
- // 判断订单是否存在
- $exists = $this->order::find()->where(['=', 'id', $order_id])->where(['=', 'mall_id', $mall_id])->exists();
- if (!$exists) {
- throw new \Exception('订单不存在!');
- }
- return $this->order_extra::getInfo($where,"id,message,created_at");
- }
- /**
- * 修改地址
- *
- * @param int $userId
- * @param int $mallId
- * @param int $addressId
- * @param int $orderId
- *
- * @return void
- * @throws Exception
- */
- public function modifyAddress(int $userId, int $mallId, int $addressId, int $orderId)
- {
- $addressExist = UserAddress::find()
- ->where(['id' => $addressId, 'user_id' => $userId, 'status' => StatusEnum::ENABLED])
- ->count();
- if (!$addressExist) {
- throw new \RuntimeException('地址错误');
- }
- $order = \common\models\order\Order::find()
- ->where([
- 'id' => $orderId,
- 'mall_id' => $mallId,
- 'user_id' => $userId,
- 'status' => StatusEnum::ENABLED,
- ])
- ->with([
- 'detail' => function ($query) {
- $query->where(['status' => StatusEnum::ENABLED]);
- }
- ])
- ->asArray()
- ->one();
- if (empty($order) || empty($order['detail'])) {
- throw new \RuntimeException('订单不存在');
- }
- if (
- OrderModifyShippingAddressLog::find()
- ->where(['mall_id' => $mallId, 'order_id' => $orderId, 'status' => [StatusEnum::DISABLED, StatusEnum::ENABLED]])
- ->count()
- ) {
- throw new \RuntimeException('当前订单已修改过收货地址');
- }
- if (!in_array($order['order_status'], [OrderStatusEnum::NOT_PAY, OrderStatusEnum::PAY]) || $order['shipping_type'] == ShippingTypeEnum::PICKUP) {
- throw new \RuntimeException('当前订单不允许修改地址');
- }
- // 验证,只要有一件已经发货就不能修改地址了
- $isSend = false;
- foreach ($order['detail'] as $detailItem) {
- if ($detailItem['order_status'] >= OrderStatusEnum::SHIPMENTS && $detailItem['order_status'] <= OrderStatusEnum::ACCOMPLISH) {
- $isSend = true;
- break;
- }
- }
- if ($isSend) {
- throw new \RuntimeException('当前订单不允许修改地址');
- }
- // 排除售后成功的订单
- foreach ($order['detail'] as $key => $detailItem) {
- if ($detailItem['is_feedback'] == OrderStatusEnum::FEEDBACKED) {
- unset($order['detail'][$key]);
- }
- }
- if (empty($order['detail'])) {
- throw new \RuntimeException('当前订单不允许修改地址');
- }
- // 初始化订单
- $orderFormLogic = new OrderFormLogic();
- $form = $orderFormLogic->getDefaultform($mallId, $userId);
- $freightAttr = [];
- foreach ($order['detail'] as $detail) {
- $freightAttr[] = ['attr_id' => $detail['goods_attr_id'], 'num' => $detail['num']];
- }
- if (empty($freightAttr)) {
- throw new \RuntimeException('当前订单不允许修改地址');
- }
- $form->attributes = [
- 'type' => PreviewTypeEnum::FREIGHT,
- 'data' => [
- 'shipping_type' => $order['shipping_type'],
- 'freight_attr' => $freightAttr,
- 'address_id' => $addressId
- ]
- ];
- $form['action'] = AppEnum::ACTION_CREATE;
- // 初始化订单数据
- $orderInitDataLogic = new OrderInitDataLogic();
- $form = $orderInitDataLogic->execute($form, $form->type);
- if ($form === false) throw new \RuntimeException($orderInitDataLogic->getError());
- // 验证新的区域是否允许购买
- try {
- $this->compute($form);
- }catch (Exception $e) {
- throw new \RuntimeException($e->getMessage());
- }
- /* 验证邮费,如果新地址需要给的邮费比下单时候的邮费高则不允许修改 */
- // 营销减免活动
- $orderMarketingLogic = new OrderMarketingLogic();
- $form = $orderMarketingLogic->run($form, true);
- if ($form === false) throw new \RuntimeException($orderMarketingLogic->getError());
- if (empty($form['group_order_goods']) || !is_array($form['group_order_goods'])) {
- throw new \RuntimeException('订单错误,修改失败');
- }
- // 因为修改地址只有一个订单修改,不会返回多条数据,所以使用reset拿第一个
- $goodsOrderGoods = reset($form['group_order_goods']);
- if (empty($goodsOrderGoods['mch_order_info'])) {
- throw new \RuntimeException('订单错误,修改失败');
- }
- $mchOrderInfo = $goodsOrderGoods['mch_order_info'];
- if (
- !isset($form['marketing']['deduct']['shipping_fee']['money']) ||
- !is_numeric($form['marketing']['deduct']['shipping_fee']['money'])
- ) {
- throw new \RuntimeException('订单错误,修改失败');
- }
- // 新地址邮费大于原地址
- if (bccomp($form['marketing']['deduct']['shipping_fee']['money'], $order['shipping_money'], 2) > 0) {
- throw new \RuntimeException('当前地址运费超过原地址运费,不允许修改');
- }
- // 执行修改
- \common\models\order\Order::changeAddress([
- 'id' => $orderId,
- 'mall_id' => $mallId,
- 'province' => $mchOrderInfo['province'],
- 'city' => $mchOrderInfo['city'],
- 'area' => $mchOrderInfo['area'],
- 'town' => $mchOrderInfo['town'],
- 'community' => $mchOrderInfo['community'],
- 'region_name' => $mchOrderInfo['region_name'],
- 'address' => $mchOrderInfo['address'],
- 'receiver_name' => $mchOrderInfo['receiver_name'],
- 'mobile' => $mchOrderInfo['mobile'],
- 'updated_at' => time()
- ]);
- OrderModifyShippingAddressLog::setData([
- 'order_id' => $orderId,
- 'mall_id' => $mallId
- ]);
- }
- /**
- * 验证区域是否能购买
- *
- * @param $form
- *
- * @return mixed
- * @throws Exception
- */
- public function compute($form)
- {
- // 如果是预约类型的订单那么不做判断
- if ($form->type == PreviewTypeEnum::RESERVE_NOW) return $form;
- $district_id = 0;
- $town_id = 0;
- if ($form->address_id == 0) {
- $where[] = ['user_id' => $form['user_id'], 'status' => 1, 'is_default' => 1];
- /**
- * @var $user_address UserAddress
- */
- $user_address = UserAddress::getOne($where, false, [], false, 'district_id, town_id');
- if (empty($user_address)) {
- $where1[] = ['user_id' => $form['user_id'], 'status' => 1];
- $user_address = UserAddress::getOne($where1, false, [], false, 'district_id, town_id');
- }
- } else {
- $where2[] = ['id' => $form->address_id, 'status' => 1];
- $user_address = UserAddress::getOne($where2, false, [], false, 'district_id, town_id');
- }
- $is_area_limit_town = \Yii::$app->services->setting->mall->get($form['mall_id'], 'area.is_area_limit_town');
- foreach ($form->sku as $item) {
- if ($item['goods']['is_area_limit'] == 1) {
- $area_limit = Json::decode($item['goods']['area_limit']);
- $address_ids = [];
- if(!empty($area_limit)&&is_array($area_limit)){
- $address_ids = array_column($area_limit, 'id');
- }
- if (!empty($user_address)) {
- $district_id = $user_address->district_id;
- $town_id = $user_address->town_id;
- }
- // 如果区县/乡镇有其中一个满足条件的话那么就需要抛出异常
- if (empty($is_area_limit_town)) {
- if ((!empty($district_id) && !in_array($district_id, $address_ids))) {
- throw new Exception('当前收货地址不允许购买');
- }
- } else if (!empty($town_id) && !in_array("_$town_id", $address_ids)) {
- throw new Exception('当前收货地址不允许购买!');
- }
- }else{
- $is_area_limit = \Yii::$app->services->setting->mall->get($form['mall_id'], 'area.is_area_limit');
- //创建订单时在判断限购局域
- if($is_area_limit && $is_area_limit==1 && $item['goods']['goods_type'] != GoodsTypeEnum::GoodsTypeVirtual && $form->action == 'create_order'){ //虚拟商品部限制
- $config = \Yii::$app->services->setting->mall->get($form['mall_id'], 'area.area_limit');
- $common_address_ids = [];
- if ($config) {
- $config = \Qiniu\json_decode($config, true);
- $common_address_ids = array_column($config, 'id');
- }
- // var_dump($district_id,$form->address_id,$user_address->district_id,$common_address_ids);die;
- if (!empty($common_address_ids)) {
- // 是否仅限制第三级
- if (empty($is_area_limit_town)) {
- if ($district_id != 0) {
- if (!in_array($district_id, $common_address_ids)) {
- throw new Exception('全局配置设置,当前收货地址不允许购买,请把默认收货地址设置成允许收货地址的局域');
- }
- }else if($user_address->district_id){
- if (!in_array($user_address->district_id, $common_address_ids)) {
- throw new Exception('全局配置设置,当前收货地址不允许购买,请把默认收货地址设置成允许收货地址的局域');
- }
- }
- } else {
- if ($town_id != 0) {
- if (!in_array("_$town_id", $common_address_ids))
- throw new Exception('全局配置设置,当前收货地址不允许购买,请把默认收货地址设置成允许收货地址的局域!');
- } elseif (!empty($user_address->town_id)) {
- if (!in_array("_$user_address->town_id", $common_address_ids)) {
- throw new Exception('全局配置设置,当前收货地址不允许购买,请把默认收货地址设置成允许收货地址的局域!');
- }
- }
- }
- }
- }
- }
- }
- return $form;
- }
- /**
- * 获取订单的收货地址
- *
- * @param int $userId
- * @param int $mallId
- * @param int $orderId
- *
- * @return array
- */
- public function getOrderDeliveryAddress(int $userId, int $mallId, int $orderId): array
- {
- return \common\models\order\Order::find()
- ->where(['user_id' => $userId, 'mall_id' => $mallId, 'id' => $orderId])
- ->select('address, region_name, mobile, receiver_name')
- ->asArray()
- ->one();
- }
- }
|