Order.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | framework
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2014~2018 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://framework.thinkadmin.top
  8. // +----------------------------------------------------------------------
  9. // | 开源协议 ( https://mit-license.org )
  10. // +----------------------------------------------------------------------
  11. // | github开源项目:https://github.com/zoujingli/framework
  12. // +----------------------------------------------------------------------
  13. namespace app\store\controller\api\member;
  14. use app\store\controller\api\Member;
  15. use app\store\service\GoodsService;
  16. use library\tools\Data;
  17. use think\Db;
  18. /**
  19. * 订单接口管理
  20. * Class Order
  21. * @package app\store\controller\api\member
  22. */
  23. class Order extends Member
  24. {
  25. /**
  26. * 创建商城订单
  27. * @throws \think\db\exception\DataNotFoundException
  28. * @throws \think\db\exception\ModelNotFoundException
  29. * @throws \think\exception\DbException
  30. * 商品ID1@商品规格1@商品数量1||商品ID2@商品规格2@商品数量2
  31. */
  32. public function set()
  33. {
  34. // 商品规则
  35. $rule = $this->request->post('rule', '');
  36. if (empty($rule)) $this->error('下单商品规则不能为空!');
  37. // 订单处理
  38. list($orderList, $order) = [[], [
  39. 'status' => '1', 'mid' => $this->mid,
  40. 'order_no' => Data::uniqidNumberCode(12),
  41. 'from_mid' => $this->request->post('from_mid', '0'),
  42. ]];
  43. // 推荐人处理
  44. if (intval($order['from_mid']) === intval($this->mid)) {
  45. $order['from_mid'] = '0';
  46. } elseif ($order['from_mid'] > 0) {
  47. if (Db::name('StoreMember')->where(['id' => $order['from_mid']])->count() < 1) {
  48. $this->error('无效的推荐会员ID,稍候再试!');
  49. }
  50. }
  51. foreach (explode('||', $rule) as $item) {
  52. list($goods_id, $goods_spec, $number) = explode('@', $item);
  53. // 商品信息检查
  54. $goods = Db::name('StoreGoods')->where(['id' => $goods_id, 'status' => '1', 'is_deleted' => '0'])->find();
  55. if (empty($goods)) $this->error('查询商品主体信息失败,请稍候再试!');
  56. $spec = Db::name('StoreGoodsList')->where(['goods_id' => $goods_id, 'goods_spec' => $goods_spec])->find();
  57. if (empty($spec)) $this->error('查询商品规则信息失败,请稍候再试!');
  58. // 商品库存检查
  59. if ($spec['number_sales'] + $number > $spec['number_stock']) {
  60. $this->error('商品库存不足,请购买其它商品!');
  61. }
  62. // 订单详情处理
  63. array_push($orderList, [
  64. 'mid' => $order['mid'],
  65. 'from_mid' => $order['from_mid'],
  66. 'order_no' => $order['order_no'],
  67. // 商品信息字段管理
  68. 'goods_id' => $goods_id,
  69. 'goods_spec' => $goods_spec,
  70. 'goods_logo' => $goods['logo'],
  71. 'goods_title' => $goods['title'],
  72. 'number_goods' => $number,
  73. 'number_express' => $spec['number_express'],
  74. // 费用字段处理
  75. 'price_market' => $spec['price_market'],
  76. 'price_selling' => $spec['price_selling'],
  77. 'price_real' => $spec['price_selling'] * $number,
  78. 'price_express' => $goods['price_express'],
  79. // 返利字段处理
  80. 'price_rate' => $goods['price_rate'],
  81. 'price_rate_amount' => $spec['price_selling'] * $number * $goods['price_rate'] / 100,
  82. ]);
  83. }
  84. $order['price_goods'] = array_sum(array_column($orderList, 'price_real')) + 0;
  85. $order['price_express'] = max(array_column($orderList, 'price_express')) + 0;
  86. $order['price_total'] = $order['price_goods'] + $order['price_express'];
  87. $order['price_rate_amount'] = array_sum(array_column($orderList, 'price_rate_amount')) + 0;
  88. try {
  89. // 订单数据写入
  90. Db::name('StoreOrder')->insert($order);
  91. Db::name('StoreOrderList')->insertAll($orderList);
  92. // 同步商品库存及销量
  93. foreach (array_unique(array_column($orderList, 'goods_id')) as $goodsId) GoodsService::syncStock($goodsId);
  94. $this->success('订单创建成功,请补全收货信息后支付!', ['order' => $order]);
  95. } catch (\think\exception\HttpResponseException $exception) {
  96. throw $exception;
  97. } catch (\Exception $e) {
  98. $this->error("创建订单失败,请稍候再试!{$e->getMessage()}");
  99. }
  100. }
  101. /**
  102. * 订单信息完成
  103. * @throws \think\Exception
  104. * @throws \think\db\exception\DataNotFoundException
  105. * @throws \think\db\exception\ModelNotFoundException
  106. * @throws \think\exception\DbException
  107. * @throws \think\exception\PDOException
  108. */
  109. public function perfect()
  110. {
  111. $data = $this->_input([
  112. 'order_no' => $this->request->post('order_no'),
  113. 'address_id' => $this->request->post('address_id'),
  114. ], [
  115. 'order_no' => 'require',
  116. 'address_id' => 'require',
  117. ], [
  118. 'order_no.require' => '订单号不能为空!',
  119. 'address_id.require' => '收货地址ID不能为空(0自提可以为空)',
  120. ]);
  121. $map = ['order_no' => $data['order_no'], 'mid' => $this->member['id']];
  122. $order = Db::name('StoreOrder')->whereIn('status', ['1', '2'])->where($map)->find();
  123. if (empty($order)) $this->error('订单异常,请返回商品重新下单!');
  124. $update = ['status' => '2'];
  125. $where = ['id' => $data['address_id'], 'mid' => $this->member['id']];
  126. $address = Db::name('StoreMemberAddress')->where($where)->find();
  127. if (empty($address)) $this->error('会员收货地址异常,请刷新页面重试!');
  128. $update['express_address_id'] = $data['address_id'];
  129. $update['express_name'] = $address['name'];
  130. $update['express_phone'] = $address['phone'];
  131. $update['express_province'] = $address['province'];
  132. $update['express_city'] = $address['city'];
  133. $update['express_area'] = $address['area'];
  134. $update['express_address'] = $address['address'];
  135. if (Db::name('StoreOrder')->where($map)->update($update) !== false) {
  136. $params = $this->getPayParams($order['order_no'], $order['price_total']);
  137. $this->success('更新订单会员信息成功!', $params);
  138. }
  139. $this->error('更新订单会员信息失败,请稍候再试!');
  140. }
  141. /**
  142. * 获取订单支付状态
  143. * @throws \think\db\exception\DataNotFoundException
  144. * @throws \think\db\exception\ModelNotFoundException
  145. * @throws \think\exception\DbException
  146. */
  147. public function pay()
  148. {
  149. $order_no = $this->request->post('order_no');
  150. $order = Db::name('StoreOrder')->where(['order_no' => $order_no])->find();
  151. if (empty($order_no)) $this->error('获取订单信息异常,请稍候再试!');
  152. if ($order['pay_state']) $this->error('订单已经完成支付,不需要再次支付!');
  153. if ($order['status'] <> 2) $this->error('该订单不能发起支付哦!');
  154. try {
  155. $param = $this->getPayParams($order['order_no'], $order['price_total']);
  156. $this->success('获取订单支付参数成功!', $param);
  157. } catch (\think\exception\HttpResponseException $exception) {
  158. throw $exception;
  159. } catch (\Exception $e) {
  160. $this->error("获取订单支付参数失败,{$e->getMessage()}");
  161. }
  162. }
  163. /**
  164. * 获取订单支付参数
  165. * @param string $order_no
  166. * @param string $pay_price
  167. * @return array
  168. */
  169. private function getPayParams($order_no, $pay_price)
  170. {
  171. $options = [
  172. 'body' => '商城订单支付',
  173. 'openid' => $this->openid,
  174. 'out_trade_no' => $order_no,
  175. // 'total_fee' => '1',
  176. 'total_fee' => $pay_price * 100,
  177. 'trade_type' => 'JSAPI',
  178. 'notify_url' => url('@store/api.notify/wxpay', '', false, true),
  179. 'spbill_create_ip' => $this->request->ip(),
  180. ];
  181. try {
  182. $pay = \We::WePayOrder(config('wechat.miniapp'));
  183. $info = $pay->create($options);
  184. if ($info['return_code'] === 'SUCCESS' && $info['result_code'] === 'SUCCESS') {
  185. return $pay->jsapiParams($info['prepay_id']);
  186. }
  187. if (isset($info['err_code_des'])) throw new \think\Exception($info['err_code_des']);
  188. } catch (\Exception $e) {
  189. $this->error("创建订单失败参数失败,{$e->getMessage()}");
  190. }
  191. }
  192. /**
  193. * 获取订单列表
  194. * @throws \think\Exception
  195. * @throws \think\db\exception\DataNotFoundException
  196. * @throws \think\db\exception\ModelNotFoundException
  197. * @throws \think\exception\DbException
  198. * @throws \think\exception\PDOException
  199. */
  200. public function gets()
  201. {
  202. $where = [['mid', 'eq', $this->mid]];
  203. if ($this->request->has('order_no', 'post', true)) {
  204. $where[] = ['order_no', 'eq', $this->request->post('order_no')];
  205. } else {
  206. $where[] = ['status', 'in', ['0', '2', '3', '4', '5']];
  207. }
  208. if ($this->request->has('status', 'post', true)) {
  209. $where[] = ['status', 'eq', $this->request->post('status')];
  210. }
  211. $result = $this->_query('StoreOrder')->where($where)->order('id desc')->page(true, false, false, 20);
  212. $glist = Db::name('StoreOrderList')->whereIn('order_no', array_unique(array_column($result['list'], 'order_no')))->select();
  213. foreach ($result['list'] as &$vo) {
  214. list($vo['goods_count'], $vo['list']) = [0, []];
  215. foreach ($glist as $goods) if ($vo['order_no'] === $goods['order_no']) {
  216. $vo['list'][] = $goods;
  217. $vo['goods_count'] += $goods['number_goods'];
  218. }
  219. }
  220. $this->success('获取订单列表成功!', $result);
  221. }
  222. /**
  223. * 订单取消
  224. * @throws \think\Exception
  225. * @throws \think\db\exception\DataNotFoundException
  226. * @throws \think\db\exception\ModelNotFoundException
  227. * @throws \think\exception\DbException
  228. * @throws \think\exception\PDOException
  229. */
  230. public function cancel()
  231. {
  232. $where = [
  233. 'mid' => $this->member['id'],
  234. 'order_no' => $this->request->post('order_no'),
  235. ];
  236. $order = Db::name('StoreOrder')->where($where)->find();
  237. if (empty($order)) $this->error('待取消的订单不存在,请稍候再试!');
  238. if (in_array($order['status'], ['1', '2'])) {
  239. $result = Db::name('StoreOrder')->where($where)->update([
  240. 'status' => '0',
  241. 'cancel_state' => '1',
  242. 'cancel_at' => date('Y-m-d H:i:s'),
  243. 'cancel_desc' => '用户主动取消订单!',
  244. ]);
  245. if ($result !== false && \app\store\service\OrderService::syncStock($order['order_no'])) {
  246. $this->success('订单取消成功!');
  247. }
  248. $this->error('订单取消失败,请稍候再试!');
  249. }
  250. $this->error('该订单状态不允许取消哦~');
  251. }
  252. /**
  253. * 订单确认收货
  254. * @throws \think\Exception
  255. * @throws \think\db\exception\DataNotFoundException
  256. * @throws \think\db\exception\ModelNotFoundException
  257. * @throws \think\exception\DbException
  258. * @throws \think\exception\PDOException
  259. */
  260. public function confirm()
  261. {
  262. $where = [
  263. 'mid' => $this->member['id'],
  264. 'order_no' => $this->request->post('order_no'),
  265. ];
  266. $order = Db::name('StoreOrder')->where($where)->find();
  267. if (empty($order)) $this->error('待确认的订单不存在,请稍候再试!');
  268. if (in_array($order['status'], ['4'])) {
  269. $result = Db::name('StoreOrder')->where($where)->update(['status' => '5']);
  270. if ($result !== false) $this->success('订单确认成功!');
  271. $this->error('订单取确认失败,请稍候再试!');
  272. }
  273. $this->error('该订单状态不允许确认哦~');
  274. }
  275. /**
  276. * 订单状态统计
  277. * @throws \think\db\exception\DataNotFoundException
  278. * @throws \think\db\exception\ModelNotFoundException
  279. * @throws \think\exception\DbException
  280. */
  281. public function total()
  282. {
  283. $result = Db::name('StoreOrder')->fieldRaw('mid,status,count(1) count')
  284. ->where(['mid' => $this->mid])->group('status')->select();
  285. $this->success('获取订单统计记录!', $result);
  286. }
  287. }