OrderRefund.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 山西牛酷信息科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com.cn
  8. * 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和使用。
  9. * 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
  10. * =========================================================
  11. */
  12. namespace app\model\order;
  13. use app\model\member\MemberAccount;
  14. use app\model\shop\Shop;
  15. use app\model\system\Pay;
  16. use app\model\BaseModel;
  17. use app\model\message\Message;
  18. /**
  19. * 订单退款
  20. *
  21. * @author Administrator
  22. *
  23. */
  24. class OrderRefund extends BaseModel
  25. {
  26. /*********************************************************************************订单退款状态*****************************************************/
  27. //已申请退款
  28. const REFUND_APPLY = 1;
  29. // 已确认
  30. const REFUND_CONFIRM = 2;
  31. //已完成
  32. const REFUND_COMPLETE = 3;
  33. //等待买家发货
  34. const REFUND_WAIT_DELIVERY = 4;
  35. //等待卖家收货
  36. const REFUND_WAIT_TAKEDELIVERY = 5;
  37. //卖家确认收货
  38. const REFUND_TAKEDELIVERY = 6;
  39. // 卖家拒绝退款
  40. const REFUND_DIEAGREE = -1;
  41. const ONLY_REFUNDS = 1;//仅退款
  42. const A_REFUND_RETURN = 2;//退款退货
  43. /**
  44. * 订单退款状态
  45. * @var unknown
  46. */
  47. public $order_refund_status = [
  48. 0 => [
  49. 'status' => 0,
  50. 'name' => '',
  51. 'action' => [
  52. ],
  53. 'member_action' => [
  54. [
  55. 'event' => 'orderRefundApply',
  56. 'title' => '申请维权',
  57. 'color' => ''
  58. ],
  59. ]
  60. ],
  61. self::REFUND_APPLY => [
  62. 'status' => self::REFUND_APPLY,
  63. 'name' => '申请维权',
  64. 'action' => [
  65. [
  66. 'event' => 'orderRefundAgree',
  67. 'title' => '同意',
  68. 'color' => ''
  69. ],
  70. [
  71. 'event' => 'orderRefundRefuse',
  72. 'title' => '拒绝',
  73. 'color' => ''
  74. ],
  75. ],
  76. 'member_action' => [
  77. [
  78. 'event' => 'orderRefundCancel',
  79. 'title' => '撤销维权',
  80. 'color' => ''
  81. ],
  82. ]
  83. ],
  84. self::REFUND_CONFIRM => [
  85. 'status' => self::REFUND_CONFIRM,
  86. 'name' => '待转账',
  87. 'action' => [
  88. [
  89. 'event' => 'orderRefundTransfer',
  90. 'title' => '转账',
  91. 'color' => ''
  92. ],
  93. ],
  94. 'member_action' => [
  95. ]
  96. ],
  97. self::REFUND_COMPLETE => [
  98. 'status' => self::REFUND_COMPLETE,
  99. 'name' => '维权结束',
  100. 'action' => [
  101. ],
  102. 'member_action' => [
  103. ]
  104. ],
  105. self::REFUND_WAIT_DELIVERY => [
  106. 'status' => self::REFUND_WAIT_DELIVERY,
  107. 'name' => '买家待退货',
  108. 'action' => [
  109. ],
  110. 'member_action' => [
  111. [
  112. 'event' => 'orderRefundDelivery',
  113. 'title' => '填写发货物流',
  114. 'color' => ''
  115. ],
  116. ]
  117. ],
  118. self::REFUND_WAIT_TAKEDELIVERY => [
  119. 'status' => self::REFUND_WAIT_TAKEDELIVERY,
  120. 'name' => '卖家待收货',
  121. 'action' => [
  122. [
  123. 'event' => 'orderRefundTakeDelivery',
  124. 'title' => '收货',
  125. 'color' => ''
  126. ],
  127. [
  128. 'event' => 'orderRefundRefuse',
  129. 'title' => '拒绝',
  130. 'color' => ''
  131. ],
  132. ],
  133. 'member_action' => [
  134. ]
  135. ],
  136. self::REFUND_TAKEDELIVERY => [
  137. 'status' => self::REFUND_TAKEDELIVERY,
  138. 'name' => '卖家已收货',
  139. 'action' => [
  140. [
  141. 'event' => 'orderRefundTransfer',
  142. 'title' => '转账',
  143. 'color' => ''
  144. ],
  145. ],
  146. 'member_action' => [
  147. ]
  148. ],
  149. self::REFUND_DIEAGREE => [
  150. 'status' => self::REFUND_DIEAGREE,
  151. 'name' => '卖家拒绝',
  152. 'action' => [
  153. ],
  154. 'member_action' => [
  155. [
  156. 'event' => 'orderRefundCancel',
  157. 'title' => '撤销维权',
  158. 'color' => ''
  159. ],
  160. [
  161. 'event' => 'orderRefundAsk',
  162. 'title' => '修改申请',
  163. 'color' => ''
  164. ],
  165. ]
  166. ],
  167. ];
  168. /**
  169. * 退款方式
  170. * @var unknown
  171. */
  172. public $refund_type = [
  173. self::ONLY_REFUNDS => '仅退款',
  174. self::A_REFUND_RETURN => '退货退款',
  175. ];
  176. /**
  177. * 退款方式
  178. * @var unknown
  179. */
  180. public $refund_reason_type = [
  181. '未按约定时间发货',
  182. '拍错/多拍/不喜欢',
  183. '协商一致退款',
  184. '其他',
  185. ];
  186. /****************************************************************************订单退款相关操作(开始)**********************************/
  187. /**
  188. * 获取退款金额
  189. * @param int $order_goods_id
  190. */
  191. public function getOrderRefundMoney($order_goods_id)
  192. {
  193. //订单商品项
  194. $order_goods_info = model('order_goods')->getInfo([
  195. 'order_goods_id' => $order_goods_id
  196. ]);
  197. $count = model("order_goods")->getCount([['order_id', '=', $order_goods_info['order_id']], ['refund_status', '=', 0], ['order_goods_id', '<>', $order_goods_id]], 'order_goods_id');
  198. if($count > 0)
  199. {
  200. $delivery_money = 0;
  201. }else{
  202. //订单整体项
  203. $order_info = model('order')->getInfo([
  204. 'order_id' => $order_goods_info['order_id']
  205. ], 'delivery_money');
  206. $delivery_money = $order_info['delivery_money'];
  207. }
  208. $refund_money = $order_goods_info['real_goods_money'] + $delivery_money;
  209. return $refund_money;
  210. }
  211. /**
  212. * 订单退回余额
  213. * @param int $order_goods_id
  214. */
  215. public function getOrderRefundBalance($order_goods_id)
  216. {
  217. //订单商品项
  218. $order_goods_info = model('order_goods')->getInfo([
  219. 'order_goods_id' => $order_goods_id
  220. ], 'order_id, goods_money');
  221. //订单整体项
  222. $order_info = model('order')->getInfo([
  223. 'order_id' => $order_goods_info['order_id']
  224. ], 'goods_money, balance_money');
  225. if($order_info['balance_money'] != 0)
  226. {
  227. if($order_info['goods_money'] != 0)
  228. {
  229. return $this->success($order_info['balance_money'] * $order_goods_info['goods_money']/$order_info['goods_money']);
  230. }else{
  231. return $this->success(0);
  232. }
  233. }
  234. return $this->success(0);
  235. }
  236. /**
  237. * 添加退款操作日志
  238. * @param int $order_goods_id
  239. * @param int $refund_status
  240. * @param string $action
  241. * @param int $action_way
  242. * @param int $action_userid
  243. * @param string $action_username
  244. */
  245. public function addOrderRefundLog($order_goods_id, $refund_status, $action, $action_way, $action_userid, $action_username)
  246. {
  247. $data = [
  248. 'order_goods_id' => $order_goods_id,
  249. 'refund_status' => $refund_status,
  250. 'action' => $action,
  251. 'action_way' => $action_way,
  252. 'action_userid' => $action_userid,
  253. 'username' => $action_username,
  254. 'action_time' => time()
  255. ];
  256. $res = model('order_refund_log')->add($data);
  257. return $res;
  258. }
  259. /**
  260. * 会员申请退款
  261. * @param array $data
  262. * @param array $member_info
  263. * @return multitype:string mixed
  264. */
  265. public function orderRefundApply($data, $member_info)
  266. {
  267. $order_goods_info = model('order_goods')->getInfo(['order_goods_id' => $data['order_goods_id']], 'order_id,refund_status,delivery_status,is_virtual,site_id');
  268. if (empty($order_goods_info))
  269. return $this->error();
  270. if ($order_goods_info['refund_status'] != 0 && $order_goods_info['refund_status'] != -1)
  271. return $this->error();
  272. $refund_type_list = $this->getRefundType($order_goods_info);
  273. //防止退款方式越权
  274. if(!in_array($data["refund_type"], $refund_type_list))
  275. return $this->error();
  276. $order_info = model('order')->getInfo(['order_id' => $order_goods_info['order_id']]);
  277. //判断是否允许申请退款
  278. // if($order_info['is_enable_refund'] == 0)
  279. // return $this->error();
  280. model('order_goods')->startTrans();
  281. try {
  282. $data['refund_status'] = self::REFUND_APPLY;
  283. $data['refund_status_name'] = $this->order_refund_status[self::REFUND_APPLY]["name"];
  284. $data['refund_status_action'] = json_encode($this->order_refund_status[self::REFUND_APPLY], JSON_UNESCAPED_UNICODE);
  285. $data['refund_type'] = $data["refund_type"];
  286. $data['refund_remark'] = $data["refund_remark"];
  287. $pay_model = new Pay();
  288. $data['refund_no'] = $pay_model->createRefundNo();
  289. $data['refund_action_time'] = time();
  290. $refund_apply_money = $this->getOrderRefundMoney($data['order_goods_id']);//可退款金额 通过计算获得
  291. $data['refund_apply_money'] = $refund_apply_money;
  292. $res = model('order_goods')->update($data, ['order_goods_id' => $data['order_goods_id']]);
  293. //验证订单锁定状态
  294. $this->verifyOrderLock($order_goods_info["order_id"]);
  295. $this->addOrderRefundLog($data['order_goods_id'], self::REFUND_APPLY, '买家申请退款', 1, $member_info['member_id'], $member_info['nickname']);
  296. event('orderRefundApply', $data);//传入订单类型以及订单项id
  297. model('order_goods')->commit();
  298. //订单会员申请退款消息
  299. $message_model = new Message();
  300. $message_model->sendMessage(['keywords' => "BUYER_REFUND", 'order_goods_id'=>$data['order_goods_id']]);
  301. return $this->success($res);
  302. } catch (\Exception $e) {
  303. model('order_goods')->rollback();
  304. return $this->error('', $e->getMessage());
  305. }
  306. }
  307. /**
  308. * 用户撤销退款申请
  309. * @param array $data
  310. * @param array $member_info
  311. * @return string[]|mixed[]
  312. */
  313. public function memberCancelRefund($data, $member_info)
  314. {
  315. $order_goods_info = model('order_goods')->getInfo(['order_goods_id' => $data['order_goods_id']]);
  316. if (empty($order_goods_info)) {
  317. return $this->error();
  318. }
  319. model('order_goods')->startTrans();
  320. try {
  321. // $order_info = model('order')->getInfo(['order_id' => $order_goods_info['order_id']]);
  322. $data['refund_status'] = 0;
  323. $data['refund_status_name'] = $this->order_refund_status[0]["name"];
  324. $data['refund_status_action'] = json_encode($this->order_refund_status[0], JSON_UNESCAPED_UNICODE);
  325. $data['refund_type'] = 0;
  326. $res = model('order_goods')->update($data, ['order_goods_id' => $data['order_goods_id']]);
  327. //验证订单锁定状态
  328. $this->verifyOrderLock($order_goods_info["order_id"]);
  329. $this->addOrderRefundLog($data['order_goods_id'], 0, '买家撤销退款申请', 1, $member_info['member_id'], $member_info['nickname']);
  330. event('memberCancelRefund', $data);//传入订单类型以及订单项id
  331. model('order_goods')->commit();
  332. return $this->success();
  333. } catch (\Exception $e) {
  334. model('order_goods')->rollback();
  335. return $this->error('', $e->getMessage());
  336. }
  337. }
  338. /**
  339. * 卖家确认退款
  340. * @param array $data
  341. * @param array $user_info
  342. */
  343. public function orderRefundConfirm($data, $user_info)
  344. {
  345. $order_goods_info = model('order_goods')->getInfo(['order_goods_id' => $data['order_goods_id']]);
  346. if (empty($order_goods_info)) {
  347. return $this->error();
  348. }
  349. if ($order_goods_info['refund_status'] != self::REFUND_APPLY) {
  350. return $this->error();
  351. }
  352. model('order_goods')->startTrans();
  353. try {
  354. if ($order_goods_info['refund_type'] == 1) {
  355. $data['refund_status'] = self::REFUND_CONFIRM; //确认等待转账
  356. } else {
  357. $data['refund_status'] = self::REFUND_WAIT_DELIVERY; //确认等待买家发货
  358. }
  359. $data['refund_status_name'] = $this->order_refund_status[$data['refund_status']]["name"];
  360. $data['refund_status_action'] = json_encode($this->order_refund_status[$data['refund_status']], JSON_UNESCAPED_UNICODE);
  361. $res = model('order_goods')->update($data, ['order_goods_id' => $data['order_goods_id']]);
  362. $this->addOrderRefundLog($data['order_goods_id'], $data['refund_status'], '卖家确认退款', 2, $user_info['uid'], $user_info['username']);
  363. model('order_goods')->commit();
  364. //订单退款同意消息
  365. $message_model = new Message();
  366. $message_model->sendMessage(['keywords' => "ORDER_REFUND_AGREE", 'order_id'=>$order_goods_info['order_id'], "order_goods_id" => $data['order_goods_id']]);
  367. return $this->success($res);
  368. } catch (\Exception $e) {
  369. model('order_goods')->rollback();
  370. return $this->error('', $e->getMessage());
  371. }
  372. }
  373. /**
  374. * 卖家拒绝退款
  375. * @param array $data
  376. * @param array $user_info
  377. */
  378. public function orderRefundRefuse($data, $user_info, $refund_refuse_reason)
  379. {
  380. $order_goods_info = model('order_goods')->getInfo(['order_goods_id' => $data['order_goods_id']]);
  381. if (empty($order_goods_info)) {
  382. return $this->error();
  383. }
  384. if ($order_goods_info['refund_status'] != self::REFUND_APPLY && $order_goods_info['refund_status'] != self::REFUND_WAIT_TAKEDELIVERY) {
  385. return $this->error();
  386. }
  387. model('order_goods')->startTrans();
  388. try {
  389. $data['refund_status'] = self::REFUND_DIEAGREE;
  390. $data['refund_status_name'] = $this->order_refund_status[self::REFUND_DIEAGREE]["name"];
  391. $data['refund_status_action'] = json_encode($this->order_refund_status[self::REFUND_DIEAGREE], JSON_UNESCAPED_UNICODE);
  392. $data["refund_refuse_reason"] = $refund_refuse_reason;
  393. //重置部分字段
  394. $data["refund_address"] = "";
  395. $data["refund_delivery_remark"] = "";
  396. $data["refund_remark"] = "";
  397. $data["refund_delivery_name"] = "";
  398. $data["refund_delivery_no"] = "";
  399. $data["refund_reason"] = "";
  400. $data["refund_action_time"] = time();
  401. $res = model('order_goods')->update($data, ['order_goods_id' => $data['order_goods_id']]);
  402. //验证订单锁定状态
  403. $this->verifyOrderLock($order_goods_info["order_id"]);
  404. $this->addOrderRefundLog($data['order_goods_id'], $data['refund_status'], '卖家拒绝退款', 2, $user_info['uid'], $user_info['username']);
  405. event("OrderRefundRefuse", $data);
  406. model('order_goods')->commit();
  407. //订单退款拒绝消息
  408. $message_model = new Message();
  409. $message_model->sendMessage(['keywords' => "ORDER_REFUND_REFUSE", 'order_id'=>$order_goods_info['order_id'], "order_goods_id" => $data['order_goods_id']]);
  410. return $this->success();
  411. } catch (\Exception $e) {
  412. model('order_goods')->rollback();
  413. return $this->error('', $e->getMessage());
  414. }
  415. }
  416. /**
  417. * 买家退货
  418. * @param array $data 退货信息
  419. * @param array $member_info 会员信息
  420. */
  421. public function orderRefundDelivery($data, $member_info)
  422. {
  423. $order_goods_info = model('order_goods')->getInfo(['order_goods_id' => $data['order_goods_id']]);
  424. if (empty($order_goods_info)) {
  425. return $this->error();
  426. }
  427. if ($order_goods_info['refund_status'] != self::REFUND_WAIT_DELIVERY) {
  428. return $this->error();
  429. }
  430. model('order_goods')->startTrans();
  431. try {
  432. $data['refund_status'] = self::REFUND_WAIT_TAKEDELIVERY;
  433. $data['refund_status_name'] = $this->order_refund_status[self::REFUND_WAIT_TAKEDELIVERY]["name"];
  434. $data['refund_status_action'] = json_encode($this->order_refund_status[self::REFUND_WAIT_TAKEDELIVERY], JSON_UNESCAPED_UNICODE);
  435. $shop_model = new Shop();
  436. $shop_info_result = $shop_model->getShopInfo([["site_id", "=", $order_goods_info["site_id"]]], "full_address");
  437. $shop_info = $shop_info_result["data"];
  438. $data["refund_address"] = $shop_info["full_address"];
  439. $res = model('order_goods')->update($data, ['order_goods_id' => $data['order_goods_id']]);
  440. $this->addOrderRefundLog($data['order_goods_id'], $data['refund_status'], $data['refund_delivery_name'] . ':' . $data['refund_delivery_no'], 1, $member_info['member_id'], $member_info['nickname']);
  441. model('order_goods')->commit();
  442. //买家已退货提醒
  443. $message_model = new Message();
  444. $message_model->sendMessage(['keywords' => "BUYER_DELIVERY_REFUND", 'order_id'=>$order_goods_info['order_id']]);
  445. return $this->success();
  446. } catch (\Exception $e) {
  447. model('order_goods')->rollback();
  448. return $this->error('', $e->getMessage());
  449. }
  450. }
  451. /**
  452. * 卖家确认收到退货
  453. * @param array $data 退货信息
  454. * @param array $member_info 会员信息
  455. */
  456. public function orderRefundTakeDelivery($data, $user_info)
  457. {
  458. $order_goods_info = model('order_goods')->getInfo(['order_goods_id' => $data['order_goods_id']]);
  459. if (empty($order_goods_info)) {
  460. return $this->error();
  461. }
  462. if ($order_goods_info['refund_status'] != self::REFUND_WAIT_TAKEDELIVERY) {
  463. return $this->error();
  464. }
  465. model('order_goods')->startTrans();
  466. try {
  467. $data['refund_status'] = self::REFUND_TAKEDELIVERY;
  468. $data['refund_status_name'] = $this->order_refund_status[self::REFUND_TAKEDELIVERY]["name"];
  469. $data['refund_status_action'] = json_encode($this->order_refund_status[self::REFUND_TAKEDELIVERY], JSON_UNESCAPED_UNICODE);
  470. $res = model('order_goods')->update($data, ['order_goods_id' => $data['order_goods_id']]);
  471. $this->addOrderRefundLog($data['order_goods_id'], $data['refund_status'], '卖家确认收到退货', 2, $user_info['uid'], $user_info['username']);
  472. model('order_goods')->commit();
  473. return $this->success();
  474. } catch (\Exception $e) {
  475. model('order_goods')->rollback();
  476. return $this->error('', $e->getMessage());
  477. }
  478. }
  479. /**
  480. * 退货完成
  481. * @param array $data
  482. * @param array $user_info
  483. * @return multitype:string mixed
  484. */
  485. public function orderRefundFinish($data, $user_info)
  486. {
  487. $order_goods_info = model('order_goods')->getInfo(['order_goods_id' => $data['order_goods_id']]);
  488. if (empty($order_goods_info)) {
  489. return $this->error();
  490. }
  491. if ($order_goods_info['refund_status'] != self::REFUND_TAKEDELIVERY && $order_goods_info['refund_status'] != self::REFUND_CONFIRM) {
  492. return $this->error();
  493. }
  494. model('order_goods')->startTrans();
  495. try {
  496. $update_data = array(
  497. "refund_time" => time(),
  498. "refund_real_money" => $order_goods_info["refund_apply_money"]
  499. );
  500. $update_data['refund_status'] = self::REFUND_COMPLETE;
  501. $update_data['refund_status_name'] = $this->order_refund_status[self::REFUND_COMPLETE]["name"];
  502. $update_data['refund_status_action'] = json_encode($this->order_refund_status[self::REFUND_COMPLETE], JSON_UNESCAPED_UNICODE);
  503. $res = model('order_goods')->update($update_data, [['order_goods_id', "=", $data['order_goods_id']]]);
  504. $this->finishAction($data['order_goods_id']);
  505. $order_info = model('order')->getInfo(['order_id' => $order_goods_info['order_id']]);
  506. //调用各种订单
  507. switch ($order_info['order_type']) {
  508. case 1:
  509. $order_model = new Order();
  510. break;
  511. case 2:
  512. $order_model = new StoreOrder();
  513. break;
  514. case 3:
  515. $order_model = new LocalOrder();
  516. break;
  517. case 4:
  518. $order_model = new VirtualOrder();
  519. break;
  520. }
  521. //退货日志
  522. $this->addOrderRefundLog($data['order_goods_id'], self::REFUND_COMPLETE, '维权完成', 2, $user_info['uid'], $user_info['username']);
  523. $order_goods_info = model("order_goods")->getInfo([["order_goods_id", "=", $data['order_goods_id']]]);
  524. $order_model->refund($order_goods_info);
  525. //同时修改用户的order_money
  526. model('member')->setDec([['member_id', '=', $order_goods_info['member_id']]], 'order_money', $order_goods_info['refund_real_money']);
  527. $member_account_modle = new \app\model\member\MemberAccount();
  528. $member_account_modle->addMemberAccount($order_goods_info['member_id'], 'balance_money', $order_goods_info['refund_real_money'], 'recharge', '购物退款','购物退款');
  529. // event('OrderRefundFinish', $order_goods_info);//传入订单类型以及订单项id
  530. model('order_goods')->commit();
  531. return $this->success();
  532. } catch (\Exception $e) {
  533. model('order_goods')->rollback();
  534. return $this->error('', $e->getMessage());
  535. }
  536. }
  537. /**
  538. * 退款完成操作
  539. * @param $data
  540. * @param $user_info
  541. * @return array
  542. */
  543. public function finishAction($order_goods_id){
  544. $order_goods_info = model('order_goods')->getInfo(['order_goods_id' => $order_goods_id]);
  545. model('order_goods')->startTrans();
  546. try {
  547. $order_info = model('order')->getInfo(['order_id' => $order_goods_info['order_id']]);
  548. //验证订单是否全部退款完毕
  549. $order_goods_count = model("order_goods")->getCount([["order_id", "=", $order_goods_info['order_id']]], "order_goods_id");
  550. $refund_count = model("order_goods")->getCount([["order_id", "=", $order_goods_info['order_id']], ["refund_status", "=", self::REFUND_COMPLETE]], "order_goods_id");
  551. $refund_total_real_money = model("order_goods")->getSum([["order_id", "=", $order_goods_info['order_id']], ["refund_status", "=", self::REFUND_COMPLETE]], "refund_real_money");
  552. if($refund_total_real_money > $order_info["order_money"]){
  553. model('order_goods')->rollback();
  554. return $this->error([], "退款金额不能大于订单总金额");
  555. }
  556. //实际执行转账 (存在余额支付的话 退款一部分余额 退还一部分实际金额) //订单退款退回余额积分等操作
  557. if($order_info["balance_money"] > 0){
  558. // if($order_goods_count == $refund_count){
  559. // $refunded_balance_money = model("order_goods")->getSum([["order_id", "=", $order_goods_info['order_id']], ["refund_status", "=", self::REFUND_COMPLETE]], "order_goods_id");
  560. // $refunded_balance_money = model("order_goods")->getSum([["order_id", "=", $order_goods_info['order_id']], ["refund_status", "=", self::REFUND_COMPLETE]], "order_goods_id");
  561. // $refund_balance_money = $order_info["balance_money"] - $refunded_balance_money;
  562. // $refund_pay_money = $order_info["pay_money"] - $refund_balance_money;
  563. // }else{
  564. $balance_rate = $order_info["balance_money"]/$order_info["order_money"];
  565. $refund_balance_money = $order_goods_info["refund_real_money"]*$balance_rate;
  566. $refund_pay_money = $order_goods_info["refund_real_money"] - $refund_balance_money;
  567. // }
  568. }else{
  569. $refund_balance_money = 0;
  570. $refund_pay_money = $order_goods_info["refund_real_money"];
  571. }
  572. //退还直接支付的金额
  573. if($refund_pay_money > 0){
  574. $pay_model = new Pay();
  575. $refund_result = $pay_model->refund($order_goods_info["refund_no"], $refund_pay_money, $order_info["out_trade_no"], '', $order_info["pay_money"], $order_info["site_id"], 1);
  576. if($refund_result["code"] < 0) {
  577. model('order_goods')->rollback();
  578. return $refund_result;
  579. }
  580. }
  581. //退款余额
  582. if($refund_balance_money > 0){
  583. $member_account_model = new MemberAccount();
  584. $balance_result = $member_account_model->addMemberAccount($order_info["member_id"], "balance", $refund_balance_money, "order", "余额返还","订单退款,返还余额:".$refund_balance_money);
  585. if($balance_result["code"] < 0) {
  586. model('order_goods')->rollback();
  587. return $balance_result;
  588. }
  589. }
  590. //验证订单锁定状态
  591. $this->verifyOrderLock($order_goods_info["order_id"]);
  592. //验证订单是否全部退款完毕 订单如果全部退款完毕,订单关闭
  593. if($order_goods_count == $refund_count){
  594. $order_common_model = new OrderCommon();
  595. $close_result = $order_common_model->orderClose($order_goods_info["order_id"]);
  596. if($close_result["code"] < 0){
  597. model('order_goods')->rollback();
  598. return $close_result;
  599. }
  600. }
  601. event('OrderRefundFinish', $order_goods_info);//传入订单类型以及订单项id
  602. model('order_goods')->commit();
  603. return $this->success();
  604. } catch (\Exception $e) {
  605. model('order_goods')->rollback();
  606. return $this->error('', $e->getMessage());
  607. }
  608. }
  609. /**
  610. * 判断当前订单是否全部退款完毕
  611. * @param $order_id
  612. */
  613. public function verifyOrderAllRefund($order_id){
  614. //验证订单是否全部退款完毕 订单如果全部退款完毕,订单关闭
  615. $order_goods_count = model("order_goods")->getCount([["order_id", "=", $order_id]], "order_goods_id");
  616. $refund_count = model("order_goods")->getCount([["order_id", "=", $order_id], ["refund_status", "=", self::REFUND_COMPLETE]], "order_goods_id");
  617. if($order_goods_count == $refund_count){
  618. //调用订单关闭
  619. $order_common_model = new OrderCommon();
  620. $close_result = $order_common_model->orderClose($order_id);
  621. if($close_result["code"] < 0){
  622. return $close_result;
  623. }
  624. }else{
  625. return $this->success();
  626. }
  627. }
  628. /**
  629. * 获取订单售后操作列表
  630. * @param array $condition
  631. * @param string $field
  632. * @return array
  633. */
  634. public function getOrderRefundLogList($condition = [], $field = '*', $order = '', $limit = null)
  635. {
  636. $list = model('order_refund_log')->getList($condition, $field, $order, '', '', '', $limit);
  637. return $this->success($list);
  638. }
  639. /**
  640. * 获取退款维权订单列表
  641. * @param array $condition
  642. * @param number $page
  643. * @param string $page_size
  644. * @param string $order
  645. * @param string $field
  646. */
  647. public function getRefundOrderGoodsPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = 'nop.*,no.order_no,no.site_id,no.site_name')
  648. {
  649. $join = [
  650. [
  651. 'order no',
  652. 'nop.order_id = no.order_id',
  653. 'left'
  654. ],
  655. ];
  656. $list = model('order_goods')->pageList($condition, $field, $order, $page, $page_size, 'nop', $join);
  657. if(!empty($list["list"])){
  658. foreach($list["list"] as $k => $v){
  659. $refund_action = empty($v["refund_status_action"]) ? [] : json_decode($v["refund_status_action"], true);
  660. $refund_member_action = $refund_action["member_action"] ?? [];
  661. $list['list'][ $k ]['refund_action'] = $refund_member_action;
  662. }
  663. }
  664. return $this->success($list);
  665. }
  666. /**
  667. * 初始化订单项退款操作
  668. * @param $order_id
  669. */
  670. public function initOrderGoodsRefundAction($condition){
  671. //订单项增加可退款操作
  672. $data = array(
  673. "refund_status_action" => json_encode($this->order_refund_status[0], JSON_UNESCAPED_UNICODE)
  674. );
  675. $result = model("order_goods")->update($data, $condition);
  676. return $this->success($result);
  677. }
  678. /**
  679. * 移除订单项退款操作
  680. * @param $order_id
  681. */
  682. public function removeOrderGoodsRefundAction($condition){
  683. //订单项增加可退款操作
  684. $data = array(
  685. "refund_status_action" => ''
  686. );
  687. $result = model("order_goods")->update($data, $condition);
  688. return $this->success($result);
  689. }
  690. /**
  691. * 会员维权详情
  692. * @param $order_goods_id
  693. */
  694. public function getMemberRefundDetail($order_goods_id, $member_id){
  695. $condition = array(
  696. ["order_goods_id", "=", $order_goods_id]
  697. );
  698. $condition[] = ["member_id", "=", $member_id];
  699. $info = model("order_goods")->getInfo($condition);
  700. $refund_action = empty($info["refund_status_action"]) ? [] : json_decode($info["refund_status_action"], true);
  701. $refund_member_action = $refund_action["member_action"] ?? [];
  702. $info['refund_action'] = $refund_member_action;
  703. //判断维权操作
  704. $complain_action = 0;
  705. //订单项未退款完毕 订单未完成 未关闭
  706. if($info["refund_status"] != 3 && $info["refund_status"] != 0){
  707. $complain_action = 1;
  708. }
  709. $info["complain_action"] = $complain_action;
  710. //将售后日志引入
  711. $refund_log_list = model("order_refund_log")->getList([["order_goods_id", "=", $order_goods_id]], "*", "action_time desc");
  712. $info['refund_log_list'] = $refund_log_list;
  713. return $this->success($info);
  714. }
  715. /**
  716. * 会员维权详情
  717. * @param $order_goods_id
  718. */
  719. public function getRefundDetail($order_goods_id){
  720. $condition = array(
  721. ["order_goods_id", "=", $order_goods_id]
  722. );
  723. $info = model("order_goods")->getInfo($condition);
  724. $refund_action = empty($info["refund_status_action"]) ? [] : json_decode($info["refund_status_action"], true);
  725. $refund_action = $refund_action["action"] ?? [];
  726. $info['refund_action'] = $refund_action;
  727. //将售后日志引入
  728. $refund_log_list = model("order_refund_log")->getList([["order_goods_id", "=", $order_goods_id]], "*", "action_time desc");
  729. $info['refund_log_list'] = $refund_log_list;
  730. return $this->success($info);
  731. }
  732. /**
  733. * 根据配送状态获取退款方式
  734. * @param $refund_status
  735. */
  736. public function getRefundType($order_goods_info){
  737. if($order_goods_info["is_virtual"] == 1){
  738. return [self::ONLY_REFUNDS];
  739. }else{
  740. if($order_goods_info["delivery_status"] == 0){
  741. return [self::ONLY_REFUNDS];
  742. }else{
  743. return [self::ONLY_REFUNDS,self::A_REFUND_RETURN];
  744. }
  745. }
  746. }
  747. /****************************************************************************订单退款相关操作(结束)**********************************/
  748. /********************************************************************** 主动退款 ********************************************************************/
  749. /**
  750. * 主动完成退款流程
  751. * @param $order_id
  752. */
  753. public function activeRefund($order_id, $remark, $refund_reason){
  754. $order_info = model("order")->getInfo([["order_id", "=", $order_id]], "pay_money, out_trade_no, site_id, delivery_money");
  755. if($order_info["pay_money"] > 0){
  756. $pay_model = new Pay();
  757. //遍历订单项
  758. $order_goods_list = model("order_goods")->getList([["order_id", "=", $order_id]]);
  759. if(!empty($order_goods_list)){
  760. $count = count($order_goods_list);
  761. foreach($order_goods_list as $k => $v){
  762. $item_refund_money = $v["real_goods_money"];
  763. if($count == ($k + 1)){
  764. $item_refund_money += $order_info["delivery_money"];
  765. }
  766. $item_result = $this->activeOrderGoodsRefund($v["order_goods_id"], $item_refund_money, $remark, $refund_reason);
  767. if($item_result["code"] < 0){
  768. return $item_result;
  769. }
  770. }
  771. }
  772. //订单整体退款
  773. // $refund_result = $pay_model->refund($refund_no, $order_info["pay_money"], $order_info["out_trade_no"], '', $order_info["pay_money"], $order_info["site_id"], 1);
  774. return $this->success();
  775. }else{
  776. return $this->success();
  777. }
  778. }
  779. /**
  780. * 订单项主动退款
  781. * @param $order_goods_id
  782. * @param $refund_money
  783. * @return array|mixed|void
  784. */
  785. public function activeOrderGoodsRefund($order_goods_id, $refund_money, $remark = '',$refund_reason = ''){
  786. model('order_goods')->startTrans();
  787. try {
  788. $pay_model = new Pay();
  789. $refund_no = $pay_model->createRefundNo();
  790. $update_data = array(
  791. "refund_no" => $refund_no,
  792. "refund_time" => time(),
  793. "refund_reason" => $refund_reason,
  794. "refund_apply_money" => $refund_money,
  795. "refund_real_money" => $refund_money,
  796. "refund_action_time" => time()
  797. );
  798. $update_data['refund_status'] = self::REFUND_COMPLETE;
  799. $update_data['refund_status_name'] = $this->order_refund_status[self::REFUND_COMPLETE]["name"];
  800. $update_data['refund_status_action'] = json_encode($this->order_refund_status[self::REFUND_COMPLETE], JSON_UNESCAPED_UNICODE);
  801. $res = model('order_goods')->update($update_data, [['order_goods_id', "=", $order_goods_id]]);
  802. if($res === false){
  803. return $this->error();
  804. }
  805. $refund_result = $this->finishAction($order_goods_id);
  806. if($refund_result['code'] < 0){
  807. model('order_goods')->rollback();
  808. return $this->error();
  809. }
  810. //退货日志
  811. $this->addOrderRefundLog($order_goods_id, self::REFUND_COMPLETE, $remark.',维权完成', 3, 0, "平台");
  812. model('order_goods')->commit();
  813. return $this->success();
  814. } catch (\Exception $e) {
  815. model('order_goods')->rollback();
  816. return $this->error('', $e->getMessage());
  817. }
  818. }
  819. /********************************************************************** 主动退款 ********************************************************************/
  820. /**
  821. * 判断订单的锁定状态
  822. * @param $order_goods_id
  823. */
  824. public function verifyOrderLock($order_id){
  825. $condition = array(
  826. ["order_id", "=", $order_id],
  827. ["refund_status", "not in", [0,3]],
  828. );
  829. $count = model("order_goods")->getCount($condition, "order_goods_id");
  830. $order_common_model = new OrderCommon();
  831. if($count > 0){
  832. $res = $order_common_model->orderLock($order_id);
  833. }else{
  834. $res = $order_common_model->orderUnlock($order_id);
  835. }
  836. return $res;
  837. }
  838. }