StoreOrderRefundServices.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\services\order;
  12. use app\dao\order\StoreOrderDao;
  13. use app\jobs\notice\SmsJob;
  14. use app\services\activity\StoreAdvanceServices;
  15. use app\services\activity\StoreBargainServices;
  16. use app\services\activity\StoreCombinationServices;
  17. use app\services\activity\StorePinkServices;
  18. use app\services\activity\StoreSeckillServices;
  19. use app\services\BaseServices;
  20. use app\services\coupon\StoreCouponIssueUserServices;
  21. use app\services\coupon\StoreCouponUserServices;
  22. use app\services\message\notice\RoutineTemplateListService;
  23. use app\services\message\notice\WechatTemplateListService;
  24. use app\services\message\service\StoreServiceServices;
  25. use app\services\pay\PayServices;
  26. use app\services\product\product\StoreProductServices;
  27. use app\services\user\UserBillServices;
  28. use app\services\user\UserServices;
  29. use app\services\wechat\WechatUserServices;
  30. use crmeb\services\AliPayService;
  31. use crmeb\services\CacheService;
  32. use crmeb\services\FormBuilder as Form;
  33. use crmeb\services\MiniProgramService;
  34. use crmeb\services\WechatService;
  35. use crmeb\services\workerman\ChannelService;
  36. use crmeb\utils\Str;
  37. use think\exception\ValidateException;
  38. /**
  39. * 订单退款
  40. * Class StoreOrderRefundServices
  41. * @package app\services\order
  42. */
  43. class StoreOrderRefundServices extends BaseServices
  44. {
  45. /**
  46. * 构造方法
  47. * StoreOrderRefundServices constructor.
  48. * @param StoreOrderDao $dao
  49. */
  50. public function __construct(StoreOrderDao $dao)
  51. {
  52. $this->dao = $dao;
  53. }
  54. /**
  55. * 订单退款表单
  56. * @param int $id
  57. * @return array
  58. * @throws \FormBuilder\Exception\FormBuilderException
  59. */
  60. public function refundOrderForm(int $id)
  61. {
  62. $order = $this->dao->get($id);
  63. if (!$order) {
  64. throw new ValidateException('未查到订单');
  65. }
  66. if (!$order['paid']) {
  67. throw new ValidateException('未支付无法退款');
  68. }
  69. if ($order['pay_price'] > 0 && in_array($order['refund_status'], [0, 1])) {
  70. if ($order['pay_price'] <= $order['refund_price']) {
  71. throw new ValidateException('订单已退款');
  72. }
  73. }
  74. $f[] = Form::input('order_id', '退款单号', $order->getData('order_id'))->disabled(true);
  75. $f[] = Form::number('refund_price', '退款金额', (float)bcsub((string)$order->getData('pay_price'), (string)$order->getData('refund_price'), 2))->precision(2)->required('请输入退款金额');
  76. return create_form('退款处理', $f, $this->url('/order/refund/' . $id), 'PUT');
  77. }
  78. /**
  79. * 订单退款处理
  80. * @param int $type
  81. * @param $order
  82. * @param array $refundData
  83. * @return mixed
  84. */
  85. public function payOrderRefund(int $type, $order, array $refundData)
  86. {
  87. return $this->transaction(function () use ($type, $order, $refundData) {
  88. //回退积分和优惠卷
  89. if (!$this->integralAndCouponBack($order)) {
  90. throw new ValidateException('回退积分和优惠卷失败');
  91. }
  92. //虚拟商品优惠券退款处理
  93. if ($order['virtual_type'] == 2) {
  94. /** @var StoreCouponUserServices $couponUser */
  95. $couponUser = app()->make(StoreCouponUserServices::class);
  96. $res = $couponUser->delUserCoupon(['cid' => $order['virtual_info'], 'uid' => $order['uid'], 'status' => 0]);
  97. if (!$res) throw new ValidateException('购买的优惠券已使用或者已过期');
  98. /** @var StoreCouponIssueUserServices $couponIssueUser */
  99. $couponIssueUser = app()->make(StoreCouponIssueUserServices::class);
  100. $couponIssueUser->delIssueUserCoupon(['issue_coupon_id' => $order['virtual_info'], 'uid' => $order['uid']]);
  101. }
  102. //退拼团
  103. if ($type == 1) {
  104. /** @var StorePinkServices $pinkServices */
  105. $pinkServices = app()->make(StorePinkServices::class);
  106. if (!$pinkServices->setRefundPink($order)) {
  107. throw new ValidateException('拼团修改失败!');
  108. }
  109. }
  110. //退佣金
  111. /** @var UserBillServices $userBillServices */
  112. $userBillServices = app()->make(UserBillServices::class);
  113. if (!$userBillServices->orderRefundBrokerageBack($order['id'], $order['order_id'])) {
  114. throw new ValidateException('回退佣金失败');
  115. }
  116. //回退库存
  117. if ($order['status'] == 0) {
  118. /** @var StoreOrderStatusServices $services */
  119. $services = app()->make(StoreOrderStatusServices::class);
  120. if (!$services->count(['oid' => $order['id'], 'change_type' => 'refund_price'])) {
  121. $this->regressionStock($order);
  122. }
  123. }
  124. //退金额
  125. if ($refundData['refund_price'] > 0) {
  126. if (!isset($refundData['refund_id']) || !$refundData['refund_id']) {
  127. mt_srand();
  128. $refundData['refund_id'] = $order['order_id'] . rand(100, 999);
  129. }
  130. if ($order['pid'] > 0) {//子订单
  131. $refundOrder = $this->dao->get((int)$order['pid']);
  132. $refundData['pay_price'] = $refundOrder['pay_price'];
  133. } else {
  134. $refundOrder = $order;
  135. }
  136. switch ($refundOrder['pay_type']) {
  137. case PayServices::WEIXIN_PAY:
  138. $no = $refundOrder['order_id'];
  139. if ($refundOrder['trade_no']) {
  140. $no = $refundOrder['trade_no'];
  141. $refundData['type'] = 'trade_no';
  142. }
  143. if ($refundOrder['is_channel'] == 1) {
  144. //小程序退款
  145. MiniProgramService::payOrderRefund($no, $refundData);//小程序
  146. } else {
  147. //微信公众号退款
  148. WechatService::payOrderRefund($no, $refundData);//公众号
  149. }
  150. break;
  151. case PayServices::YUE_PAY:
  152. //余额退款
  153. if (!$this->yueRefund($refundOrder, $refundData)) {
  154. throw new ValidateException('余额退款失败');
  155. }
  156. break;
  157. case PayServices::ALIAPY_PAY:
  158. mt_srand();
  159. $refund_id = $refundData['refund_id'] ?? $refundOrder['order_id'] . rand(100, 999);
  160. //支付宝退款
  161. AliPayService::instance()->refund(strpos($refundOrder['trade_no'], '_') !== false ? $refundOrder['trade_no'] : $refundOrder['order_id'], floatval($refundData['refund_price']), $refund_id);
  162. break;
  163. }
  164. }
  165. /** @var UserServices $userServices */
  166. $userServices = app()->make(UserServices::class);
  167. $usermoney = $userServices->value(['uid' => $order['uid']], 'now_money');
  168. $userBillServices->income('pay_product_refund', $order['uid'], ['number' => $refundData['refund_price'], 'payType' => PayServices::PAY_TYPE[$order['pay_type']] ?? '未知'], bcadd((string)$usermoney, (string)$refundData['refund_price'], 2), $order['id']);
  169. //修改开票数据退款状态
  170. $orderInvoiceServices = app()->make(StoreOrderInvoiceServices::class);
  171. $orderInvoiceServices->update(['order_id' => $order['id']], ['is_refund' => 1]);
  172. });
  173. }
  174. /**
  175. * 余额退款
  176. * @param $order
  177. * @param array $refundData
  178. * @return bool
  179. */
  180. public function yueRefund($order, array $refundData)
  181. {
  182. /** @var UserServices $userServices */
  183. $userServices = app()->make(UserServices::class);
  184. $res = $userServices->bcInc($order['uid'], 'now_money', $refundData['refund_price'], 'uid');
  185. return $res ? true : false;
  186. }
  187. /**
  188. * 回退积分和优惠卷
  189. * @param $order
  190. * @return bool
  191. */
  192. public function integralAndCouponBack($order)
  193. {
  194. $res = true;
  195. //回退优惠卷
  196. if ($order['coupon_id'] && $order['coupon_price']) {
  197. /** @var StoreCouponUserServices $coumonUserServices */
  198. $coumonUserServices = app()->make(StoreCouponUserServices::class);
  199. $res = $res && $coumonUserServices->recoverCoupon((int)$order['coupon_id']);
  200. }
  201. //回退积分
  202. $order = $this->regressionIntegral($order);
  203. /** @var StoreOrderStatusServices $statusService */
  204. $statusService = app()->make(StoreOrderStatusServices::class);
  205. $statusService->save([
  206. 'oid' => $order['id'],
  207. 'change_type' => 'integral_back',
  208. 'change_message' => '商品退积分',
  209. 'change_time' => time()
  210. ]);
  211. return $res && $order->save();
  212. }
  213. /**
  214. * 回退使用积分和赠送积分
  215. * @param $order
  216. * @return bool
  217. */
  218. public function regressionIntegral($order)
  219. {
  220. /** @var UserServices $userServices */
  221. $userServices = app()->make(UserServices::class);
  222. $userInfo = $userServices->get($order['uid'], ['integral']);
  223. if (!$userInfo) {
  224. $order->back_integral = $order->use_integral;
  225. return $order;
  226. }
  227. $integral = $userInfo['integral'];
  228. if ($order['status'] == -2 || $order['is_del']) {
  229. return $order;
  230. }
  231. if ((int)$order['refund_status'] != 2 && $order['back_integral'] >= $order['use_integral']) {
  232. return $order;
  233. }
  234. $res1 = $res2 = $res3 = $res4 = true;
  235. //订单赠送积分
  236. /** @var UserBillServices $userBillServices */
  237. $userBillServices = app()->make(UserBillServices::class);
  238. $give_integral = $userBillServices->sum([
  239. 'category' => 'integral',
  240. 'type' => 'sign',
  241. 'link_id' => $order['id'],
  242. 'uid' => $order['uid']
  243. ], 'number');
  244. if ($give_integral) {
  245. //判断订单是否已经回退积分
  246. $count = $userBillServices->count(['category' => 'integral', 'type' => 'deduction', 'link_id' => $order['id']]);
  247. if (!$count) {
  248. $res1 = $userServices->bcDec($order['uid'], 'integral', $give_integral);
  249. //记录赠送积分收回
  250. $res2 = $userBillServices->income('integral_refund', $order['uid'], $give_integral, $integral, $order['id']);
  251. }
  252. }
  253. //返还下单使用积分
  254. $use_integral = $order['use_integral'];
  255. if ($use_integral > 0) {
  256. $res3 = $userServices->bcInc($order['uid'], 'integral', $use_integral);
  257. //记录下单使用积分还回
  258. $res4 = $userBillServices->income('pay_product_integral_back', $order['uid'], $use_integral, $integral, $order['id']);
  259. }
  260. if (!($res1 && $res2 && $res3 && $res4)) {
  261. throw new ValidateException('回退积分增加失败');
  262. }
  263. if ($use_integral > $give_integral) {
  264. $order->back_integral = bcsub($use_integral, $give_integral, 2);
  265. }
  266. return $order;
  267. }
  268. /**
  269. * 回退库存
  270. * @param $order
  271. * @return bool
  272. */
  273. public function regressionStock($order)
  274. {
  275. if ($order['status'] == -2 || $order['is_del']) return true;
  276. $combination_id = $order['combination_id'];
  277. $seckill_id = $order['seckill_id'];
  278. $bargain_id = $order['bargain_id'];
  279. $advance_id = $order['advance_id'];
  280. $res5 = true;
  281. /** @var StoreOrderCartInfoServices $cartServices */
  282. $cartServices = app()->make(StoreOrderCartInfoServices::class);
  283. /** @var StoreProductServices $services */
  284. $services = app()->make(StoreProductServices::class);
  285. /** @var StoreSeckillServices $seckillServices */
  286. $seckillServices = app()->make(StoreSeckillServices::class);
  287. /** @var StoreCombinationServices $pinkServices */
  288. $pinkServices = app()->make(StoreCombinationServices::class);
  289. /** @var StoreBargainServices $bargainServices */
  290. $bargainServices = app()->make(StoreBargainServices::class);
  291. /** @var StoreAdvanceServices $advanceServices */
  292. $advanceServices = app()->make(StoreAdvanceServices::class);
  293. $cartInfo = $cartServices->getCartInfoList(['cart_id' => $order['cart_id']], ['cart_info']);
  294. foreach ($cartInfo as $cart) {
  295. $cart['cart_info'] = is_array($cart['cart_info']) ? $cart['cart_info'] : json_decode($cart['cart_info'], true);
  296. //增库存减销量
  297. $unique = isset($cart['cart_info']['productInfo']['attrInfo']) ? $cart['cart_info']['productInfo']['attrInfo']['unique'] : '';
  298. $cart_num = (int)$cart['cart_info']['cart_num'];
  299. $type = 0;
  300. if ($combination_id) {
  301. $type = 3;
  302. $res5 = $res5 && $pinkServices->incCombinationStock($cart_num, (int)$combination_id, $unique);
  303. } else if ($seckill_id) {
  304. $type = 1;
  305. $res5 = $res5 && $seckillServices->incSeckillStock($cart_num, (int)$seckill_id, $unique);
  306. } else if ($bargain_id) {
  307. $type = 2;
  308. $res5 = $res5 && $bargainServices->incBargainStock($cart_num, (int)$bargain_id, $unique);
  309. } else if ($advance_id) {
  310. $type = 6;
  311. $res5 = $res5 && $advanceServices->incAdvanceStock($cart_num, (int)$advance_id, $unique);
  312. } else {
  313. $res5 = $res5 && $services->incProductStock($cart_num, (int)$cart['cart_info']['productInfo']['id'], $unique);
  314. }
  315. if ($type) CacheService::setStock($unique, $cart_num, $type, false);
  316. }
  317. return $res5;
  318. }
  319. /**
  320. * 同意退款成功发送模板消息和记录订单状态
  321. * @param $data
  322. * @param $order
  323. * @param $refund_price
  324. * @param $id
  325. */
  326. public function storeProductOrderRefundY($data, $order, $refund_price)
  327. {
  328. /** @var StoreOrderStatusServices $statusService */
  329. $statusService = app()->make(StoreOrderStatusServices::class);
  330. $statusService->save([
  331. 'oid' => $order['id'],
  332. 'change_type' => 'refund_price',
  333. 'change_message' => '退款给用户:' . $refund_price . '元',
  334. 'change_time' => time()
  335. ]);
  336. event('notice.notice', [['data' => $data, 'order' => $order], 'order_refund']);
  337. }
  338. /**
  339. * 同意退款退款失败写入订单记录
  340. * @param int $id
  341. * @param $refund_price
  342. */
  343. public function storeProductOrderRefundYFasle(int $id, $refund_price)
  344. {
  345. /** @var StoreOrderStatusServices $statusService */
  346. $statusService = app()->make(StoreOrderStatusServices::class);
  347. $statusService->save([
  348. 'oid' => $id,
  349. 'change_type' => 'refund_price',
  350. 'change_message' => '退款给用户:' . $refund_price . '元失败',
  351. 'change_time' => time()
  352. ]);
  353. }
  354. /**
  355. * 不退款记录订单变更状态
  356. * @param int $id
  357. * @param string $refundReason
  358. */
  359. public function storeProductOrderRefundNo(int $id, string $refundReason)
  360. {
  361. /** @var StoreOrderStatusServices $statusService */
  362. $statusService = app()->make(StoreOrderStatusServices::class);
  363. $statusService->save([
  364. 'oid' => $id,
  365. 'change_type' => 'refund_n',
  366. 'change_message' => '不退款原因:' . $refundReason,
  367. 'change_time' => time()
  368. ]);
  369. }
  370. /**
  371. * 不退款表单
  372. * @param int $id
  373. * @return array
  374. * @throws \FormBuilder\Exception\FormBuilderException
  375. */
  376. public function noRefundForm(int $id)
  377. {
  378. $order = $this->dao->get($id);
  379. if (!$order) {
  380. throw new ValidateException('Data does not exist!');
  381. }
  382. $f[] = Form::input('order_id', '不退款单号', $order->getData('order_id'))->disabled(true);
  383. $f[] = Form::input('refund_reason', '不退款原因')->type('textarea')->required('请填写不退款原因');
  384. return create_form('不退款原因', $f, $this->url('order/no_refund/' . $id), 'PUT');
  385. }
  386. /**
  387. * 退积分表单创建
  388. * @param int $id
  389. * @return array
  390. * @throws \FormBuilder\Exception\FormBuilderException
  391. */
  392. public function refundIntegralForm(int $id)
  393. {
  394. if (!$orderInfo = $this->dao->get($id))
  395. throw new ValidateException('订单不存在');
  396. if ($orderInfo->use_integral < 0 || $orderInfo->use_integral == $orderInfo->back_integral)
  397. throw new ValidateException('积分已退或者积分为零无法再退');
  398. if (!$orderInfo->paid)
  399. throw new ValidateException('未支付无法退积分');
  400. $f[] = Form::input('order_id', '退款单号', $orderInfo->getData('order_id'))->disabled(1);
  401. $f[] = Form::number('use_integral', '使用的积分', (float)$orderInfo->getData('use_integral'))->min(0)->disabled(1);
  402. $f[] = Form::number('use_integrals', '已退积分', (float)$orderInfo->getData('back_integral'))->min(0)->disabled(1);
  403. $f[] = Form::number('back_integral', '可退积分', (float)bcsub($orderInfo->getData('use_integral'), $orderInfo->getData('back_integral')))->min(0)->precision(0)->required('请输入可退积分');
  404. return create_form('退积分', $f, $this->url('/order/refund_integral/' . $id), 'PUT');
  405. }
  406. /**
  407. * 单独退积分处理
  408. * @param $orderInfo
  409. * @param $back_integral
  410. */
  411. public function refundIntegral($orderInfo, $back_integral)
  412. {
  413. /** @var UserServices $userServices */
  414. $userServices = app()->make(UserServices::class);
  415. $integral = $userServices->value(['uid' => $orderInfo['uid']], 'integral');
  416. return $this->transaction(function () use ($userServices, $orderInfo, $back_integral, $integral) {
  417. $res1 = $userServices->bcInc($orderInfo['uid'], 'integral', $back_integral, 'uid');
  418. /** @var UserBillServices $userBillServices */
  419. $userBillServices = app()->make(UserBillServices::class);
  420. $res2 = $userBillServices->income('pay_product_integral_back', $orderInfo['uid'], $back_integral, $integral + $back_integral, $orderInfo['id']);
  421. /** @var StoreOrderStatusServices $statusService */
  422. $statusService = app()->make(StoreOrderStatusServices::class);
  423. $res3 = $statusService->save([
  424. 'oid' => $orderInfo['id'],
  425. 'change_type' => 'integral_back',
  426. 'change_message' => '商品退积分:' . $back_integral,
  427. 'change_time' => time()
  428. ]);
  429. $res4 = $orderInfo->save();
  430. $res = $res1 && $res2 && $res3 && $res4;
  431. if (!$res) {
  432. throw new ValidateException('订单退积分失败');
  433. }
  434. return true;
  435. });
  436. }
  437. /**
  438. * 订单申请退款
  439. * @param $uni
  440. * @param $uid
  441. * @param string $refundReasonWap
  442. * @param string $refundReasonWapExplain
  443. * @param array $refundReasonWapImg
  444. * @return bool|void
  445. */
  446. public function orderApplyRefund($order, string $refundReasonWap = '', string $refundReasonWapExplain = '', array $refundReasonWapImg = [], int $refundType = 0, $cart_id = 0, $refund_num = 0)
  447. {
  448. if (!$order) {
  449. throw new ValidateException('支付订单不存在!');
  450. }
  451. if ($order['refund_status'] == 2) {
  452. throw new ValidateException('订单已退款!');
  453. }
  454. if ($order['refund_status'] == 1) {
  455. throw new ValidateException('正在申请退款中!');
  456. }
  457. if ($order['total_num'] < $refund_num) {
  458. throw new ValidateException('退款件数大于订单件数!');
  459. }
  460. $this->transaction(function () use ($order, $refundReasonWap, $refundReasonWapExplain, $refundReasonWapImg, $refundType, $refund_num, $cart_id) {
  461. $status = 0;
  462. $order_id = (int)$order['id'];
  463. if ($cart_id) {
  464. /** @var StoreOrderCartInfoServices $storeOrderCartInfoServices */
  465. $storeOrderCartInfoServices = app()->make(StoreOrderCartInfoServices::class);
  466. $cart_ids = [];
  467. $cart_ids[0] = ['cart_id' => $cart_id, 'cart_num' => $refund_num];
  468. /** @var StoreOrderSplitServices $storeOrderSplitServices */
  469. $storeOrderSplitServices = app()->make(StoreOrderSplitServices::class);
  470. //拆单
  471. $order = $storeOrderSplitServices->split($order_id, $cart_ids, $order);
  472. $status = 1;
  473. } elseif (in_array($order['pid'], [0, -1]) && $this->dao->count(['pid' => $order_id])) {
  474. /** @var StoreOrderCartInfoServices $storeOrderCartInfoServices */
  475. $storeOrderCartInfoServices = app()->make(StoreOrderCartInfoServices::class);
  476. $cart_info = $storeOrderCartInfoServices->getSplitCartList($order_id, 'cart_info');
  477. if (!$cart_info) {
  478. throw new ValidateException('该订单已全部拆分发货,请去自订单申请');
  479. }
  480. $cart_ids = [];
  481. foreach ($cart_info as $key => $cart) {
  482. $cart_ids[$key] = ['cart_id' => $cart['id'], 'cart_num' => $refund_num];
  483. }
  484. /** @var StoreOrderSplitServices $storeOrderSplitServices */
  485. $storeOrderSplitServices = app()->make(StoreOrderSplitServices::class);
  486. //拆单
  487. $order = $storeOrderSplitServices->split($order_id, $cart_ids, $order);
  488. $status = 1;
  489. }
  490. $data = [
  491. 'refund_status' => 1,
  492. 'refund_reason_time' => time(),
  493. 'refund_reason_wap' => $refundReasonWap,
  494. 'refund_reason_wap_explain' => $refundReasonWapExplain,
  495. 'refund_reason_wap_img' => json_encode($refundReasonWapImg),
  496. 'refund_type' => $refundType
  497. ];
  498. if ($status) $data['status'] = $status;
  499. /** @var StoreOrderStatusServices $statusService */
  500. $statusService = app()->make(StoreOrderStatusServices::class);
  501. $res1 = false !== $statusService->save([
  502. 'oid' => $order['id'],
  503. 'change_type' => 'apply_refund',
  504. 'change_message' => '用户申请退款,原因:' . $refundReasonWap,
  505. 'change_time' => time()
  506. ]);
  507. $res2 = false !== $this->dao->update(['id' => $order['id']], $data);
  508. $res = $res1 && $res2;
  509. if (!$res)
  510. throw new ValidateException('申请退款失败!');
  511. //子订单申请退款
  512. if ($order['pid'] > 0) {
  513. $p_order = $this->dao->get((int)$order['pid']);
  514. $split_order = $this->dao->count(['pid' => $order['pid'], 'refund_status' => 0]);
  515. if ($split_order || (!$split_order && $p_order['status'] == 4) || $cart_id) {
  516. $this->dao->update(['id' => $order['pid']], ['refund_status' => 3, 'refund_reason_time' => time()]);
  517. } else {
  518. $this->dao->update(['id' => $order['pid']], ['refund_status' => 4, 'refund_reason_time' => time()]);
  519. }
  520. } else {
  521. /** @var StoreOrderCartInfoServices $orderCartInfoService */
  522. $orderCartInfoService = app()->make(StoreOrderCartInfoServices::class);
  523. // if (!$orderCartInfoService->getSplitCartList()) {
  524. //
  525. // }
  526. }
  527. });
  528. try {
  529. ChannelService::instance()->send('NEW_REFUND_ORDER', ['order_id' => $order['order_id']]);
  530. } catch (\Exception $e) {
  531. }
  532. //提醒推送
  533. event('notice.notice', [['order' => $order], 'send_order_apply_refund']);
  534. return true;
  535. }
  536. /**
  537. * 写入退款快递单号
  538. * @param $order
  539. * @param $express
  540. * @return bool
  541. */
  542. public function editRefundExpress($id, $express_id)
  543. {
  544. $this->transaction(function () use ($id, $express_id) {
  545. /** @var StoreOrderStatusServices $statusService */
  546. $statusService = app()->make(StoreOrderStatusServices::class);
  547. /** @var StoreOrderServices $orderService */
  548. $orderService = app()->make(StoreOrderServices::class);
  549. $res1 = false !== $statusService->save([
  550. 'oid' => $id,
  551. 'change_type' => 'refund_express',
  552. 'change_message' => '用户已退货,订单号:' . $express_id,
  553. 'change_time' => time()
  554. ]);
  555. $res2 = false !== $orderService->update(['id' => $id], ['refund_type' => 5, 'refund_express' => $express_id]);
  556. $res = $res1 && $res2;
  557. if (!$res)
  558. throw new ValidateException('提交退货快递单号失败!');
  559. });
  560. return true;
  561. }
  562. }