common.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <?php
  2. require_once "common/GameGameConfig.php";
  3. use Firebase\JWT\JWT;
  4. use Firebase\JWT\Key;
  5. use think\facade\Db;
  6. use app\model\UserIdAssignModel;
  7. /// 加密密钥
  8. $GLOBALS['token_key_secret'] = "z.1i8L?Ld+ovuA4r%4YZrz?w1Y%-NYvlrJ=TqV$[W[5=B#C[=l2gHV8gJ,DhZc";
  9. /// COOKIE 有效期
  10. $GLOBALS['cookieExpire'] = 60 * 60 * 24 * 3;
  11. // 全局默认RTP值
  12. $GLOBALS['defaultRTPValue'] = 97;
  13. /**
  14. * 响应成功json
  15. */
  16. if(!function_exists('json_success')){
  17. function json_success($data = [], $message = "", $code = 0){
  18. return json([
  19. 'state' => 1,
  20. 'code' => $code,
  21. 'data' => $data,
  22. 'message' => $message ?? ""
  23. ]);
  24. }
  25. }
  26. /**
  27. * 响应失败json
  28. */
  29. if(!function_exists('json_error')){
  30. function json_error($data = [], $message = "", $code = 0){
  31. return json([
  32. 'state' => 0,
  33. 'code' => $code,
  34. 'data' => $data,
  35. 'message' => $message ?? ""
  36. ]);
  37. }
  38. }
  39. /**
  40. * 获取用户真实请求IP
  41. * 使用ThinkPHP内置的Request::ip()方法
  42. *
  43. * @return string 返回客户端真实IP地址
  44. */
  45. if(!function_exists('getClientIp')){
  46. function getClientIp() {
  47. return \think\facade\Request::ip();
  48. }
  49. }
  50. /**
  51. * 生成JWT Token
  52. *
  53. * @param array $data 待加密数据
  54. * @param int $expire 过期时间(秒),0表示使用默认过期时间
  55. * @return string
  56. */
  57. if(!function_exists('generateToken')){
  58. function generateToken($data = [], $expire = 0){
  59. $payload = [
  60. 'exp' => time() + ($expire > 0 ? $expire : $GLOBALS['cookieExpire']), // 有效期
  61. 'iat' => time(), // 签发时间
  62. ];
  63. $payload = array_merge($payload, $data);
  64. $token = JWT::encode($payload, $GLOBALS['token_key_secret'], 'HS256');
  65. return $token;
  66. }
  67. }
  68. /**
  69. * 解析JWT Token
  70. *
  71. * @param string $token JWT Token字符串
  72. * @return array|null 解析成功返回payload数组,失败返回null
  73. */
  74. if(!function_exists('parseToken')){
  75. function parseToken($token) {
  76. try {
  77. if (empty($token)) {
  78. return null;
  79. }
  80. // 使用JWT库解析token
  81. $decoded = JWT::decode($token, new Key($GLOBALS['token_key_secret'], 'HS256'));
  82. // 转换为数组
  83. $payload = (array) $decoded;
  84. // 检查是否过期
  85. if (isset($payload['exp']) && $payload['exp'] < time()) {
  86. return null;
  87. }
  88. return $payload;
  89. } catch (\Firebase\JWT\ExpiredException $e) {
  90. // Token已过期
  91. return null;
  92. } catch (\Firebase\JWT\SignatureInvalidException $e) {
  93. // 签名无效
  94. return null;
  95. } catch (\Firebase\JWT\BeforeValidException $e) {
  96. // Token尚未生效
  97. return null;
  98. } catch (\Exception $e) {
  99. // 其他异常
  100. return null;
  101. }
  102. }
  103. }
  104. /**
  105. * 验证Token是否有效
  106. *
  107. * @param string $token JWT Token字符串
  108. * @return bool
  109. */
  110. if(!function_exists('verifyToken')){
  111. function verifyToken($token) {
  112. return parseToken($token) !== null;
  113. }
  114. }
  115. /**
  116. * 检查用户登录状态
  117. *
  118. * @return array|null 登录成功返回用户信息数组,失败返回null
  119. */
  120. if(!function_exists('checkUserLogin')){
  121. function checkUserLogin() {
  122. $token = \think\facade\Cookie::get('auth_token');
  123. if (!$token) {
  124. return null;
  125. }
  126. return parseToken($token);
  127. }
  128. }
  129. /**
  130. * 获取当前登录用户ID
  131. */
  132. if(!function_exists('getUserId')){
  133. function getUserId(): int {
  134. $userInfo = checkUserLogin();
  135. return $userInfo ? (int)$userInfo['user_id'] : 0;
  136. }
  137. }
  138. /**
  139. * 获取当前登录用户角色ID
  140. */
  141. if(!function_exists('getUserRoleId')){
  142. function getUserRoleId(int $userId): int {
  143. if (!$userId) {
  144. return 0;
  145. }
  146. $user = \app\model\UserModel::where('user_id', $userId)->find();
  147. return $user ? (int)$user->user_role : 0;
  148. }
  149. }
  150. /**
  151. * 检查用户权限
  152. *
  153. * @param array $user 用户信息数组
  154. * @param string $controller 控制器名称
  155. * @param string $action 操作名称
  156. * @param bool $checkIp 是否检查IP白名单,默认false
  157. * @return bool 有权限返回true,无权限返回false
  158. */
  159. if(!function_exists('checkPermission')){
  160. function checkPermission($user, $controller, $action, $checkIp = false) {
  161. $userId = is_array($user) ? (int)$user['user_id'] : 0;
  162. if (!$userId) {
  163. return false;
  164. }
  165. // 使用PermissionService统一权限检查
  166. $hasPermission = \app\service\PermissionService::checkPermission($userId, $controller, $action);
  167. // 如果有权限且需要检查IP,则进一步验证IP白名单
  168. if ($hasPermission && $checkIp) {
  169. return checkUserIpWhiteList($user);
  170. }
  171. return $hasPermission;
  172. }
  173. }
  174. /**
  175. * 检查用户IP白名单
  176. *
  177. * @param array $user 用户信息数组
  178. * @return bool IP在白名单中返回true,否则返回false
  179. */
  180. if(!function_exists('checkUserIpWhiteList')){
  181. function checkUserIpWhiteList($user) {
  182. // 获取用户完整信息
  183. $userModel = \app\model\UserModel::where('user_id', $user['user_id'])
  184. ->where('merchant_id', $user['merchant_id'])
  185. ->find();
  186. if (!$userModel) {
  187. return false;
  188. }
  189. // 获取客户端IP
  190. $clientIp = getClientIp();
  191. // 检查IP白名单
  192. return \app\service\IpWhiteListService::checkIpWhiteList($clientIp, $userModel->white_list_ip);
  193. }
  194. }
  195. /**
  196. * 检查用户登录状态并验证IP白名单
  197. *
  198. * @param bool $checkIp 是否检查IP白名单,默认false
  199. * @return array|null 验证通过返回用户信息数组,失败返回null
  200. */
  201. if(!function_exists('checkUserLoginWithIp')){
  202. function checkUserLoginWithIp($checkIp = false) {
  203. $user = checkUserLogin();
  204. if (!$user) {
  205. return null;
  206. }
  207. // 如果需要检查IP白名单
  208. if ($checkIp && !checkUserIpWhiteList($user)) {
  209. return null;
  210. }
  211. return $user;
  212. }
  213. }
  214. /**
  215. * 获取IP地址的地理位置信息
  216. *
  217. * @param string $ip IP地址,如果为空则获取当前请求的IP
  218. * @param bool $formatted 是否返回格式化的数据
  219. * @return array 返回IP地理位置信息
  220. */
  221. if(!function_exists('getIpLocation')){
  222. function getIpLocation($ip = '', $formatted = false) {
  223. if (empty($ip)) {
  224. $ip = getClientIp();
  225. }
  226. try {
  227. $ipService = \app\service\IpLocationService::getInstance();
  228. if ($formatted) {
  229. $result = $ipService->getLocationFormatted($ip);
  230. } else {
  231. $result = $ipService->getLocation($ip);
  232. }
  233. if ($result['status']) {
  234. return $result['data'];
  235. } else {
  236. return [
  237. 'ip' => $ip,
  238. 'location' => '未知'
  239. ];
  240. }
  241. } catch (\Exception $e) {
  242. return [
  243. 'ip' => $ip,
  244. 'location' => '查询失败'
  245. ];
  246. }
  247. }
  248. }
  249. /**
  250. * 批量获取IP地址的地理位置信息
  251. *
  252. * @param array $ips IP地址数组
  253. * @param bool $formatted 是否返回格式化的数据
  254. * @return array 返回IP地理位置信息数组
  255. */
  256. if(!function_exists('batchGetIpLocation')){
  257. function batchGetIpLocation(array $ips, $formatted = false) {
  258. try {
  259. $ipService = \app\service\IpLocationService::getInstance();
  260. if ($formatted) {
  261. return $ipService->batchGetLocationFormatted($ips);
  262. } else {
  263. return $ipService->batchGetLocation($ips);
  264. }
  265. } catch (\Exception $e) {
  266. $results = [];
  267. foreach ($ips as $ip) {
  268. $results[$ip] = [
  269. 'status' => false,
  270. 'message' => '查询失败',
  271. 'data' => null
  272. ];
  273. }
  274. return $results;
  275. }
  276. }
  277. }
  278. /**
  279. * 分配用户id
  280. */
  281. if(!function_exists('assignUserId')) {
  282. function assignUserId(): int|false
  283. {
  284. $data = [
  285. 'status' => 1,
  286. 'user_id' => Db::raw('LAST_INSERT_ID(user_id)'),
  287. ];
  288. try {
  289. $affectedRows = UserIdAssignModel::where('status', 0)->limit(1)->update($data);
  290. if ($affectedRows > 0) {
  291. $result = Db::query('SELECT LAST_INSERT_ID()');
  292. if (!empty($result) && isset($result[0])) {
  293. $assignedId = array_values($result[0])[0] ?? null;
  294. if ($assignedId !== null) {
  295. return (int)$assignedId;
  296. }
  297. }
  298. }
  299. } catch (Throwable $e) {
  300. return 0;
  301. }
  302. return 0;
  303. }
  304. }