AfterSaleController.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <?php
  2. namespace addons\TinyShop\merchant\modules\order\controllers;
  3. use Yii;
  4. use yii\web\NotFoundHttpException;
  5. use common\models\base\SearchModel;
  6. use common\forms\CreditsLogForm;
  7. use common\enums\StatusEnum;
  8. use common\enums\PayTypeEnum;
  9. use common\helpers\BcHelper;
  10. use common\helpers\StringHelper;
  11. use common\helpers\ResultHelper;
  12. use addons\TinyShop\common\models\order\AfterSale;
  13. use addons\TinyShop\common\forms\OrderAfterSaleForm;
  14. use addons\TinyShop\common\models\order\Order;
  15. use addons\TinyShop\common\enums\RefundStatusEnum;
  16. use addons\TinyShop\merchant\controllers\BaseController;
  17. use addons\TinyShop\common\enums\SubscriptionActionEnum;
  18. use addons\TinyShop\common\models\order\OrderProduct;
  19. use yii\web\UnprocessableEntityHttpException;
  20. /**
  21. * 售后
  22. *
  23. * Class AfterSaleController
  24. * @package addons\TinyShop\merchant\modules\order\controllers
  25. * @author jianyan74 <751393839@qq.com>
  26. */
  27. class AfterSaleController extends BaseController
  28. {
  29. /**
  30. * 首页
  31. *
  32. * @return string
  33. * @throws \yii\web\NotFoundHttpException
  34. */
  35. public function actionIndex()
  36. {
  37. $afterSale = Yii::$app->request->get('after_sale', StatusEnum::DISABLED);
  38. $condition = ['in', 'refund_status', RefundStatusEnum::refund()];
  39. if ($afterSale == StatusEnum::ENABLED) {
  40. $condition = [
  41. 'in',
  42. 'refund_status',
  43. [
  44. 0,
  45. RefundStatusEnum::NO_PASS_ALWAYS,
  46. RefundStatusEnum::CANCEL,
  47. RefundStatusEnum::NO_PASS,
  48. RefundStatusEnum::MEMBER_AFFIRM,
  49. RefundStatusEnum::CONSENT
  50. ]
  51. ];
  52. }
  53. $searchModel = new SearchModel([
  54. 'model' => AfterSale::class,
  55. 'scenario' => 'default',
  56. 'partialMatchAttributes' => ['title'], // 模糊查询
  57. 'defaultOrder' => [
  58. 'id' => SORT_DESC,
  59. ],
  60. 'pageSize' => $this->pageSize,
  61. ]);
  62. $dataProvider = $searchModel
  63. ->search(Yii::$app->request->queryParams);
  64. $dataProvider->query
  65. ->andWhere(['>=', 'status', StatusEnum::DISABLED])
  66. ->andWhere($condition)
  67. ->andFilterWhere(['merchant_id' => $this->getMerchantId()]);
  68. return $this->render($this->action->id, [
  69. 'dataProvider' => $dataProvider,
  70. 'searchModel' => $searchModel,
  71. 'afterSale' => $afterSale,
  72. ]);
  73. }
  74. /**
  75. * 同意退款申请
  76. *
  77. * @return array
  78. */
  79. public function actionPass()
  80. {
  81. $id = Yii::$app->request->post('id');
  82. try {
  83. Yii::$app->tinyShopService->orderAfterSale->pass($id);
  84. return ResultHelper::json(200, '操作成功');
  85. } catch (\Exception $e) {
  86. return ResultHelper::json(422, $e->getMessage());
  87. }
  88. }
  89. /**
  90. * 拒绝退款申请
  91. *
  92. * @param $id
  93. * @param $always
  94. * @return array
  95. */
  96. public function actionRefuse()
  97. {
  98. $id = Yii::$app->request->post('id');
  99. $always = Yii::$app->request->post('always', false);
  100. try {
  101. Yii::$app->tinyShopService->orderAfterSale->refuse($id, $always);
  102. // 取消退款通知
  103. $afterSale = $this->findRefundModel($id);
  104. /** @var OrderProduct $orderProduct */
  105. $orderProduct = $afterSale->orderProduct;
  106. $orderProduct->product_name = StringHelper::textNewLine($orderProduct->product_name, 15, 1)[0]; // 内容过长无法通知
  107. Yii::$app->tinyShopService->notify->createRemindByReceiver(
  108. $afterSale->order_id,
  109. SubscriptionActionEnum::ORDER_RETURN_APPLY_CLOSE,
  110. $afterSale->buyer_id,
  111. [
  112. 'afterSale' => $afterSale,
  113. 'orderProduct' => $orderProduct,
  114. ]
  115. );
  116. return ResultHelper::json(200, '操作成功');
  117. } catch (\Exception $e) {
  118. return ResultHelper::json(422, $e->getMessage());
  119. }
  120. }
  121. /**
  122. * 确认收货
  123. *
  124. * @return array
  125. */
  126. public function actionTakeDelivery()
  127. {
  128. $id = Yii::$app->request->post('id');
  129. try {
  130. Yii::$app->tinyShopService->orderAfterSale->merchantTakeDelivery($id);
  131. return ResultHelper::json(200, '操作成功');
  132. } catch (\Exception $e) {
  133. return ResultHelper::json(422, $e->getMessage());
  134. }
  135. }
  136. /**
  137. * 发货
  138. *
  139. * @param $id
  140. * @return mixed|string
  141. * @throws \yii\base\ExitException
  142. */
  143. public function actionDeliver($id)
  144. {
  145. $model = Yii::$app->tinyShopService->orderAfterSale->findById($id);
  146. $order = Yii::$app->tinyShopService->order->findById($model->order_id);
  147. $this->activeFormValidate($model);
  148. if ($model->load(Yii::$app->request->post())) {
  149. // 事务
  150. $transaction = Yii::$app->db->beginTransaction();
  151. try {
  152. if (!($company = Yii::$app->tinyShopService->expressCompany->findById($model->merchant_express_company_id))) {
  153. throw new UnprocessableEntityHttpException('找不到物流公司');
  154. }
  155. $model->merchant_express_company = $company['title'];
  156. Yii::$app->tinyShopService->orderAfterSale->merchantDelivery($model);
  157. $transaction->commit();
  158. return $this->message('发货成功', $this->redirect(Yii::$app->request->referrer));
  159. } catch (\Exception $e) {
  160. $transaction->rollBack();
  161. return $this->message($e->getMessage(), $this->redirect(Yii::$app->request->referrer), 'error');
  162. }
  163. }
  164. $model->merchant_express_company_id = $order->express_company_id;
  165. return $this->renderAjax($this->action->id, [
  166. 'model' => $model,
  167. 'order' => $order,
  168. 'company' => Yii::$app->tinyShopService->expressCompany->getMapList()
  169. ]);
  170. }
  171. /**
  172. * 物流状态
  173. *
  174. * @param $id
  175. * @return string
  176. */
  177. public function actionCompany($id, $is_merchant = false)
  178. {
  179. $model = $this->findRefundModel($id);
  180. if ($is_merchant == true) {
  181. $trace = Yii::$app->services->extendLogistics->query($model->merchant_express_no, $model->merchant_express_company, $model->merchant_express_mobile);
  182. } else {
  183. $trace = Yii::$app->services->extendLogistics->query($model->member_express_no, $model->member_express_company, $model->member_express_mobile);
  184. }
  185. return $this->renderAjax($this->action->id, [
  186. 'trace' => $trace,
  187. ]);
  188. }
  189. /**
  190. * 确认退款
  191. *
  192. * @param $id
  193. * @return mixed|string
  194. * @throws NotFoundHttpException
  195. */
  196. public function actionAffirmReturn($id)
  197. {
  198. $model = $this->findRefundModel($id);
  199. $model->setScenario('affirmRefund');
  200. // 申请默认退款金额
  201. $model->refund_money = $model->refund_apply_money;
  202. /** @var Order $order */
  203. $order = $model->order;
  204. $refundTypes = [
  205. PayTypeEnum::ON_LINE => '线下',
  206. PayTypeEnum::USER_MONEY => '余额',
  207. ];
  208. // 线上支付
  209. $thirdParty = PayTypeEnum::thirdParty();
  210. in_array($order->pay_type, array_keys($thirdParty)) && $refundTypes[$order->pay_type] = $thirdParty[$order->pay_type];
  211. // 判断默认值
  212. in_array($order->pay_type, array_keys($refundTypes)) && $model->refund_pay_type = $order->pay_type;
  213. // 退款上限
  214. $maxRefundMoney = BcHelper::sub($order->pay_money, $order->refund_money);
  215. // ajax 校验
  216. $this->activeFormValidate($model);
  217. if ($model->load(Yii::$app->request->post())) {
  218. // 开启事务
  219. $transaction = Yii::$app->db->beginTransaction();
  220. try {
  221. // 退款进订单
  222. $model->refund_money > $maxRefundMoney && $model->refund_money = $maxRefundMoney;
  223. $afterSale = Yii::$app->tinyShopService->orderAfterSale->returnMoney($id, $model->refund_money);
  224. if ($model->refund_pay_type == PayTypeEnum::USER_MONEY) {
  225. // 退款进用户余额/原路退回
  226. Yii::$app->services->memberCreditsLog->incrMoney(new CreditsLogForm([
  227. 'member' => Yii::$app->services->member->get($model->buyer_id),
  228. 'num' => $afterSale->refund_money,
  229. 'group' => 'orderRefund',
  230. 'map_id' => $afterSale->id,
  231. 'remark' => '订单退款-' . $order->order_sn,
  232. ]));
  233. } elseif (in_array($model->refund_pay_type, array_keys($thirdParty))) {
  234. Yii::$app->services->extendPay->refund($model->refund_pay_type, $model->refund_money, $order->order_sn);
  235. }
  236. // 自动触发计算订单状态
  237. Yii::$app->tinyShopService->order->autoUpdateStatus($order->id);
  238. // 处理判断售后状态
  239. Yii::$app->tinyShopService->order->autoUpdateAfterSale($order->id);
  240. // 确认退款通知
  241. /** @var OrderProduct $orderProduct */
  242. $orderProduct = $afterSale->orderProduct;
  243. $orderProduct->product_name = StringHelper::textNewLine($orderProduct->product_name, 15, 1)[0]; // 内容过长无法通知
  244. Yii::$app->tinyShopService->notify->createRemindByReceiver(
  245. $afterSale->order_id,
  246. SubscriptionActionEnum::ORDER_RETURN_MONEY,
  247. $afterSale->buyer_id,
  248. [
  249. 'afterSale' => $afterSale,
  250. 'orderProduct' => $orderProduct,
  251. ]
  252. );
  253. $transaction->commit();
  254. return $this->message('操作成功', $this->redirect(Yii::$app->request->referrer));
  255. } catch (\Exception $e) {
  256. $transaction->rollBack();
  257. return $this->message($e->getMessage(), $this->redirect(Yii::$app->request->referrer), 'error');
  258. }
  259. }
  260. return $this->renderAjax($this->action->id, [
  261. 'model' => $model,
  262. 'order' => $order,
  263. 'orderProduct' => $model->orderProduct,
  264. 'refundTypes' => $refundTypes,
  265. 'maxRefundMoney' => $maxRefundMoney,
  266. ]);
  267. }
  268. /**
  269. * @param $id
  270. * @return string
  271. */
  272. public function actionDetail($id)
  273. {
  274. $model = Yii::$app->tinyShopService->orderAfterSale->findById($id);
  275. return $this->render($this->action->id, [
  276. 'model' => $model,
  277. 'orderAction' => Yii::$app->services->actionLog->findByBehavior('orderAfterSale', $id, 'TinyShop'),
  278. ]);
  279. }
  280. /**
  281. * @param $id
  282. * @return OrderAfterSaleForm|\yii\db\ActiveRecord
  283. * @throws NotFoundHttpException
  284. */
  285. public function findRefundModel($id)
  286. {
  287. /* @var $model OrderAfterSaleForm */
  288. if (empty($id) || !($model = OrderAfterSaleForm::find()->where([
  289. 'id' => $id,
  290. 'status' => StatusEnum::ENABLED,
  291. ])->andFilterWhere(['merchant_id' => $this->getMerchantId()])->one())) {
  292. throw new NotFoundHttpException('请求的数据不存在');
  293. }
  294. return $model;
  295. }
  296. }
粤ICP备19079148号