Home.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. namespace app\controller\v2;
  3. use app\extra\basic\Base;
  4. use app\extra\dyLife\Crypt;
  5. use app\middleware\AuthMiddleware;
  6. use app\model\saas\SaasGoods;
  7. use app\model\saas\SaasStore;
  8. use LinFly\Annotation\Attributes\Route\Controller;
  9. use LinFly\Annotation\Attributes\Route\GetMapping;
  10. use LinFly\Annotation\Attributes\Route\Middleware;
  11. use LinFly\Annotation\Attributes\Route\PostMapping;
  12. use support\Request;
  13. use support\Response;
  14. #[Controller("/v2/home"),Middleware(AuthMiddleware::class)]
  15. class Home extends Base
  16. {
  17. /**
  18. * @var array|string[]
  19. */
  20. protected array $noNeedLogin = ["getHomeData","getLicense","payBtnMobile","getMoreGoods","getCityJson"];
  21. #[GetMapping("data")]
  22. public function getHomeData(Request $request): Response
  23. {
  24. try {
  25. $param = $this->_valid([
  26. "store.require" => trans("empty.require")
  27. ],$request->method());
  28. if (!is_array($param)) return error($param);
  29. $store = (new SaasStore)->where("poi_id",$param['store'])->field("poi_name,start_at,end_at,longitude,latitude,service_mobile,poi_id,poi_city,poi_address,poi_logo")->findOrEmpty();
  30. if (!$store->isEmpty()) {
  31. $store['poi_logo'] = empty($store['poi_logo']) ? sConf("service.logo") : $store['poi_logo'];
  32. }
  33. return success("ok",compact('store'));
  34. } catch (\Throwable $th) {
  35. return error($th->getMessage());
  36. }
  37. }
  38. #[GetMapping("goods")]
  39. public function getMoreGoods(Request $request): Response
  40. {
  41. try {
  42. $param = $this->_valid([
  43. "store.require" => trans("empty.require"),
  44. "page.default" => 1,
  45. "size.default" => 10
  46. ],$request->method());
  47. if (!is_array($param)) return error($param);
  48. $goods = (new SaasGoods)->where("poi_id",$param['store'])->where("status",1)->field("product_id,product_name,image_list,category,price,line_price,sale_stock,id,goods_id,is_new")->limit(10)->order('id','desc')->paginate([
  49. "list_rows" => $param['size'],
  50. "page" => $param['page']
  51. ]);
  52. return successTrans(100010,pageFormat($goods),200);
  53. } catch (\Throwable $throwable) {
  54. return error($throwable->getMessage());
  55. }
  56. }
  57. #[GetMapping("license")]
  58. public function getLicense(): Response
  59. {
  60. try {
  61. return success("ok",['img' => sConf("service.license")]);
  62. } catch (\Throwable $throwable) {
  63. return error($throwable->getMessage());
  64. }
  65. }
  66. /**
  67. * 三级城市信息
  68. * @param Request $request
  69. * @return Response
  70. */
  71. #[GetMapping("city")]
  72. public function getCityJson(Request $request): Response
  73. {
  74. try {
  75. $data = json_decode(file_get_contents(base_path()."/city.json"),true);
  76. return successTrans("success.data",$data);
  77. } catch (\Throwable $throwable) {
  78. return error($throwable->getMessage());
  79. }
  80. }
  81. /**
  82. * 生服组件解密手机号码
  83. * @param Request $request
  84. * @return Response
  85. */
  86. #[PostMapping("mobile")]
  87. public function payBtnMobile(Request $request): Response
  88. {
  89. try {
  90. $param = $request->all();
  91. $mobile = [];
  92. if (!empty($param['code'])) {
  93. $sessionKey = (new Crypt)->config($this->getDyConfig())->token()->getSessionKey($param['code']);
  94. if (!empty($sessionKey)) {
  95. $mobileStr = $this->decrypt2code($param['encryptedData'], $sessionKey['session_key'],$param['iv']);
  96. if (!empty($mobileStr)) $mobile = json_decode($mobileStr,true);
  97. }
  98. }
  99. if (empty($mobile)) return error("获取失败");
  100. return successTrans("success.data",['mobile' => $mobile['purePhoneNumber']]);
  101. } catch (\Throwable $throwable) {
  102. return error($throwable->getMessage());
  103. }
  104. }
  105. /**
  106. * 解密微信用户手机号等加密数据
  107. *
  108. * @param string $encrypted_data Base64 编码的密文
  109. * @param string $session_key Base64 编码的会话密钥
  110. * @param string $iv Base64 编码的初始向量
  111. * @return string 解密后的原始字符串(通常为 JSON)
  112. * @throws Exception
  113. */
  114. protected function decrypt2code($encrypted_data, $session_key, $iv)
  115. {
  116. // 1. Base64 解码
  117. $data = base64_decode($encrypted_data, true);
  118. $key = base64_decode($session_key, true);
  119. $iv = base64_decode($iv, true);
  120. if ($data === false || $key === false || $iv === false) {
  121. throw new \Exception('Base64 解码失败');
  122. }
  123. // 2. 根据密钥长度选择 AES 算法
  124. $key_len = strlen($key);
  125. switch ($key_len) {
  126. case 16:
  127. $method = 'AES-128-CBC';
  128. break;
  129. case 24:
  130. $method = 'AES-192-CBC';
  131. break;
  132. case 32:
  133. $method = 'AES-256-CBC';
  134. break;
  135. default:
  136. throw new \Exception("无效的密钥长度: {$key_len} 字节");
  137. }
  138. // 3. 解密(OPENSSL_RAW_DATA 表示返回二进制数据,不进行 Base64 编码)
  139. $decrypted = openssl_decrypt($data, $method, $key, OPENSSL_RAW_DATA, $iv);
  140. if ($decrypted === false) {
  141. throw new \Exception('解密失败: ' . openssl_error_string());
  142. }
  143. return $decrypted;
  144. }
  145. }