BaseApi.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2015-2025 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace app\api\controller;
  11. use app\model\member\Member as MemberModel;
  12. use app\model\shop\Shop;
  13. use app\model\system\Api;
  14. use extend\RSA;
  15. use think\facade\Cache;
  16. use addon\store\model\Config as StoreConfig;
  17. use app\model\store\Store;
  18. class BaseApi
  19. {
  20. public $lang;
  21. public $params;
  22. public $token;
  23. protected $member_id;
  24. protected $site_id;
  25. protected $app_module = "shop";
  26. public $app_type;
  27. private $refresh_token;
  28. /**
  29. * 所选门店id
  30. * @var
  31. */
  32. protected $store_id = 0; // 门店id
  33. /**
  34. * 门店数据
  35. * @var
  36. */
  37. protected $store_data = [
  38. 'config' => [
  39. 'store_business' => 'shop'
  40. ]
  41. ];
  42. public function __construct()
  43. {
  44. if ($_SERVER[ 'REQUEST_METHOD' ] == 'OPTIONS') {
  45. exit;
  46. }
  47. //获取参数
  48. $this->site_id = request()->siteid();
  49. $this->params = input();
  50. $this->params[ 'site_id' ] = $this->site_id;
  51. $shop_model = new Shop();
  52. $shop_status = $shop_model->getShopStatus($this->site_id, 'shop');
  53. //默认APP类型处理
  54. if (!isset($this->params[ 'app_type' ])) $this->params[ 'app_type' ] = 'h5';
  55. if ($this->params[ 'app_type' ] == 'pc') {
  56. if (!$shop_status[ 'data' ][ 'value' ][ 'shop_pc_status' ]) exit(json_encode($this->error([], 'SITE_CLOSE')));
  57. } else if ($this->params[ 'app_type' ] == 'weapp') {
  58. if (!$shop_status[ 'data' ][ 'value' ][ 'shop_weapp_status' ]) exit(json_encode($this->error([], 'SITE_CLOSE')));
  59. } else if ($this->params[ 'app_type' ] == 'h5' || $this->params[ 'app_type' ] == 'wechat') {
  60. if (!$shop_status[ 'data' ][ 'value' ][ 'shop_h5_status' ]) exit(json_encode($this->error([], 'SITE_CLOSE')));
  61. }
  62. if (isset($this->params[ 'encrypt' ]) && !empty($this->params[ 'encrypt' ])) {
  63. $this->decryptParams();
  64. }
  65. $this->store_id = $this->params[ 'store_id' ] ?? 0;
  66. }
  67. /**
  68. * 初始化门店数据
  69. */
  70. protected function initStoreData()
  71. {
  72. $store_model = new Store();
  73. $default_store = $store_model->getDefaultStore($this->site_id)[ 'data' ];
  74. $this->store_data[ 'default_store' ] = $default_store ? $default_store[ 'store_id' ] : 0;
  75. $this->store_id = $this->store_id ? $this->store_id : $this->store_data[ 'default_store' ];
  76. if (addon_is_exit('store', $this->site_id)) {
  77. $this->store_data[ 'config' ] = ( new StoreConfig() )->getStoreBusinessConfig($this->site_id)[ 'data' ][ 'value' ];
  78. if ($this->store_id == $this->store_data[ 'default_store' ]) $this->store_data[ 'store_info' ] = $default_store;
  79. else $this->store_data[ 'store_info' ] = $store_model->getStoreInfo([ [ 'site_id', '=', $this->site_id ], [ 'store_id', '=', $this->store_id ] ])[ 'data' ];
  80. if (empty($this->store_data[ 'store_info' ]) || $this->store_data[ 'store_info' ][ 'status' ] == 0) {
  81. exit(json_encode($this->error([], 'STORE_CLOSE')));
  82. }
  83. }
  84. }
  85. /**
  86. * api请求参数解密
  87. */
  88. private function decryptParams()
  89. {
  90. $api_model = new Api();
  91. $config = $api_model->getApiConfig();
  92. $config = $config[ 'data' ];
  93. if ($config[ 'is_use' ] && !empty($config[ 'value' ])) {
  94. $decrypted = RSA::decrypt(urldecode($this->params[ 'encrypt' ]), $config[ 'value' ][ 'private_key' ], $config[ 'value' ][ 'public_key' ]);
  95. if ($decrypted[ 'code' ] >= 0) {
  96. $this->params = json_decode($decrypted[ 'data' ], true);
  97. $this->params[ 'site_id' ] = $this->site_id;
  98. }
  99. }
  100. }
  101. /**
  102. * 检测token(使用私钥检测)
  103. */
  104. protected function checkToken() : array
  105. {
  106. if (empty($this->params[ 'token' ])) return $this->error('', 'TOKEN_NOT_EXIST');
  107. $key = 'site' . $this->site_id;
  108. $api_model = new Api();
  109. $api_config = $api_model->getApiConfig()[ 'data' ];
  110. if ($api_config[ 'is_use' ] && isset($api_config[ 'value' ][ 'private_key' ]) && !empty($api_config[ 'value' ][ 'private_key' ])) {
  111. $key = $api_config[ 'value' ][ 'private_key' ] . $key;
  112. }
  113. $decrypt = decrypt($this->params[ 'token' ], $key);
  114. if (empty($decrypt)) return $this->error('', 'TOKEN_ERROR');
  115. $data = json_decode($decrypt, true);
  116. if (!isset($data[ 'member_id' ]) || empty($data[ 'member_id' ])) return $this->error('', 'TOKEN_ERROR');
  117. $member_model = new MemberModel();
  118. $check_member_id = $member_model->checkMemberByMemberId($data[ 'member_id' ], $this->site_id);
  119. if (!$check_member_id) {
  120. return $this->error('', 'TOKEN_EXPIRE');
  121. }
  122. if ($data[ 'expire_time' ] < time()) {
  123. if ($data[ 'expire_time' ] != 0) {
  124. return $this->error('', 'TOKEN_EXPIRE');
  125. }
  126. } else if (( $data[ 'expire_time' ] - time() ) < 300 && !Cache::get('member_token' . $data[ 'member_id' ])) {
  127. $this->refresh_token = $this->createToken($data[ 'member_id' ]);
  128. Cache::set('member_token' . $data[ 'member_id' ], $this->refresh_token, 360);
  129. }
  130. $this->member_id = $data[ 'member_id' ];
  131. return success(0, '', $data);
  132. }
  133. /**
  134. * 创建token
  135. * @param
  136. */
  137. protected function createToken($member_id)
  138. {
  139. $api_model = new Api();
  140. $config_result = $api_model->getApiConfig();
  141. $config = $config_result[ "data" ];
  142. # $expire_time 有效时间 0为永久 单位s
  143. if ($config) {
  144. $expire_time = round($config[ 'value' ][ 'long_time' ] * 3600);
  145. } else {
  146. $expire_time = 0;
  147. }
  148. $key = 'site' . $this->site_id;
  149. $api_model = new Api();
  150. $api_config = $api_model->getApiConfig()[ 'data' ];
  151. if ($api_config[ 'is_use' ] && isset($api_config[ 'value' ][ 'private_key' ]) && !empty($api_config[ 'value' ][ 'private_key' ])) {
  152. $key = $api_config[ 'value' ][ 'private_key' ] . $key;
  153. }
  154. $data = [
  155. 'member_id' => $member_id,
  156. 'create_time' => time(),
  157. 'expire_time' => empty($expire_time) ? 0 : time() + $expire_time
  158. ];
  159. $token = encrypt(json_encode($data), $key);
  160. return $token;
  161. }
  162. /**
  163. * 返回数据
  164. * @param $data
  165. * @return false|string
  166. */
  167. public function response($data)
  168. {
  169. $data[ 'timestamp' ] = time();
  170. if (!empty($this->refresh_token)) $data[ 'refreshtoken' ] = $this->refresh_token;
  171. return json_encode($data, JSON_UNESCAPED_UNICODE);
  172. }
  173. /**
  174. * 操作成功返回值函数
  175. * @param string $data
  176. * @param string $code_var
  177. * @return array
  178. */
  179. public function success($data = '', $code_var = 'SUCCESS')
  180. {
  181. $lang_array = $this->getLang();
  182. $code_array = $this->getCode();
  183. $lang_var = isset($lang_array[ $code_var ]) ? $lang_array[ $code_var ] : $code_var;
  184. $code_var = isset($code_array[ $code_var ]) ? $code_array[ $code_var ] : $code_array[ 'SUCCESS' ];
  185. return success($code_var, $lang_var, $data);
  186. }
  187. /**
  188. * 操作失败返回值函数
  189. * @param string $data
  190. * @param string $code_var
  191. * @return array
  192. */
  193. public function error($data = '', $code_var = 'ERROR')
  194. {
  195. $lang_array = $this->getLang();
  196. $code_array = $this->getCode();
  197. $lang_var = isset($lang_array[ $code_var ]) ? $lang_array[ $code_var ] : $code_var;
  198. $code_var = isset($code_array[ $code_var ]) ? $code_array[ $code_var ] : $code_array[ 'ERROR' ];
  199. return error($code_var, $lang_var, $data);
  200. }
  201. /**
  202. * 获取语言包数组
  203. * @return Ambigous <multitype:, unknown>
  204. */
  205. private function getLang()
  206. {
  207. $default_lang = config("lang.default_lang");
  208. $addon = request()->addon();
  209. $addon = isset($addon) ? $addon : '';
  210. $cache_common = Cache::get("lang_app/api/lang/" . $default_lang);
  211. if (empty($cache_common)) {
  212. $cache_common = include 'app/api/lang/' . $default_lang . '.php';
  213. Cache::tag("lang")->set("lang_app/api/lang/" . $default_lang, $cache_common);
  214. }
  215. if (!empty($addon)) {
  216. try {
  217. $addon_cache_common = include 'addon/' . $addon . '/api/lang/' . $default_lang . '.php';
  218. if (!empty($addon_cache_common)) {
  219. $cache_common = array_merge($cache_common, $addon_cache_common);
  220. Cache::tag("lang")->set("lang_app/api/lang/" . $addon . '_' . $default_lang, $addon_cache_common);
  221. }
  222. } catch (\Exception $e) {
  223. }
  224. }
  225. return $cache_common;
  226. }
  227. /**
  228. * 获取code编码
  229. * @return Ambigous <multitype:, unknown>
  230. */
  231. private function getCode()
  232. {
  233. $addon = request()->addon();
  234. $addon = isset($addon) ? $addon : '';
  235. $cache_common = Cache::get("lang_code_app/api/lang");
  236. if (!empty($addon)) {
  237. $addon_cache_common = Cache::get("lang_code_app/api/lang/" . $addon);
  238. if (!empty($addon_cache_common)) {
  239. $cache_common = array_merge($cache_common, $addon_cache_common);
  240. }
  241. }
  242. if (empty($cache_common)) {
  243. $cache_common = include 'app/api/lang/code.php';
  244. Cache::tag("lang_code")->set("lang_code_app/api/lang", $cache_common);
  245. if (!empty($addon)) {
  246. try {
  247. $addon_cache_common = include 'addon/' . $addon . '/api/lang/code.php';
  248. if (!empty($addon_cache_common)) {
  249. Cache::tag("lang_code")->set("lang_code_app/api/lang/" . $addon, $addon_cache_common);
  250. $cache_common = array_merge($cache_common, $addon_cache_common);
  251. }
  252. } catch (\Exception $e) {
  253. }
  254. }
  255. }
  256. $lang_path = isset($this->lang) ? $this->lang : '';
  257. if (!empty($lang_path)) {
  258. $cache_path = Cache::get("lang_code_" . $lang_path);
  259. if (empty($cache_path)) {
  260. $cache_path = include $lang_path . '/code.php';
  261. Cache::tag("lang")->set("lang_code_" . $lang_path, $cache_path);
  262. }
  263. $lang = array_merge($cache_common, $cache_path);
  264. } else {
  265. $lang = $cache_common;
  266. }
  267. return $lang;
  268. }
  269. /**
  270. * @param array $data 验证数据
  271. * @param $validate 验证类
  272. * @param $scene 验证场景
  273. */
  274. public function validate(array $data, $validate, $scene = '')
  275. {
  276. try {
  277. $class = new $validate;
  278. if (!empty($scene)) {
  279. $res = $class->scene($scene)->check($data);
  280. } else {
  281. $res = $class->check($data);
  282. }
  283. if (!$res) {
  284. return error(-1, $class->getError());
  285. } else
  286. return success(1);
  287. } catch (ValidateException $e) {
  288. return error(-1, $e->getError());
  289. } catch (\Exception $e) {
  290. return error(-1, $e->getMessage());
  291. }
  292. }
  293. }