Home.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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'],'status' => 1,'show_channel' => 1])->field("product_id,product_name,image_list,category,price,line_price,sale_stock,id,goods_id,is_new")->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(Request $request): Response
  59. {
  60. try {
  61. $param = $this->_valid([
  62. "poi.default" => 0
  63. ],$request->method());
  64. if (!is_array($param)) return error($param);
  65. $store = (new SaasStore)->where("poi_id",$param['poi'])->findOrEmpty();
  66. if ($store->isEmpty()) return error("数据错误");
  67. if (empty($store['license'])) {
  68. $license = sConf("service.license");
  69. } else {
  70. $license = $store['license'];
  71. }
  72. return success("ok",['img' => $license]);
  73. } catch (\Throwable $throwable) {
  74. return error($throwable->getMessage());
  75. }
  76. }
  77. /**
  78. * 三级城市信息
  79. * @param Request $request
  80. * @return Response
  81. */
  82. #[GetMapping("city")]
  83. public function getCityJson(Request $request): Response
  84. {
  85. try {
  86. $data = json_decode(file_get_contents(base_path()."/city.json"),true);
  87. return successTrans("success.data",$data);
  88. } catch (\Throwable $throwable) {
  89. return error($throwable->getMessage());
  90. }
  91. }
  92. /**
  93. * 生服组件解密手机号码
  94. * @param Request $request
  95. * @return Response
  96. */
  97. #[PostMapping("mobile")]
  98. public function payBtnMobile(Request $request): Response
  99. {
  100. try {
  101. $param = $request->all();
  102. $mobile = [];
  103. if (!empty($param['code'])) {
  104. $sessionKey = (new Crypt)->config($this->getDyConfig())->token()->getSessionKey($param['code']);
  105. if (!empty($sessionKey)) {
  106. $mobileStr = $this->decrypt2code($param['encryptedData'], $sessionKey['session_key'],$param['iv']);
  107. if (!empty($mobileStr)) $mobile = json_decode($mobileStr,true);
  108. }
  109. }
  110. if (empty($mobile)) return error("获取失败");
  111. return successTrans("success.data",['mobile' => $mobile['purePhoneNumber']]);
  112. } catch (\Throwable $throwable) {
  113. return error($throwable->getMessage());
  114. }
  115. }
  116. /**
  117. * 解密微信用户手机号等加密数据
  118. *
  119. * @param string $encrypted_data Base64 编码的密文
  120. * @param string $session_key Base64 编码的会话密钥
  121. * @param string $iv Base64 编码的初始向量
  122. * @return string 解密后的原始字符串(通常为 JSON)
  123. * @throws Exception
  124. */
  125. protected function decrypt2code($encrypted_data, $session_key, $iv)
  126. {
  127. // 1. Base64 解码
  128. $data = base64_decode($encrypted_data, true);
  129. $key = base64_decode($session_key, true);
  130. $iv = base64_decode($iv, true);
  131. if ($data === false || $key === false || $iv === false) {
  132. throw new \Exception('Base64 解码失败');
  133. }
  134. // 2. 根据密钥长度选择 AES 算法
  135. $key_len = strlen($key);
  136. switch ($key_len) {
  137. case 16:
  138. $method = 'AES-128-CBC';
  139. break;
  140. case 24:
  141. $method = 'AES-192-CBC';
  142. break;
  143. case 32:
  144. $method = 'AES-256-CBC';
  145. break;
  146. default:
  147. throw new \Exception("无效的密钥长度: {$key_len} 字节");
  148. }
  149. // 3. 解密(OPENSSL_RAW_DATA 表示返回二进制数据,不进行 Base64 编码)
  150. $decrypted = openssl_decrypt($data, $method, $key, OPENSSL_RAW_DATA, $iv);
  151. if ($decrypted === false) {
  152. throw new \Exception('解密失败: ' . openssl_error_string());
  153. }
  154. return $decrypted;
  155. }
  156. }