You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

754 lines
28 KiB

  1. <?php
  2. namespace app\admin\controller\unishop;
  3. use addons\nzf\PayService;
  4. use addons\unishop\extend\Hashids;
  5. use addons\unishop\extend\Redis;
  6. use app\admin\model\unishop\Area;
  7. use app\admin\model\unishop\OrderProduct;
  8. use app\admin\model\unishop\OrderRefund;
  9. use app\common\controller\Backend;
  10. use think\Db;
  11. use think\Exception;
  12. use think\exception\PDOException;
  13. use think\exception\ValidateException;
  14. use think\Hook;
  15. /**
  16. * 订单管理
  17. *
  18. * @icon fa fa-circle-o
  19. */
  20. class Order extends Backend
  21. {
  22. /**
  23. * 是否是关联查询
  24. */
  25. protected $relationSearch = true;
  26. protected $noNeedLogin=["export","finish","doRefund","carry"];
  27. /**
  28. * Order模型对象
  29. * @var \app\admin\model\unishop\Order
  30. */
  31. protected $model = null;
  32. public function _initialize()
  33. {
  34. parent::_initialize();
  35. $this->model = new \app\admin\model\unishop\Order;
  36. $this->view->assign("payTypeList", $this->model->getPayTypeList());
  37. $this->view->assign("statusList", $this->model->getStatusList());
  38. $this->view->assign("refundStatusList", $this->model->getRefundStatusList());
  39. }
  40. /**
  41. * 查看
  42. */
  43. public function index()
  44. {
  45. //设置过滤方法
  46. $this->request->filter(['strip_tags']);
  47. if ($this->request->isAjax()) {
  48. //如果发送的来源是Selectpage,则转发到Selectpage
  49. if ($this->request->request('keyField')) {
  50. return $this->selectpage();
  51. }
  52. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  53. $total = $this->model
  54. ->alias('order')
  55. ->join('user', 'user.id = order.user_id')
  56. ->where($where)
  57. ->count();
  58. $list = $this->model
  59. ->alias('order')
  60. ->join('user', 'user.id = order.user_id')
  61. ->where($where)
  62. ->order($sort, $order)
  63. ->limit($offset, $limit)
  64. ->field('order.*,user.username')
  65. ->select();
  66. $list = collection($list)->toArray();
  67. foreach ($list as &$item) {
  68. $item['id'] = (string)$item['id']; // 整形数字太大js会失准
  69. $item['user'] = [];
  70. $item['user']['username'] = $item['username'] ? $item['username'] : __('Tourist');
  71. $item['have_paid_status'] = $item['have_paid'];
  72. $item['have_delivered_status'] = $item['have_delivered'];
  73. $item['have_received_status'] = $item['have_received'];
  74. $item['have_commented_status'] = $item['have_commented'];
  75. $item["is_carry"]=$item["is_carry"]?"已提货":"未提货";
  76. $item['refund_fee'] = $item['refund_status']==3?$item['refund_fee']:'--';
  77. }
  78. $result = array("total" => $total, "rows" => $list);
  79. return json($result);
  80. }
  81. return $this->view->fetch();
  82. }
  83. /**
  84. * 生成查询所需要的条件,排序方式
  85. * @param mixed $searchfields 快速查询的字段
  86. * @param boolean $relationSearch 是否关联查询
  87. * @return array
  88. */
  89. protected function buildparams($searchfields = null, $relationSearch = null)
  90. {
  91. $searchfields = is_null($searchfields) ? $this->searchFields : $searchfields;
  92. $relationSearch = is_null($relationSearch) ? $this->relationSearch : $relationSearch;
  93. $search = $this->request->get("search", '');
  94. $filter = $this->request->get("filter", '');
  95. $op = $this->request->get("op", '', 'trim');
  96. $sort = $this->request->get("sort", "id");
  97. $order = $this->request->get("order", "DESC");
  98. $offset = $this->request->get("offset", 0);
  99. $limit = $this->request->get("limit", 0);
  100. $filter = (array)json_decode($filter, true);
  101. $op = (array)json_decode($op, true);
  102. $filter = $filter ? $filter : [];
  103. $where = [];
  104. $tableName = '';
  105. if ($relationSearch) {
  106. if (!empty($this->model)) {
  107. $name = \think\Loader::parseName(basename(str_replace('\\', '/', get_class($this->model))));
  108. $tableName = '' . $name . '.';
  109. }
  110. $sortArr = explode(',', $sort);
  111. foreach ($sortArr as $index => & $item) {
  112. $item = stripos($item, ".") === false ? $tableName . trim($item) : $item;
  113. }
  114. unset($item);
  115. $sort = implode(',', $sortArr);
  116. }
  117. $adminIds = $this->getDataLimitAdminIds();
  118. if (is_array($adminIds)) {
  119. $where[] = [$tableName . $this->dataLimitField, 'in', $adminIds];
  120. }
  121. if ($search) {
  122. $searcharr = is_array($searchfields) ? $searchfields : explode(',', $searchfields);
  123. foreach ($searcharr as $k => &$v) {
  124. $v = stripos($v, ".") === false ? $tableName . $v : $v;
  125. }
  126. unset($v);
  127. $where[] = [implode("|", $searcharr), "LIKE", "%{$search}%"];
  128. }
  129. foreach ($filter as $k => $v) {
  130. // 搜索订单状态
  131. if (in_array($k, ['have_paid_status', 'have_delivered_status', 'have_received_status', 'have_commented_status'])) {
  132. switch ($k) {
  133. case 'have_paid_status':
  134. $k = 'have_paid';
  135. break;
  136. case 'have_delivered_status':
  137. $k = 'have_delivered';
  138. break;
  139. case 'have_received_status':
  140. $k = 'have_received';
  141. break;
  142. case 'have_commented_status':
  143. $k = 'have_commented';
  144. break;
  145. }
  146. $v == 0 ? ($op[$k] = '=') : ($op[$k] = '>');
  147. $v = 0;
  148. }
  149. $sym = isset($op[$k]) ? $op[$k] : '=';
  150. if (stripos($k, ".") === false) {
  151. $k = $tableName . $k;
  152. }
  153. $v = !is_array($v) ? trim($v) : $v;
  154. $sym = strtoupper(isset($op[$k]) ? $op[$k] : $sym);
  155. switch ($sym) {
  156. case '=':
  157. case '<>':
  158. $where[] = [$k, $sym, (string)$v];
  159. break;
  160. case 'LIKE':
  161. case 'NOT LIKE':
  162. case 'LIKE %...%':
  163. case 'NOT LIKE %...%':
  164. $where[] = [$k, trim(str_replace('%...%', '', $sym)), "%{$v}%"];
  165. break;
  166. case '>':
  167. case '>=':
  168. case '<':
  169. case '<=':
  170. $where[] = [$k, $sym, intval($v)];
  171. break;
  172. case 'FINDIN':
  173. case 'FINDINSET':
  174. case 'FIND_IN_SET':
  175. $where[] = "FIND_IN_SET('{$v}', " . ($relationSearch ? $k : '`' . str_replace('.', '`.`', $k) . '`') . ")";
  176. break;
  177. case 'IN':
  178. case 'IN(...)':
  179. case 'NOT IN':
  180. case 'NOT IN(...)':
  181. $where[] = [$k, str_replace('(...)', '', $sym), is_array($v) ? $v : explode(',', $v)];
  182. break;
  183. case 'BETWEEN':
  184. case 'NOT BETWEEN':
  185. $arr = array_slice(explode(',', $v), 0, 2);
  186. if (stripos($v, ',') === false || !array_filter($arr)) {
  187. continue 2;
  188. }
  189. //当出现一边为空时改变操作符
  190. if ($arr[0] === '') {
  191. $sym = $sym == 'BETWEEN' ? '<=' : '>';
  192. $arr = $arr[1];
  193. } elseif ($arr[1] === '') {
  194. $sym = $sym == 'BETWEEN' ? '>=' : '<';
  195. $arr = $arr[0];
  196. }
  197. $where[] = [$k, $sym, $arr];
  198. break;
  199. case 'RANGE':
  200. case 'NOT RANGE':
  201. $v = str_replace(' - ', ',', $v);
  202. $arr = array_slice(explode(',', $v), 0, 2);
  203. if (stripos($v, ',') === false || !array_filter($arr)) {
  204. continue 2;
  205. }
  206. //当出现一边为空时改变操作符
  207. if ($arr[0] === '') {
  208. $sym = $sym == 'RANGE' ? '<=' : '>';
  209. $arr = $arr[1];
  210. } elseif ($arr[1] === '') {
  211. $sym = $sym == 'RANGE' ? '>=' : '<';
  212. $arr = $arr[0];
  213. }
  214. $where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' time', $arr];
  215. break;
  216. case 'LIKE':
  217. case 'LIKE %...%':
  218. $where[] = [$k, 'LIKE', "%{$v}%"];
  219. break;
  220. case 'NULL':
  221. case 'IS NULL':
  222. case 'NOT NULL':
  223. case 'IS NOT NULL':
  224. $where[] = [$k, strtolower(str_replace('IS ', '', $sym))];
  225. break;
  226. default:
  227. break;
  228. }
  229. }
  230. $where = function ($query) use ($where) {
  231. foreach ($where as $k => $v) {
  232. if (is_array($v)) {
  233. call_user_func_array([$query, 'where'], $v);
  234. } else {
  235. $query->where($v);
  236. }
  237. }
  238. };
  239. return [$where, $sort, $order, $offset, $limit];
  240. }
  241. /**
  242. * 编辑
  243. */
  244. public function edit($ids = null)
  245. {
  246. $row = $this->model->get($ids);
  247. if (!$row) {
  248. $this->error(__('No Results were found'));
  249. }
  250. $adminIds = $this->getDataLimitAdminIds();
  251. if (is_array($adminIds)) {
  252. if (!in_array($row[$this->dataLimitField], $adminIds)) {
  253. $this->error(__('You have no permission'));
  254. }
  255. }
  256. if ($this->request->isPost()) {
  257. $params = $this->request->post("row/a");
  258. if ($params) {
  259. $params = $this->preExcludeFields($params);
  260. $result = false;
  261. Db::startTrans();
  262. try {
  263. //是否采用模型验证
  264. if ($this->modelValidate) {
  265. $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
  266. $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
  267. $row->validateFailException(true)->validate($validate);
  268. }
  269. $updatetime = $this->request->post('updatetime');
  270. // 乐观锁
  271. $result = $this->model->allowField(true)->save($params, ['id' => $ids, 'updatetime' => $updatetime]);
  272. if (!$result) {
  273. throw new Exception(__('Data had been update before saved, close windows and do it again'));
  274. }
  275. Db::commit();
  276. } catch (ValidateException $e) {
  277. Db::rollback();
  278. $this->error($e->getMessage());
  279. } catch (PDOException $e) {
  280. Db::rollback();
  281. $this->error($e->getMessage());
  282. } catch (Exception $e) {
  283. Db::rollback();
  284. $this->error($e->getMessage());
  285. }
  286. if ($result !== false) {
  287. $this->success();
  288. } else {
  289. $this->error(__('No rows were updated'));
  290. }
  291. }
  292. $this->error(__('Parameter %s can not be empty', ''));
  293. }
  294. $this->view->assign("row", $row);
  295. return $this->view->fetch();
  296. }
  297. /**
  298. * 物流管理
  299. */
  300. public function delivery($ids = null)
  301. {
  302. $row = $this->model->get($ids, ['extend']);
  303. if (!$row) {
  304. $this->error(__('No Results were found'));
  305. }
  306. $adminIds = $this->getDataLimitAdminIds();
  307. if (is_array($adminIds)) {
  308. if (!in_array($row[$this->dataLimitField], $adminIds)) {
  309. $this->error(__('You have no permission'));
  310. }
  311. }
  312. if ($this->request->isPost()) {
  313. $result = false;
  314. Db::startTrans();
  315. try {
  316. $express_number = $this->request->post('express_number');
  317. $have_delivered = $express_number ? time() : 0;
  318. $res1 = $row->allowField(true)->save(['have_delivered' => $have_delivered]);
  319. $res2 = $row->extend->allowField(true)->save(['express_number' => $express_number]);
  320. if ($res1 && $res2) {
  321. $result = true;
  322. } else {
  323. throw new Exception(__('No rows were updated'));
  324. }
  325. Db::commit();
  326. } catch (ValidateException $e) {
  327. Db::rollback();
  328. $this->error($e->getMessage());
  329. } catch (PDOException $e) {
  330. Db::rollback();
  331. $this->error($e->getMessage());
  332. } catch (Exception $e) {
  333. Db::rollback();
  334. $this->error($e->getMessage());
  335. }
  336. if ($result !== false) {
  337. $this->success();
  338. } else {
  339. $this->error(__('No rows were updated'));
  340. }
  341. $this->error(__('Parameter %s can not be empty', ''));
  342. }
  343. $address = json_decode($row->extend->address_json,true);
  344. if ($address) {
  345. $area = (new Area)->whereIn('id',[$address['province_id'],$address['city_id'],$address['area_id']])->column('name', 'id');
  346. $row['addressText'] = $area[$address['province_id']].$area[$address['city_id']].$area[$address['area_id']].' '.$address['address'];
  347. $row['address'] = $address;
  348. }
  349. $this->view->assign("row", $row);
  350. return $this->view->fetch();
  351. }
  352. /**
  353. * 商品管理
  354. */
  355. public function product($ids = null)
  356. {
  357. if ($this->request->isPost()) {
  358. $this->success();
  359. }
  360. $row = $this->model->get($ids, ['product','evaluate']);
  361. $this->view->assign('product', $row->product);
  362. $evaluate = [];
  363. foreach ($row->evaluate as $key => $item) {
  364. $evaluate[$item['product_id']] = $item;
  365. }
  366. $this->view->assign('order', $row);
  367. $this->view->assign('evaluate', $evaluate);
  368. return $this->view->fetch();
  369. }
  370. /**
  371. * 退货管理
  372. */
  373. public function refund($ids = null)
  374. {
  375. $row = $this->model->get($ids, ['refund']);
  376. if ($row['status'] != \app\admin\model\unishop\Order::STATUS_REFUND) {
  377. $this->error(__('This order is not returned'));
  378. }
  379. if ($this->request->isPost()) {
  380. $params = $this->request->post("row/a");
  381. if ($params) {
  382. $params = $this->preExcludeFields($params);
  383. $result = false;
  384. Db::startTrans();
  385. try {
  386. // 退款
  387. if($params['refund_action'] == 1) {
  388. $params['had_refund'] = time();
  389. Hook::add('order_refund', 'addons\\unishop\\behavior\\Order');
  390. }
  391. $updatetime = $this->request->post('updatetime');
  392. // 乐观锁
  393. $result = $this->model->allowField(true)->save($params, ['id' => $ids, 'updatetime' => $updatetime]);
  394. if (!$result) {
  395. throw new Exception(__('Data had been update before saved, close windows and do it again'));
  396. }
  397. Db::commit();
  398. } catch (ValidateException $e) {
  399. Db::rollback();
  400. $this->error($e->getMessage());
  401. } catch (PDOException $e) {
  402. Db::rollback();
  403. $this->error($e->getMessage());
  404. } catch (Exception $e) {
  405. Db::rollback();
  406. $this->error($e->getMessage());
  407. }
  408. if ($result !== false) {
  409. Hook::listen('order_refund', $row);
  410. $this->success();
  411. } else {
  412. $this->error(__('No rows were updated'));
  413. }
  414. }
  415. $this->error(__('Parameter %s can not be empty', ''));
  416. }
  417. $products = $row->product;
  418. $refundProducts = $row->refundProduct;
  419. foreach ($products as &$product) {
  420. $product['choose'] = 0;
  421. foreach ($refundProducts as $refundProduct) {
  422. if ($product['id'] == $refundProduct['order_product_id']) {
  423. $product['choose'] = 1;
  424. }
  425. }
  426. }
  427. if ($row->refund) {
  428. $refund = $row->refund->append(['receiving_status_text', 'service_type_text'])->toArray();
  429. } else {
  430. $refund = [
  431. 'service_type' => 0,
  432. 'express_number' => -1,
  433. 'receiving_status_text' => -1,
  434. 'receiving_status' => -1,
  435. 'service_type_text' => -1,
  436. 'amount' => -1,
  437. 'reason_type' => -1,
  438. 'refund_explain' => -1,
  439. ];
  440. }
  441. $this->view->assign('row', $row);
  442. $this->view->assign('product', $products);
  443. $this->view->assign('refund', $refund);
  444. return $this->view->fetch();
  445. }
  446. /**
  447. * 回收站
  448. */
  449. public function recyclebin()
  450. {
  451. //设置过滤方法
  452. $this->request->filter(['strip_tags']);
  453. if ($this->request->isAjax()) {
  454. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  455. $total = $this->model
  456. ->onlyTrashed()
  457. ->alias('order')
  458. ->join('user', 'user.id = order.user_id')
  459. ->where($where)
  460. ->count();
  461. $list = $this->model
  462. ->onlyTrashed()
  463. ->alias('order')
  464. ->join('user', 'user.id = order.user_id')
  465. ->where($where)
  466. ->field('order.*,user.username')
  467. ->order($sort, $order)
  468. ->limit($offset, $limit)
  469. ->select();
  470. $list = collection($list)->toArray();
  471. foreach ($list as &$item) {
  472. $item['id'] = (string)$item['id'];
  473. $item['user'] = [];
  474. $item['user']['username'] = $item['username'] ? $item['username'] : __('Tourist');
  475. $item['have_paid_status'] = $item['have_paid'];
  476. $item['have_delivered_status'] = $item['have_delivered'];
  477. $item['have_received_status'] = $item['have_received'];
  478. $item['have_commented_status'] = $item['have_commented'];
  479. }
  480. $result = array("total" => $total, "rows" => $list);
  481. return json($result);
  482. }
  483. return $this->view->fetch();
  484. }
  485. public function export(){
  486. $order_model=New \app\admin\model\unishop\Order();
  487. $list = $order_model
  488. ->alias('o')
  489. ->join('user', 'user.id = o.user_id')
  490. ->join('unishop_order_product', 'unishop_order_product.order_id = o.id')
  491. ->where([
  492. 'o.status'=>1
  493. ])
  494. ->field('
  495. out_trade_no,
  496. user.username,
  497. user.nickname,
  498. user.floor,
  499. user.email,
  500. unishop_order_product.title,
  501. unishop_order_product.number as number,
  502. unishop_order_product.price,
  503. FROM_UNIXTIME(o.createtime,\'%Y-%m-%d %H:%i:%S\'),
  504. if(o.is_carry=1,\'已提货\',\'未提货\'),
  505. o.remark')
  506. ->group("unishop_order_product.id")
  507. ->order("o.createtime","desc")
  508. ->select();
  509. $list = collection($list)->toArray();
  510. $title = ['订单号','工号','姓名','楼层','邮箱','商品','购买数量','总金额','下单时间','是否提货','备注'];
  511. // Create new Spreadsheet object
  512. $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
  513. $sheet = $spreadsheet->getActiveSheet();
  514. $sheet->setTitle("订单信息");
  515. // 方法一,使用 setCellValueByColumnAndRow
  516. //表头
  517. //设置单元格内容
  518. foreach ($title as $key => $value) {
  519. // 单元格内容写入
  520. $sheet->setCellValueByColumnAndRow($key + 1, 1, $value);
  521. }
  522. $row = 2; // 从第二行开始
  523. foreach ($list as $item) {
  524. $column = 1;
  525. foreach ($item as $value) {
  526. // 单元格内容写入
  527. $sheet->setCellValueByColumnAndRow($column, $row, $value);
  528. $column++;
  529. }
  530. $row++;
  531. }
  532. $sheet_two = $spreadsheet->createSheet(2)->setTitle('商品信息');
  533. $title1=["商品名称","件数","单价","总价"];
  534. $product=new \app\admin\model\unishop\OrderProduct();
  535. $product_list = $product->alias("p")
  536. ->join("unishop_order","p.order_id = unishop_order.id")
  537. ->where([
  538. 'unishop_order.have_received'=>0,
  539. 'unishop_order.status'=>1
  540. ])
  541. ->field('
  542. p.title,
  543. SUM(p.number) num,
  544. p.price,
  545. SUM(p.number)*p.price as total,
  546. p.product_id')
  547. ->group("p.id")
  548. ->select();
  549. $product_list = collection($product_list)->toArray();
  550. $product_arr=[];
  551. foreach ($product_list as $tmp_product){
  552. if (isset($product_arr[$tmp_product['product_id']])){
  553. $product_arr[$tmp_product['product_id']]["num"]+=$tmp_product['num'];
  554. $product_arr[$tmp_product['product_id']]["total"]+=$tmp_product['total'];
  555. }else{
  556. $product_arr[$tmp_product['product_id']]=$tmp_product;
  557. }
  558. }
  559. foreach ($title1 as $key => $value) {
  560. // 单元格内容写入
  561. $sheet_two->setCellValueByColumnAndRow($key + 1, 1, $value);
  562. }
  563. $row=2;
  564. foreach ($product_arr as $item) {
  565. unset($item['product_id']);
  566. $column = 1;
  567. foreach ($item as $value) {
  568. // 单元格内容写入
  569. $sheet_two->setCellValueByColumnAndRow($column, $row, $value);
  570. $column++;
  571. }
  572. $row++;
  573. }
  574. $title2=["商品名称","总库存","剩余库存"];
  575. $sheet_three= $spreadsheet->createSheet(3)->setTitle('库存信息');
  576. foreach ($title2 as $key => $value) {
  577. // 单元格内容写入
  578. $sheet_three->setCellValueByColumnAndRow($key + 1, 1, $value);
  579. }
  580. $product1=new \addons\unishop\model\Product();
  581. $product_list1 = $product1
  582. ->field('
  583. id,
  584. title,
  585. (stock+real_sales),
  586. stock')
  587. ->select();
  588. $product_list1 = collection($product_list1)->toArray();
  589. $row=2;
  590. foreach ($product_list1 as $tmp_product){
  591. unset($tmp_product["product_id"]);
  592. $column = 1;
  593. foreach ($tmp_product as $value) {
  594. // 单元格内容写入
  595. $sheet_three->setCellValueByColumnAndRow($column, $row, $value);
  596. $column++;
  597. }
  598. $row++;
  599. }
  600. $file_name="导出订单.xlsx";
  601. // Redirect output to a client’s web browser (Xlsx)
  602. header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  603. header('Content-Disposition: attachment;filename='.$file_name);
  604. header('Cache-Control: max-age=0');
  605. // If you're serving to IE 9, then the following may be needed
  606. header('Cache-Control: max-age=1');
  607. // If you're serving to IE over SSL, then the following may be needed
  608. header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
  609. header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
  610. header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
  611. header('Pragma: public'); // HTTP/1.0
  612. $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
  613. $writer->save('php://output');
  614. exit;
  615. }
  616. public function finish(){
  617. $this->model->save(
  618. ['have_received'=>time(),
  619. "have_delivered"=>time()],
  620. ['have_received'=>0,
  621. 'status'=>1]
  622. );
  623. $this->success("提交成功", null);
  624. }
  625. public function doRefund(){
  626. $order_id = $this->request->get('id');
  627. $refund_fee = $this->request->get("refund_fee",0);
  628. $order = $this->model->where([
  629. 'id' => $order_id,
  630. 'status'=>1,//订单状态正常
  631. // 'have_paid'=>[">",0],//已支付
  632. // 'had_refund'=>0
  633. ])->find();
  634. if (!$order){
  635. $this->error("订单已取消,请勿重复操作");
  636. }
  637. if ($order->have_paid>0){
  638. if ($order['total_price']<$refund_fee) {
  639. $this->error("退款金额不能高于订单总金额");
  640. }
  641. //已支付
  642. self::refundOrder($order,$refund_fee);
  643. }else{
  644. $order->status = \addons\unishop\model\Order::STATUS_CANCEL;
  645. $order->save();
  646. }
  647. //回退库存
  648. $this->refundProduct($order->id);
  649. $this->success("提交成功", null);
  650. }
  651. static function refundOrder($order,$refund_fee){
  652. if ($refund_fee == 0) {//如果未传入金额,则使用总金额
  653. $refund_fee = $order['total_price'];
  654. }
  655. $order->status = \addons\unishop\model\Order::STATUS_REFUND;
  656. $order->refund_status = \addons\unishop\model\Order::REFUND_STATUS_AGREE;
  657. $order->refund_fee = $refund_fee;
  658. $result = $order->save();
  659. if ($result !== false){
  660. //order_id:订单ID name:订单名称 total_fee:总金额-元 refund_fee退款金额
  661. $param = [
  662. "order_id"=>$order['out_trade_no'],
  663. "total_fee"=>$order['total_price'],
  664. "refund_fee"=>$refund_fee,
  665. "memo"=>'订单退款',
  666. ];
  667. PayService::cancel($param,$order["pay_type"]);
  668. return;
  669. }
  670. }
  671. public function refundProduct($order_id){
  672. $model=new OrderProduct();
  673. $order =$model->where([
  674. 'order_id' => $order_id,
  675. ])->select();
  676. if (!$order){
  677. return;
  678. }
  679. $list = collection($order)->toArray();
  680. $product = new \app\admin\model\unishop\Product();
  681. foreach ($list as $val){
  682. try {
  683. $product->where(["id" => $val['product_id']])->setInc("stock", $val["number"]);
  684. $product->where(["id" => $val['product_id']])->setInc("real_sales", -$val["number"]);
  685. } catch (Exception $e) {
  686. }
  687. }
  688. }
  689. public function carry($ids = null)
  690. {
  691. $this->model->save(
  692. ['is_carry'=>1],
  693. ['id'=>["in",$ids]]
  694. );
  695. $this->success("确认成功", null);
  696. }
  697. public function refundShow(){
  698. $id = $this->request->get("id");
  699. $refund_fee = $this->request->get("refund_fee");
  700. $this->view->assign('id', $id);
  701. $this->view->assign('refund_fee', $refund_fee);
  702. return $this->view->fetch();
  703. }
  704. }