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.
 
 
 
 
 
 

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