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.

Order.php 25 KiB

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