Order.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <?php
  2. namespace app\controller\api;
  3. use app\extra\basic\Base;
  4. use app\extra\dyLife\Crypt;
  5. use app\extra\dyMini\Pay;
  6. use app\middleware\AuthMiddleware;
  7. use app\model\saas\SaasOrder;
  8. use app\service\saas\OrderService;
  9. use DI\Attribute\Inject;
  10. use LinFly\Annotation\Attributes\Route\Controller;
  11. use LinFly\Annotation\Attributes\Route\GetMapping;
  12. use LinFly\Annotation\Attributes\Route\Middleware;
  13. use LinFly\Annotation\Attributes\Route\PostMapping;
  14. use support\Request;
  15. use support\Response;
  16. #[Controller("/dy/order"),Middleware(AuthMiddleware::class)]
  17. class Order extends Base
  18. {
  19. #[Inject]
  20. protected SaasOrder $model;
  21. #[Inject]
  22. protected OrderService $service;
  23. #[GetMapping('list')]
  24. public function getDataList(Request $request): Response
  25. {
  26. try {
  27. $param = $request->all();
  28. if (!empty($param['size'])) {
  29. $param['pageSize'] = $param['size'];
  30. }
  31. $param['openid'] = $request->user['openid'];
  32. $data = $this->service->setModel()->getList($param);
  33. return successTrans("success.data",pageFormat($data));
  34. } catch (\Throwable $th) {
  35. return error($th->getMessage());
  36. }
  37. }
  38. #[PostMapping("refund")]
  39. public function orderRefund(Request $request): Response
  40. {
  41. try {
  42. $param = $this->_valid([
  43. "order.require" => trans("empty.require"),
  44. "refund.require" => trans("empty.require"),
  45. ],$request->method());
  46. if (!is_array($param)) return error($param);
  47. $order = $this->model->where("order_sn",$param['order'])->with(['product','poi'])->findOrEmpty();
  48. if ($order->isEmpty()) return errorTrans("empty.data");
  49. if ($order['openid'] <> $request->user['openid']) return errorTrans("empty.data");
  50. if ($order['status'] <> 1) return error("当前订单不支持退款");
  51. $reason = explode(",",$param['refund']);
  52. $payParam = [
  53. "order_sn" => $order['order_sn'],
  54. "total" => $order['pay_money'],
  55. "reason" => $reason[0]??'不想要了',
  56. "out_refund_no" => $order['pay_sn'],
  57. "notify_url" => "https://tran.jsshuita.cn/notify/refund"
  58. ];
  59. $byteAuthorization = (new Pay)->config([
  60. "appid" => sConf("wechat.mini_appid"),
  61. "secret" => sConf("wechat.mini_secret"),
  62. "salt" => sConf("wechat.mch_salt"),
  63. ])->createRefund($payParam);
  64. if (!$byteAuthorization) return error("发起退款失败");
  65. $order->status = 4;
  66. $order->refund_apply = getDateFull();
  67. $state = $order->save();
  68. if (!$state) return errorTrans("error.data");
  69. return successTrans("提交申请成功");
  70. } catch (\Throwable $throwable) {
  71. return error($throwable->getMessage());
  72. }
  73. }
  74. #[GetMapping('detail')]
  75. public function getDataDetail(Request $request): Response
  76. {
  77. try {
  78. $param = $this->_valid([
  79. "order.require" => trans("empty.require")
  80. ],$request->method());
  81. if (!is_array($param)) return error($param);
  82. $order = $this->model->where("order_sn",$param['order'])->with(['product','poi'])->findOrEmpty();
  83. if ($order->isEmpty()) return errorTrans("empty.data");
  84. return $this->encode("ok",$order->toArray());
  85. } catch (\Throwable $th) {
  86. return error($th->getMessage());
  87. }
  88. }
  89. #[GetMapping("confirm")]
  90. public function confirmOrder(Request $request): Response
  91. {
  92. try {
  93. $param = $this->_valid([
  94. "order.require" => trans("empty.require")
  95. ],$request->method());
  96. if (!is_array($param)) return error($param);
  97. $order = $this->model->where("order_sn",$param['order'])->with(['product','poi'])->findOrEmpty();
  98. if ($order->isEmpty()) return errorTrans("empty.data");
  99. if ($order['status'] <> 0) return errorTrans("empty.data");
  100. return $this->encode("ok",$order->toArray());
  101. } catch (\Throwable $throwable) {
  102. return error($throwable->getMessage());
  103. }
  104. }
  105. /**
  106. * 发起支付
  107. * @param Request $request
  108. * @return Response
  109. */
  110. #[PostMapping("toPay")]
  111. public function orderPay(Request $request): Response
  112. {
  113. try {
  114. $param = $this->_valid([
  115. "order.require" => trans("empty.require"),
  116. "mobile.default" => ""
  117. ],$request->method());
  118. if (!is_array($param)) return error($param);
  119. $order = $this->model->where("order_sn",$param['order'])->with(['product','poi'])->findOrEmpty();
  120. $payParam = [
  121. "order_sn" => $order['order_sn'],
  122. "total" => $order['price'],
  123. "name" => $order['product']['product_name'],
  124. "notify_url" => "https://tran.jsshuita.cn/notify/douyin"
  125. ];
  126. $byteAuthorization = (new Pay)->config([
  127. "appid" => sConf("wechat.mini_appid"),
  128. "secret" => sConf("wechat.mini_secret"),
  129. "salt" => sConf("wechat.mch_salt"),
  130. ])->createOrder($payParam);
  131. if (!empty($param['mobile'])) {
  132. $order->mobile = $param['mobile'];
  133. $order->save();
  134. }
  135. return success("ok",['pay' => $byteAuthorization]);
  136. } catch (\Throwable $throwable) {
  137. return error($throwable->getMessage());
  138. }
  139. }
  140. #[PostMapping("mobile")]
  141. public function getOrderMobile(Request $request)
  142. {
  143. try {
  144. $param = $request->post();
  145. $mobile = [];
  146. if (!empty($param['code'])) {
  147. $mobileStr = (new Crypt)->config($this->getDyConfig())->token()->getMobile($param['code']);
  148. if (!empty($mobileStr)) {
  149. $mobile = $this->decrypt2code(sConf('wechat.min_private_key'), $mobileStr);
  150. }
  151. }
  152. $mobileStr = "";
  153. if (!empty($mobile['purePhoneNumber'])) {
  154. $mobileStr = $mobile['purePhoneNumber'];
  155. }
  156. return success("ok",['mobile' => $mobileStr]);
  157. } catch (\Throwable $throwable) {
  158. return error($throwable->getMessage());
  159. }
  160. }
  161. protected function decrypt2code($private_key, $ciphertext_str) {
  162. // 解码 base64 密文
  163. $ciphertext = base64_decode($ciphertext_str);
  164. // 使用私钥解密
  165. openssl_private_decrypt($ciphertext, $plaintext, $private_key, OPENSSL_PKCS1_PADDING);
  166. if ($plaintext === false) {
  167. return [];
  168. }
  169. return json_decode($plaintext,true);
  170. }
  171. protected function decrypt($encrypted_data, $session_key, $iv) {
  172. $data = base64_decode($encrypted_data);
  173. $key = base64_decode($session_key);
  174. $iv_decoded = base64_decode($iv);
  175. // 使用 AES-256-CBC 模式解密
  176. $decrypted = openssl_decrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv_decoded);
  177. return $decrypted;
  178. }
  179. }