From 522183cb715ceff10335bf50e9e6adb7eb1e7e37 Mon Sep 17 00:00:00 2001 From: "HESU\\HESU" <1696136552@qq.com> Date: Wed, 2 Apr 2025 15:17:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=85=A5=E5=85=AC=E5=85=B1=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 4 +- app/controller/AreaController.php | 18 ++- app/controller/UserController.php | 44 ++++-- app/model/User.php | 2 +- app/service/UserService.php | 38 ++++- app/util/HttpClient.php | 227 ++++++++++++++++++++++++++++++ app/util/RedisHelper.php | 171 ++++++++++++++++++++++ config/const.php | 5 + 8 files changed, 491 insertions(+), 18 deletions(-) create mode 100644 app/util/HttpClient.php create mode 100644 app/util/RedisHelper.php create mode 100644 config/const.php diff --git a/.env.example b/.env.example index c937e0e..2da6de2 100644 --- a/.env.example +++ b/.env.example @@ -17,4 +17,6 @@ JWT_ALGORITHM = 'HS256' JWT_EXPIRATION = 2592000 WEBMAN_LISTEN = 'http://0.0.0.0:9007' -WEBMAN_COUNT = 8 \ No newline at end of file +WEBMAN_COUNT = 8 + +RPC_DOMAIN = http://219.157.255.213:25015 \ No newline at end of file diff --git a/app/controller/AreaController.php b/app/controller/AreaController.php index 9b0d979..c935393 100644 --- a/app/controller/AreaController.php +++ b/app/controller/AreaController.php @@ -4,7 +4,11 @@ namespace app\controller; use app\model\Area; use app\model\Country; +use app\util\HttpClient; +use app\util\RedisHelper; use app\util\Util; +use support\Log; +use support\Redis; use support\Request; class AreaController @@ -41,7 +45,19 @@ class AreaController public function getCountry (Request $request) { - $list = Country::get()->toArray(); + $list = RedisHelper::get("rpc_country"); + $list = null; + if(!$list){ + $res = HttpClient::get(config('const.rpc_domain') . '/country/all'); + if ($res['code'] != 200 && $res['data']['code'] != 0){ + Log::info('register_rpc',$res); + return Util::fail($res, trans('register_fail')); + } + $list = $res['data']['data']['data']; + RedisHelper::set("rpc_country", $list, 600); + } + +// $list = Country::get()->toArray(); $language = 'en_addr'; if($request->user['language'] == 'zh_CN'){ $language = 'cn_addr'; diff --git a/app/controller/UserController.php b/app/controller/UserController.php index a52cd7c..3e1ba6e 100644 --- a/app/controller/UserController.php +++ b/app/controller/UserController.php @@ -7,8 +7,11 @@ use app\model\FeishuUser; use app\model\User; use app\model\UserSn; use app\service\MailService; +use app\service\UserService; +use app\util\HttpClient; use app\util\JwtUtil; use app\util\Util; +use support\Log; use support\Redis; use support\Request; @@ -126,9 +129,9 @@ class UserController $res = User::select('id', 'email') ->where('email', $email) ->first(); -// if (!Util::isEmpty($res)) { -// return Util::fail([], trans('email_repeat')); -// } + if (!empty($res)) { + return Util::fail($res, trans('email_repeat')); + } if (Util::isEmpty($name)) { // return Util::fail([], trans('required_not_null')); @@ -159,15 +162,18 @@ class UserController if (Util::isEmpty($id)) { - // 获取编号 - $userSnModel = new UserSn(); - $sn = $userSnModel->where('user_id', '=', 0)->inRandomOrder()->first(); - if (!$sn) { - throw new BusinessException('未找到适用编号'); + $option = ['email' => $email]; + $userService = new UserService; + $res = $userService->createOrquery($option); + Log::info('register_rpc',$res); +// return Util::fail($res, trans('register_fail')); + if ($res['code'] != 200 && $res['data']['code'] != 0){ + return Util::fail($res, trans('register_fail')); } - $data['sn'] = $sn['user_sn']; - $res = User::create($data); - UserSn::where(['user_sn'=>$data['sn']])->update(['user_id'=>$res['id']]); + $data['sn'] = $res['data']['data']['sn']; + $data['id'] = $res['data']['data']['uid']; + $res = User::firstOrCreate(['sn' => $data['sn']],$data); + $res['id'] = $data['id']; } else { $res = User::where('id', $id) ->update($data); @@ -210,14 +216,28 @@ class UserController { $id = $request->user['id']; $avatar = Util::getParam($request, 'avatar_url'); + $socializePic = Util::getParam($request, 'socialize_pic_url'); $user = User::where('id', $id)->first(); // 只填充前端传递的字段 - $user->fill($request->only(['name', 'sex', 'position', 'country_id', 'sign', 'mobile', 'address'])); + $user->fill($request->only(['name', 'sex', 'position', 'country_id', 'sign', 'mobile', 'address', 'socialize', 'socialize_pic'])); if(!Util::isEmpty($avatar)){ $user->avatar = $avatar; } + if(!Util::isEmpty($socializePic)){ + $user->socialize_pic = $socializePic; + } + + $mobile = $user->isDirty('mobile'); + $name = $user->isDirty('name'); + $sign = $user->isDirty('sign'); + if($mobile || $name || $sign){ + $userService = new UserService; + $option = ['uid' => $user->id, 'phone' => $user->mobile, 'name' => $user->name, 'sign' => $user->sign, ]; + $res = $userService->update($option); + Log::info('register_rpc',$res); + } $res = $user->save(); diff --git a/app/model/User.php b/app/model/User.php index 118d3b2..abdc2ea 100644 --- a/app/model/User.php +++ b/app/model/User.php @@ -34,7 +34,7 @@ class User extends Model protected $dateFormat = 'U'; //设置黑名单 - protected $guarded = ['id','created_at','updated_at']; + protected $guarded = ['created_at','updated_at']; protected $casts = [ // 'updated_at' => 'datetime:Y-m-d H:i:s', // 指定序列化格式 diff --git a/app/service/UserService.php b/app/service/UserService.php index 197021a..cea12c8 100644 --- a/app/service/UserService.php +++ b/app/service/UserService.php @@ -4,9 +4,17 @@ namespace app\service; use app\model\User; use app\model\UserSn; +use app\util\HttpClient; class UserService { + protected $domain; + + + public function __construct(){ + $this->domain = config('const.rpc_domain'); + } + /** * 更新用户sn * @param $sn @@ -15,12 +23,12 @@ class UserService public static function updateSn($sn, $email) { $user = User::first() - ->where('email',$email) + ->where('email', $email) ->first(); - if(!$user){ + if (!$user) { return false; } - if($user->sn != $sn){ + if ($user->sn != $sn) { UserSn::where(['sn' => $user->sn])->update(['user_id' => 0]); UserSn::where(['sn' => $sn])->update(['user_id' => $user->id]); $user->sn = $sn; @@ -28,4 +36,28 @@ class UserService } return $user; } + + /** + * 创建或查询用户 + * @param array $data ['email'=>'','phone'=>'','company_tag'=>'','name'=>'']; + * @return array + */ + public function createOrquery(array $data) + { + + $result = HttpClient::post($this->domain . '/user/create/query', $data); + return $result; + } + + /** + * 创建或查询用户 + * @param array $data ['email'=>'','phone'=>'','company_tag'=>'','name'=>'']; + * @return array + */ + public function update(array $data) + { + + $result = HttpClient::post($this->domain . '/user/update', $data); + return $result; + } } \ No newline at end of file diff --git a/app/util/HttpClient.php b/app/util/HttpClient.php new file mode 100644 index 0000000..55b0b86 --- /dev/null +++ b/app/util/HttpClient.php @@ -0,0 +1,227 @@ + 10, // 默认超时时间10秒 + 'verify' => false, // 不验证SSL证书(生产环境建议设为true) + 'http_errors' => false, // 不抛出HTTP异常,自己处理 + ]); + } + return self::$client; + } + + /** + * 发送GET请求 + * @param string $url 请求地址 + * @param array $query 查询参数 + * @param array $headers 请求头 + * @return array + */ + public static function get(string $url, array $query = [], array $headers = []): array + { + $options = [ + 'query' => $query, + 'headers' => $headers + ]; + return self::request('GET', $url, $options); + } + + /** + * 发送POST请求 + * @param string $url 请求地址 + * @param array|string $data 请求数据 + * @param array $headers 请求头 + * @param string $contentType 内容类型(form/json/xml) + * @return array + */ + public static function post(string $url, $data = [], array $headers = [], string $contentType = 'form'): array + { + $options = ['headers' => $headers]; + + switch ($contentType) { + case 'json': + $options['json'] = $data; + $options['headers']['Content-Type'] = 'application/json'; + break; + /*case 'xml': + $options['body'] = is_array($data) ? self::arrayToXml($data) : $data; + $options['headers']['Content-Type'] = 'application/xml'; + break;*/ + default: // form + $options['form_params'] = $data; + $options['headers']['Content-Type'] = 'application/x-www-form-urlencoded'; + } + + return self::request('POST', $url, $options); + } + + /** + * 发送PUT请求 + * @param string $url 请求地址 + * @param array|string $data 请求数据 + * @param array $headers 请求头 + * @return array + */ + public static function put(string $url, $data = [], array $headers = []): array + { + $options = [ + 'json' => $data, + 'headers' => $headers + ]; + return self::request('PUT', $url, $options); + } + + /** + * 发送DELETE请求 + * @param string $url 请求地址 + * @param array $data 请求数据 + * @param array $headers 请求头 + * @return array + */ + public static function delete(string $url, array $data = [], array $headers = []): array + { + $options = [ + 'json' => $data, + 'headers' => $headers + ]; + return self::request('DELETE', $url, $options); + } + + /** + * 发送HTTP请求 + * @param string $method 请求方法 + * @param string $url 请求地址 + * @param array $options 请求选项 + * @return array + */ + public static function request(string $method, string $url, array $options = []): array + { + try { + $response = self::getClient()->request($method, $url, $options); + return self::formatResponse($response); + } catch (GuzzleException $e) { + return [ + 'status' => false, + 'code' => $e->getCode(), + 'message' => $e->getMessage(), + 'data' => null + ]; + } + } + + /** + * 上传文件 + * @param string $url 请求地址 + * @param array $files 文件数组 [['name' => 'field_name', 'path' => 'file_path']] + * @param array $form 其他表单数据 + * @param array $headers 请求头 + * @return array + */ + public static function upload(string $url, array $files, array $form = [], array $headers = []): array + { + $multipart = []; + + // 添加文件 + foreach ($files as $file) { + if (file_exists($file['path'])) { + $multipart[] = [ + 'name' => $file['name'], + 'contents' => fopen($file['path'], 'r'), + 'filename' => basename($file['path']) + ]; + } + } + + // 添加其他表单数据 + foreach ($form as $name => $value) { + $multipart[] = [ + 'name' => $name, + 'contents' => $value + ]; + } + + $options = [ + 'multipart' => $multipart, + 'headers' => $headers + ]; + + return self::request('POST', $url, $options); + } + + /** + * 格式化响应 + * @param ResponseInterface $response + * @return array + */ + private static function formatResponse(ResponseInterface $response): array + { + $contents = $response->getBody()->getContents(); + $contentType = $response->getHeaderLine('Content-Type'); + + $data = $contents; + if (strpos($contentType, 'application/json') !== false) { + $data = json_decode($contents, true) ?? $contents; + } + + return [ + 'status' => $response->getStatusCode() === 200, + 'code' => $response->getStatusCode(), + 'message' => $response->getReasonPhrase(), + 'data' => $data, + 'headers' => $response->getHeaders() + ]; + } + + /** + * 数组转XML + * @param array $data + * @param string $rootNode + * @return string + */ + private static function arrayToXml(array $data, string $rootNode = 'root'): string + { + $xml = new \SimpleXMLElement('<' . $rootNode . '/>'); + self::addDataToXml($xml, $data); + return $xml->asXML(); + } + + /** + * 递归添加数据到XML + * @param \SimpleXMLElement $xml + * @param array $data + */ + private static function addDataToXml(\SimpleXMLElement $xml, array $data) + { + foreach ($data as $key => $value) { + if (is_array($value)) { + if (is_numeric($key)) { + $key = 'item'; + } + $subNode = $xml->addChild($key); + self::addDataToXml($subNode, $value); + } else { + $xml->addChild($key, htmlspecialchars($value)); + } + } + } +} \ No newline at end of file diff --git a/app/util/RedisHelper.php b/app/util/RedisHelper.php new file mode 100644 index 0000000..caadcae --- /dev/null +++ b/app/util/RedisHelper.php @@ -0,0 +1,171 @@ +getMessage()}", ['key' => $key]); + return false; + } + } + + /** + * 获取数据(自动反序列化数组) + * @param string $key 键名 + * @param mixed $default 默认值 + * @return mixed + */ + public static function get(string $key, $default = null) + { + try { + $value = Redis::get($key); + + if ($value === false || $value === null) { + return $default; + } + + // 尝试JSON解码 + $decoded = json_decode($value, true); + return json_last_error() === JSON_ERROR_NONE ? $decoded : $value; + } catch (\Throwable $e) { + Log::error("Redis读取失败: {$e->getMessage()}", ['key' => $key]); + return $default; + } + } + + /** + * 删除键 + * @param string|array $keys 键名或键名数组 + * @return int 删除的键数量 + */ + public static function del($keys): int + { + try { + return Redis::del(...(array)$keys); + } catch (\Throwable $e) { + Log::error("Redis删除失败: {$e->getMessage()}", ['keys' => $keys]); + return 0; + } + } + + /** + * 检查键是否存在 + * @param string $key 键名 + * @return bool + */ + public static function exists(string $key): bool + { + try { + return (bool)Redis::exists($key); + } catch (\Throwable $e) { + Log::error("Redis检查存在失败: {$e->getMessage()}", ['key' => $key]); + return false; + } + } + + /** + * 设置带过期时间的缓存 + * @param string $key 键名 + * @param mixed $value 值 + * @param int $ttl 过期时间(秒) + * @return bool + */ + public static function setex(string $key, $value, int $ttl): bool + { + return self::set($key, $value, $ttl); + } + + /** + * 哈希表设置字段值 + * @param string $key 键名 + * @param string $field 字段名 + * @param mixed $value 值 + * @return bool + */ + public static function hSet(string $key, string $field, $value): bool + { + try { + $storageValue = is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value; + return Redis::hSet($key, $field, $storageValue); + } catch (\Throwable $e) { + Log::error("Redis哈希设置失败: {$e->getMessage()}", ['key' => $key, 'field' => $field]); + return false; + } + } + + /** + * 哈希表获取字段值 + * @param string $key 键名 + * @param string $field 字段名 + * @param mixed $default 默认值 + * @return mixed + */ + public static function hGet(string $key, string $field, $default = null) + { + try { + $value = Redis::hGet($key, $field); + + if ($value === false) { + return $default; + } + + $decoded = json_decode($value, true); + return json_last_error() === JSON_ERROR_NONE ? $decoded : $value; + } catch (\Throwable $e) { + Log::error("Redis哈希获取失败: {$e->getMessage()}", ['key' => $key, 'field' => $field]); + return $default; + } + } + + /** + * 自增计数器 + * @param string $key 键名 + * @param int $increment 增量 + * @return int|false + */ + public static function incr(string $key, int $increment = 1) + { + try { + return $increment === 1 + ? Redis::incr($key) + : Redis::incrBy($key, $increment); + } catch (\Throwable $e) { + Log::error("Redis自增失败: {$e->getMessage()}", ['key' => $key]); + return false; + } + } + + /** + * 获取剩余过期时间 + * @param string $key 键名 + * @return int 剩余秒数(-2表示键不存在,-1表示没有设置过期时间) + */ + public static function ttl(string $key): int + { + try { + return Redis::ttl($key); + } catch (\Throwable $e) { + Log::error("Redis获取TTL失败: {$e->getMessage()}", ['key' => $key]); + return -2; + } + } +} \ No newline at end of file diff --git a/config/const.php b/config/const.php new file mode 100644 index 0000000..12ba463 --- /dev/null +++ b/config/const.php @@ -0,0 +1,5 @@ + getenv('RPC_DOMAIN'), +]; \ No newline at end of file