$mall_id], ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]] ]; if (!empty($params['refund_no'])) { $where[] = ['like', 'refund_no', $params['refund_no']]; } if (!empty($params['order_no'])) { $where[] = ['like', 'order_no', $params['order_no']]; } if (!empty($params['third_refund_no'])) { $where[] = ['like', 'third_order_no', $params['third_refund_no']]; } if (!empty($params['third_refund_id'])) { $where[] = ['like', 'third_refund_id', $params['third_refund_id']]; } $ret = QiShangTongRefund::listPage([ 'where' => $where, 'order' => 'id desc', 'limit' => $params['limit'] ?? '', 'with' => ['refund' => function($query) { $query->with(['orderDetail']); }] ]); if (!empty(QiShangTongRefund::getStaticError())) return QiShangTongRefund::getStaticError(); return $ret; } /** * @param array $refund * @return true * @throws \Exception */ public function create(array $refund) { // 只有退货退款/换货维修才需要过来这里? // 未收到货的无需处理 $aOrder = QiShangTongOrder::findOne(['order_id' => $refund['order_id']]); if (empty($aOrder)) return true; if (in_array($refund['order_detail_id'], $aOrder->order_detail_ids)) { // 可以执行退款操作 $model = new QiShangTongRefund(); $model->mall_id = $refund['mall_id']; $model->order_id = $aOrder->order_id; $model->order_no = $aOrder->order_no; $model->refund_id = $refund['id']; $model->refund_no = $refund['order_no']; $model->third_order_no = $aOrder->third_order_no; $model->order_detail_id = $refund['order_detail_id']; $model->user_id = $refund['user_id']; if (!$model->save()) throw new \Exception($model->getErrorMessage()); } return true; } /** * 同步 * @param int $mall_id * @param int $id * @return string|true */ public function async(int $mall_id, int $id) { // 执行同步 $aRefund = QiShangTongRefund::findOne(['id' => $id, 'mall_id' => $mall_id]); if (empty($aRefund)) return true; try { $refund = OrderRefund::findOne(['id' => $aRefund->refund_id]); $order = Order::findOne(['id' => $aRefund->order_id]); $detail = OrderDetail::findOne(['id' => $aRefund->order_detail_id]); $aGoods = QiShangTongGoods::findOne(['goods_id' => $detail->goods_id]); $aOrder = QiShangTongOrder::findOne(['order_id' => $order->id]); $contentModel = new RefundCreateModel(); $specItem = QiShangTongGoodsAttr::findOne(['goods_attr_id' => $detail->goods_attr_id]); $order_sn_map = array_column($aOrder->content['create']['goods'], "order_sn", "spec_id"); $next_req = true; if ($refund->type != RefundTypeEnum::MONEY) { $rContentModel = new RefundReasonListModel(); $rContentModel->order_sn = $order_sn_map[$specItem->third_spec_id]; // 订单创建时返回的order_sn 在goods里面的单号 $rContentModel->apply_type = $refund->type; // 售后类型 1退款 2退货 3换货 $res = RequestHelper::send(new RefundReasonListRequest(), $rContentModel, $mall_id); $aRefund->req_success = 100; if (!is_array($res)) { // throw new \Exception($rRes); $aRefund->req_success = StatusEnum::ENABLED; $next_req = false; } } if ($next_req) { $contentModel->goods_id = $aGoods->third_goods_id; // 商品ID $contentModel->spec_id = $specItem->third_spec_id; // 商品规格ID $contentModel->order_sn = $order_sn_map[$specItem->third_spec_id]; // 客户平台订单单号 $contentModel->apply_type = $refund->type; // 售后类型 1退款 2退货 3换货 $contentModel->apply_num = $detail->num; // 售后数量 $contentModel->image = $refund->pic_list; // 售后图片 $contentModel->video = ""; // 售后视频 // 售后原因(可通过售后原因列表获取) 售后原因列表的type的值 退款情况下传0即可 $contentModel->apply_case = $refund->type == RefundTypeEnum::MONEY ? StatusEnum::DISABLED : $res[0]['type'] ?? 0; $contentModel->send_back_name = $order->receiver_name; // 联系人姓名 $contentModel->send_back_phone = $order->mobile; // 联系人电话 $contentModel->caused = $refund->type == RefundTypeEnum::MONEY ? '' : $refund->reason; // 售后理由 原因列表的type_txt的值 退款情况下传空即可 $contentModel->order_parent_sn = $aOrder->third_order_no; // 支付单号 $res = RequestHelper::send(new RefundCreateRequest(), $contentModel, $mall_id); $aRefund->req_success = 100; if (!is_array($res)) { // throw new \Exception($res); $aRefund->req_success = StatusEnum::ENABLED; } else { $aRefund->third_refund_id = $res['apply_sn'] ?? ''; } } // 更新数据 $aRefund->post = ['create' => $contentModel->toArray()]; $aRefund->content = ['create' => $res ?? []]; $aRefund->last_req = 'async'; $aRefund->last_resp = var_export($res ?? [], true); if (!$aRefund->save()) throw new \Exception($aRefund->getErrorMessage()); } catch (\Exception $e) { \Yii::error(FormatHelper::exception($e, __METHOD__)); return $e->getMessage(); } return true; } /** * 取消售后 * @param array $refund * @return true * @throws \Exception */ public function cancel(array $refund) { // 执行同步 $mall_id = $refund['mall_id']; $aRefund = QiShangTongRefund::findOne(['id' => $refund['id'], 'mall_id' => $mall_id]); if (empty($aRefund)) return true; $contentModel = new RefundCancelModel(); $contentModel->apply_sn = $aRefund->third_refund_id; $res = RequestHelper::send(new RefundCancelRequest(), $contentModel, $mall_id); $aRefund->req_success = 100; if (!is_array($res)) { // throw new \Exception($res); $aRefund->req_success = StatusEnum::ENABLED; } else { $aRefund->refund_status = RefundStatusEnum::REVOKE; } // 更新数据 $aRefund->post = array_merge($aRefund->post, ['cancel' => $contentModel->toArray()]); $aRefund->content = array_merge($aRefund->content, ['cancel' => $res]); $aRefund->third_refund_id = $res['apply_sn']; $aRefund->last_resp = var_export($res, true); $aRefund->last_req = 'cancel'; if (!$aRefund->save()) throw new \Exception($aRefund->getErrorMessage()); return true; } public function task() { foreach (QiShangTongRefund::find()->select('id, mall_id')->where(['refund_status' => [0, 1, 2]])->each() as $item) { $data = [ 'mall_id' => $item->mall_id, 'id' => $item->id ]; \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_ORDER, RabbitMqEnum::ORDER_QUEUE, $data, self::class, 'taskSync'); // $this->taskSync($data); } } /** * 更新退款状态 * @param QiShangTongEvent $event * @return true * @throws \Exception */ public function eventUpdate(QiShangTongEvent &$event) { $t = Yii::$app->db->beginTransaction(); try { $aRefund = QiShangTongRefund::findOne(['third_refund_id' => $event->content['apply_sn']]); if (empty($aRefund)) throw new \Exception("退款记录不存在"); $event->mall_id = $aRefund->mall_id; $is_update = true; switch ($event->content['process_step']) { case 1: // $step_status = RefundStatusEnum::REFUSE; // 驳回 break; case 2: /** * address_type: 1 consignee: 林锦豪 mobile: 13246824705 address: 广州市白云区永平街永泰学山塘街81号A2栋618 express_id: saler_express: saler_express_no: customer_name: id: 377 step_status: 8 */ //去企叮咚第三方详情 // 退货退款 2 // 换货 8 $refund = OrderRefund::findOne(['id' => $aRefund->refund_id]); // 确认收货并退款 $step_status = $refund->type == RefundTypeEnum::MONEY_AND_PRODUCT ? RefundStatusEnum::STEP_2 : RefundStatusEnum::STEP_8; $contentModel = new RefundDetailModel(); $contentModel->apply_sn = $aRefund->third_refund_id; $res = RequestHelper::send(new RefundDetailRequest(), $contentModel, $aRefund->mall_id); $aRefund->req_success = 100; $aRefund->last_resp = var_export($res, true); // $aRefund->last_req = ''; if (!is_array($res)) { // throw new \Exception($res); $aRefund->req_success = StatusEnum::ENABLED; $is_update = false; } else { $address = $res['consignee_address']; $mobile = $res['consignee_phone']; $consignee = $res['consignee_name']; } // 需要完善物流信息 break; case 3: // $step_status = RefundStatusEnum::REVOKE; $params['mall_id'] = $aRefund->mall_id; $params['user_id'] = $aRefund->user_id; $params['id'] = $aRefund->refund_id; $res = OrderRefund::cancelRefund($params); if (!$res) throw new \Exception($res); // 取消 break; case 4: $refund = OrderRefund::findOne(['id' => $aRefund->refund_id]); $step_status = $refund->type == RefundTypeEnum::MONEY ? RefundStatusEnum::STEP_6 : RefundStatusEnum::STEP_4; $aRefund->refund_status = RefundStatusEnum::FINISH; // 完成 break; } if (!$aRefund->save()) throw new \Exception($aRefund->getErrorMessage()); if ($is_update) { if (empty($step_status)) throw new \Exception("未匹配到退款步骤"); // 退货地址 $address = ['consignee' => $consignee ?? '','mobile' => $mobile ?? '','address' => $address ?? '']; // 换货物流信息 $express = ['saler_express' => '','saler_express_no' => '','customer_name' => '']; $data = [ 'id' => $aRefund->refund_id, 'step_status' => $step_status, 'address' => $address, 'express' => $express, 'refund_reason' => '', ]; $logic = new OrderRefundLogic(); $res = $logic->execute($event->mall_id, $data); if (!$res) throw new \Exception($logic->getError()); } $t->commit(); } catch (\Exception $e) { $t->rollBack(); throw new \Exception($e->getMessage()); } return true; } /** * 拒绝售后 * @param int $mall_id * @param int $id * @return string|true */ public function reject(int $mall_id, int $id, array $otherData = []) { $aRefund = QiShangTongRefund::findOne(['id' => $id, 'mall_id' => $mall_id]); if (empty($aRefund)) return '售后记录不存在'; // 退货地址 $address = ['consignee' => '','mobile' => '','address' => '']; // 换货物流信息 $express = ['saler_express' => '','saler_express_no' => '','customer_name' => '']; $data = [ 'id' => $aRefund->refund_id, 'step_status' => RefundStatusEnum::REFUSE, 'address' => $address, 'express' => $express, 'refund_reason' => '暂无拒绝理由', 'is_admin' => $otherData['is_admin'] ?? 0, 'operator_id' => $otherData['operator_id'] ?? 0, ]; $logic = new OrderRefundLogic(); $res = $logic->execute($mall_id, $data); if (!$res) return $logic->getError(); // 执行拒绝动作 return true; } public function compensate(int $mall_id, $id) { $aRefund = QiShangTongRefund::findOne(['id' => $id, 'mall_id' => $mall_id]); if (empty($aRefund)) return '售后记录不存在'; if ($aRefund->req_success == 100) return '当前状态无效补偿'; try { switch ($aRefund->last_req) { case 'cancel': $refund = OrderRefund::getOne([ ['id' => $aRefund->refund_id] ], true, ['orderDetail', 'base_user', 'order']); return $this->cancel($refund); case 'async': return $this->async($aRefund->mall_id, $aRefund->id); case 'buyerShip': $refund = OrderRefund::getOne([ ['id' => $aRefund->refund_id] ], true, ['orderDetail', 'base_user', 'order']); return $this->buyerShip($refund); } } catch (\Exception $e) { return $e->getMessage(); } return true; } /** * @param array $refund * @return true * @throws \Exception */ public function buyerShip(array $refund) { $aRefund = QiShangTongRefund::findOne(['refund_id' => $refund['id'], 'mall_id' => $refund['mall_id']]); if (empty($aRefund)) { return true; } // 存在 那么就需要邮寄过去 $contentModel = new RefundDetailModel(); $contentModel->apply_sn = $aRefund->third_refund_id; $res = RequestHelper::send(new RefundDetailRequest(), $contentModel, $aRefund->mall_id); $aRefund->last_resp = var_export($res, true); $aRefund->last_req = 'buyerShip'; $aRefund->req_success = 100; if (!is_array($res)) { $aRefund->req_success = 1; } else { // 处理 if ($res['status'] == 7 && $res['is_send_back'] == StatusEnum::ENABLED) { $order = Order::findOne(['id' => $refund['order_id']]); $contentModel = new RefundDeliveryModel(); $contentModel->apply_sn = $aRefund->third_refund_id; $contentModel->back_ship_name = $refund['express']; // 快递名称 $contentModel->back_ship_sn = $refund['express_no']; // 快递单号 $contentModel->back_ship_image = $refund['pic_list']; // 快递凭证 $contentModel->send_back_name = $order->receiver_name; // 寄回人姓名 $contentModel->send_back_phone = $order->mobile; // 寄回人电话 $contentModel->back_ship_notes = '这边系统无需上传快递凭证'; $res = RequestHelper::send(new RefundDeliveryRequest(), $contentModel, $aRefund->mall_id); $aRefund->last_resp = var_export($res, true); if (!is_array($res)) { $aRefund->req_success = 1; } } } $aRefund->save(); return true; } }