OrderController.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controllers\User;
  4. use App\Controllers\BaseController;
  5. use App\Models\Invoice;
  6. use App\Models\Order;
  7. use App\Models\Product;
  8. use App\Models\UserCoupon;
  9. use App\Utils\Tools;
  10. use Slim\Http\Response;
  11. use Slim\Http\ServerRequest;
  12. use voku\helper\AntiXSS;
  13. final class OrderController extends BaseController
  14. {
  15. public static array $details = [
  16. 'field' => [
  17. 'op' => '操作',
  18. 'id' => '订单ID',
  19. 'product_id' => '商品ID',
  20. 'product_type' => '商品类型',
  21. 'product_name' => '商品名称',
  22. 'coupon' => '优惠码',
  23. 'price' => '金额',
  24. 'status' => '状态',
  25. 'create_time' => '创建时间',
  26. 'update_time' => '更新时间',
  27. ],
  28. ];
  29. public function order(ServerRequest $request, Response $response, array $args)
  30. {
  31. return $response->write(
  32. $this->view()
  33. ->assign('details', self::$details)
  34. ->fetch('user/order/index.tpl')
  35. );
  36. }
  37. public function create(ServerRequest $request, Response $response, array $args)
  38. {
  39. $antiXss = new AntiXSS();
  40. $product_id = $antiXss->xss_clean($request->getQueryParams()['product_id']) ?? null;
  41. if ($product_id === null || $product_id === '') {
  42. return $response->withRedirect('/user/product');
  43. }
  44. $product = Product::where('id', $product_id)->first();
  45. $product->content = \json_decode($product->content);
  46. return $response->write(
  47. $this->view()
  48. ->assign('product', $product)
  49. ->fetch('user/order/create.tpl')
  50. );
  51. }
  52. public function detail(ServerRequest $request, Response $response, array $args)
  53. {
  54. $antiXss = new AntiXSS();
  55. $id = $antiXss->xss_clean($args['id']);
  56. $order = Order::where('user_id', $this->user->id)->where('id', $id)->first();
  57. if ($order === null) {
  58. return $response->withRedirect('/user/order');
  59. }
  60. $order->product_type = Tools::getOrderProductType($order);
  61. $order->status = Tools::getOrderStatus($order);
  62. $order->create_time = Tools::toDateTime($order->create_time);
  63. $order->update_time = Tools::toDateTime($order->update_time);
  64. $product_content = \json_decode($order->product_content);
  65. $invoice = Invoice::where('order_id', $id)->first();
  66. $invoice->status = Tools::getInvoiceStatus($invoice);
  67. $invoice->create_time = Tools::toDateTime($invoice->create_time);
  68. $invoice->update_time = Tools::toDateTime($invoice->update_time);
  69. $invoice->pay_time = Tools::toDateTime($invoice->pay_time);
  70. $invoice_content = \json_decode($invoice->content);
  71. return $response->write(
  72. $this->view()
  73. ->assign('order', $order)
  74. ->assign('invoice', $invoice)
  75. ->assign('product_content', $product_content)
  76. ->assign('invoice_content', $invoice_content)
  77. ->fetch('user/order/view.tpl')
  78. );
  79. }
  80. public function process(ServerRequest $request, Response $response, array $args)
  81. {
  82. $antiXss = new AntiXSS();
  83. $coupon_raw = $antiXss->xss_clean($request->getParam('coupon'));
  84. $product_id = $antiXss->xss_clean($request->getParam('product_id'));
  85. $product = Product::find($product_id);
  86. if ($product === null) {
  87. return $response->withJson([
  88. 'ret' => 0,
  89. 'msg' => '商品不存在',
  90. ]);
  91. }
  92. if ($product->stock === 0) {
  93. return $response->withJson([
  94. 'ret' => 0,
  95. 'msg' => '商品库存不足',
  96. ]);
  97. }
  98. $buy_price = $product->price;
  99. $user = $this->user;
  100. if ($coupon_raw !== '') {
  101. $coupon = UserCoupon::where('code', $coupon_raw)->first();
  102. if ($coupon === null) {
  103. return $response->withJson([
  104. 'ret' => 0,
  105. 'msg' => '优惠码无效',
  106. ]);
  107. }
  108. if ($coupon->expire_time < \time()) {
  109. return $response->withJson([
  110. 'ret' => 0,
  111. 'msg' => '优惠码无效',
  112. ]);
  113. }
  114. $coupon_limit = \json_decode($coupon->limit);
  115. if ((int) $coupon_limit->disabled === 1) {
  116. return $response->withJson([
  117. 'ret' => 0,
  118. 'msg' => '优惠码无效',
  119. ]);
  120. }
  121. if ($coupon_limit->product_id !== '') {
  122. $product_limit = explode(',', $coupon_limit->product_id);
  123. if (! in_array($product_id, $product_limit)) {
  124. return $response->withJson([
  125. 'ret' => 0,
  126. 'msg' => '优惠码无效',
  127. ]);
  128. }
  129. }
  130. $coupon_use_limit = $coupon_limit->use_time;
  131. if ($coupon_use_limit > 0) {
  132. $use_count = Order::where('user_id', $user->id)->where('coupon', $coupon->code)->count();
  133. if ($use_count >= $coupon_use_limit) {
  134. return $response->withJson([
  135. 'ret' => 0,
  136. 'msg' => '优惠码无效',
  137. ]);
  138. }
  139. }
  140. $content = \json_decode($coupon->content);
  141. if ($content->type === 'percentage') {
  142. $discount = $product->price * $content->value / 100;
  143. } else {
  144. $discount = $content->value;
  145. }
  146. $buy_price = $product->price - $discount;
  147. }
  148. $product_limit = \json_decode($product->limit);
  149. if ($product_limit->class_required !== '') {
  150. if ($user->class < $product_limit->class_required) {
  151. return $response->withJson([
  152. 'ret' => 0,
  153. 'msg' => '账户不满足购买条件',
  154. ]);
  155. }
  156. }
  157. if ($product_limit->node_group_required !== '') {
  158. if ($user->node_group !== $product_limit->node_group_required) {
  159. return $response->withJson([
  160. 'ret' => 0,
  161. 'msg' => '账户不满足购买条件',
  162. ]);
  163. }
  164. }
  165. if ($product_limit->new_user_required !== 0) {
  166. $order_count = Order::where('user_id', $user->id)->count();
  167. if ($order_count > 0) {
  168. return $response->withJson([
  169. 'ret' => 0,
  170. 'msg' => '账户不满足购买条件',
  171. ]);
  172. }
  173. }
  174. $order = new Order();
  175. $order->user_id = $user->id;
  176. $order->product_id = $product->id;
  177. $order->product_type = $product->type;
  178. $order->product_name = $product->name;
  179. $order->product_content = $product->content;
  180. $order->coupon = $coupon_raw;
  181. $order->price = $buy_price;
  182. $order->status = 'pending_payment';
  183. $order->create_time = time();
  184. $order->update_time = time();
  185. $order->save();
  186. $invoice_content[] = [
  187. 'content_id' => 0,
  188. 'name' => $product->price,
  189. 'price' => $product->content,
  190. ];
  191. if ($coupon_raw !== '') {
  192. $invoice_content[] = [
  193. 'content_id' => 1,
  194. 'name' => '优惠码 ' . $coupon_raw,
  195. 'price' => '-' . $discount,
  196. ];
  197. }
  198. $invoice = new Invoice();
  199. $invoice->user_id = $user->id;
  200. $invoice->order_id = $order->id;
  201. $invoice->content = \json_encode($invoice_content);
  202. $invoice->price = $buy_price;
  203. $invoice->status = 'unpaid';
  204. $invoice->create_time = \time();
  205. $invoice->update_time = \time();
  206. $invoice->pay_time = 0;
  207. $invoice->save();
  208. return $response->withJson([
  209. 'ret' => 1,
  210. 'msg' => '成功创建订单,正在跳转账单页面',
  211. 'invoice_id' => $invoice->id,
  212. ]);
  213. }
  214. public function ajax(ServerRequest $request, Response $response, array $args)
  215. {
  216. $orders = Order::orderBy('id', 'desc')->where('user_id', $this->user->id)->get();
  217. foreach ($orders as $order) {
  218. $order->op = '<a class="btn btn-blue" href="/user/order/' . $order->id . '/view">查看</a>';
  219. if ($order->status === 'pending_payment') {
  220. $invoice_id = Invoice::where('order_id', $order->id)->first()->id;
  221. $order->op .= '
  222. <a class="btn btn-red" href="/user/invoice/' . $invoice_id . '/view">支付</a>';
  223. }
  224. $order->product_type = Tools::getOrderProductType($order);
  225. $order->status = Tools::getOrderStatus($order);
  226. $order->create_time = Tools::toDateTime($order->create_time);
  227. $order->update_time = Tools::toDateTime($order->update_time);
  228. }
  229. return $response->withJson([
  230. 'orders' => $orders,
  231. ]);
  232. }
  233. }