Files
hospital-applets-api/app/Services/LoginService.php
T

649 lines
25 KiB
PHP

<?php
namespace App\Services;
use App\Constants\DoctorTitleCode;
use App\Constants\HttpEnumCode;
use App\Model\User as UserModel;
use App\Model\UserDoctor as UserDoctorModel;
use App\Model\UserPatient as UserPatientModel;
use App\Model\UserPharmacist as UserPharmacistModel;
use App\Model\UserSystem;
use App\Utils\Http;
use App\Utils\Jwt;
use App\Utils\Log;
use Extend\TencentIm\Account;
use Extend\Wechat\Wechat;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class LoginService extends BaseService
{
/**
* 微信登陆
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function wechatMobileLogin(): array
{
$phone_code = $this->request->input('phone_code');
$wx_code = $this->request->input('wx_code');
$user_type = $this->request->input('user_type');
$weChat = new Wechat($user_type);
// 获取手机号
$phone_info = $weChat->getPhone($phone_code);
if (empty($phone_info) || empty($phone_info['phone_info']) || empty($phone_info['phone_info']['purePhoneNumber'])) {
return fail(HttpEnumCode::GET_WX_ERROR);
}
// 获取用户openid
$wx_info_data = $weChat->codeToSession($wx_code);
if (empty($wx_info_data['session_key']) || empty($wx_info_data['openid'])) {
return fail(HttpEnumCode::GET_WX_ERROR);
}
Db::beginTransaction();
try {
// 获取用户信息
$params = array();
$params['mobile'] = $phone_info['phone_info']['purePhoneNumber'];
$user = UserModel::getOne($params);
if (empty($user)) {
// 处理药师特殊情况,后台添加,前台不允许注册
if ($user_type == 3) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, "账号不存在,请联系客服");
}
// 获取用户默认头像oss地址
$UserService = new UserService();
$avatar = $UserService->getUserDefaultOssAvatar($user_type);
// 新增用户表
$data = array();
$data['user_name'] = 'gdxz' . substr($phone_info['phone_info']['purePhoneNumber'], -4) . mt_rand(10000, 99999);
$data['mobile'] = $phone_info['phone_info']['purePhoneNumber'];
$data['wx_mobile'] = $phone_info['phone_info']['purePhoneNumber'];
$data['user_type'] = $user_type;
$data['register_method'] = 1;//注册方式(1:小程序授权 2:手机号 )
$data['avatar'] = $avatar;
$data['login_ip'] = (new Http())->getIp() ?? "";// 登陆ip
$data['last_login_at'] = date('Y-m-d H:i:s', time());// 最后登陆时间
$user = UserModel::addUser($data);
if (empty($user)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 新增对应用户数据表
$data = array();
$data['user_id'] = $user->user_id;
$data['user_name'] = $user['user_name'];
$data['open_id'] = $wx_info_data['openid'];
$data['union_id'] = $wx_info_data['unionid'] ?? "";
$data['wx_session_key'] = $wx_info_data['session_key'];
$data['status'] = 1;
$data['avatar'] = $avatar;
if ($user['user_type'] == 1) {
// 患者
$user_patient = UserPatientModel::addUserPatient($data);
if (empty($user_patient)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
$client_user_id = $user_patient['patient_id'];
} elseif ($user['user_type'] == 2) {
// 新增医生表
$user_doctor = UserDoctorModel::addUserDoctor($data);
if (empty($user_doctor)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
$client_user_id = $user_doctor['doctor_id'];
}
// 新增用户配置表
$params = array();
$params['user_id'] = $user['user_id'];
$user_system = UserSystem::getOne($params);
if (empty($user_system)) {
$data = array();
$data['user_id'] = $user['user_id'];
$data['is_accept_im_message_push'] = 1; // 默认新增一下配置表
$user_system = UserSystem::addUserSystem($data);
if (empty($user_system)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}
// 修改用户表创建者id
$params = array();
$params['user_id'] = $user['user_id'];
$data = array();
$data['created_by'] = $user['user_id'];
UserModel::editUser($params,$data);
// 创建im账号
$account = new Account();
// 创建单个账号
$account->createAccount($user->user_id, $user->user_name, addAliyunOssWebsite($avatar));
if ($user['user_type'] == 1) {
// 发放用户优惠卷
$CouponService = new CouponService();
$res = $CouponService->DistributeCoupon(1, (string)$user->user_id, $user_patient['patient_id']);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}
} else {
// 已注册用户
// 重复注册不同端
if ($user_type != $user['user_type']) {
Db::rollBack();
$result = UserTypeToString($user['user_type']);
return fail(HttpEnumCode::GET_WX_ERROR, "手机号已在" . $result . "注册");
}
// 获取对应端用户信息
$params = array();
$params['user_id'] = $user->user_id;
if ($user['user_type'] == 1) {
$result = UserPatientModel::getOne($params);
if (!empty($result)) {
$client_user_id = $result['patient_id'];
}
} elseif ($user['user_type'] == 2) {
$result = UserDoctorModel::getOne($params);
if (!empty($result)) {
$client_user_id = $result['doctor_id'];
}
} elseif ($user['user_type'] == 3) {
$result = UserPharmacistModel::getOne($params);
if (!empty($result)) {
$client_user_id = $result['pharmacist_id'];
}
}
if (empty($result)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 判断用户状态
if ($result['status'] != 1) {
Db::rollBack();
return fail(HttpEnumCode::USER_STATUS_ERROR);
}
$data = array();
if ($wx_info_data['session_key'] != $result['session_key']) {
// 更新session_key
$data['wx_session_key'] = $wx_info_data['session_key'];
}
if ($wx_info_data['openid'] != $result['open_id']) {
// 更新open_id
$data['open_id'] = $wx_info_data['openid'];
}
$data['updated_at'] = date('Y-m-d H:i:s', time());
$params = array();
if ($user['user_type'] == 1) {
$params['patient_id'] = $result['patient_id'];
$res = UserPatientModel::editUserPatient($params, $data);
} elseif ($user['user_type'] == 2) {
$params['doctor_id'] = $result['doctor_id'];
$res = UserDoctorModel::editUserDoctor($params, $data);
} elseif ($user['user_type'] == 3) {
$params['pharmacist_id'] = $result['pharmacist_id'];
$res = UserPharmacistModel::editUserPharmacist($params, $data);
}
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
try {
$avatar = addAliyunOssWebsite($user['avatar']);
$account = new Account();
// 查询账号导入状态
$res = $account->checkAccountStatus($user['user_id']);
if (!$res) {
// 创建单个账号
$account->createAccount($user['user_id'], $user['user_name'], $avatar);
}
} catch (\Throwable $e) {
Log::getInstance()->error("IM账号倒入失败");
}
}
// 记录用户登陆记录
$Http = new Http();
$login_ip = $Http->getIp();
$params = array();
$params['user_id'] = $user['user_id'];
$data = array();
$data['login_ip'] = $login_ip ?? "";
$data['last_login_at'] = date('Y-m-d H:i:s', time());
UserModel::editUser($params, $data);
// 组合生成token的数据
$token_user_data = array();
$token_user_data['user_id'] = (string)$user['user_id']; // 用户id
$token_user_data['user_type'] = $user['user_type'];// 用户类型
$token_user_data['open_id'] = $wx_info_data['openid'];// open_id
$token_user_data['client_user_id'] = (string)$client_user_id;// 对应客户端id
// 发放token
$Jwt = new Jwt();
$token = $Jwt->encode($token_user_data);
// 组合返回数据
$data = array();
$data['token'] = $token;
$data['user_id'] = (string)$user['user_id'];
$data['client_user_id'] = (string)$client_user_id;
Db::commit();
return success($data);
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
}
}
/**
* 手机号登陆
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function mobileLogin(): array
{
$code = $this->request->input('code');
$phone = $this->request->input('phone');
$user_type = $this->request->input('user_type');
$wx_code = $this->request->input('wx_code');
$app_env = config('app_env', 'dev');
if ($app_env != 'dev') {
$redis = $this->container->get(Redis::class);
// 验证验证码
$sms_code = $redis->get("login_code" . $phone);
if (empty($sms_code)) {
return fail(HttpEnumCode::CODE_EXPIRED);
}
if ($sms_code != $code) {
return fail(HttpEnumCode::CODE_ERROR);
}
}
try {
$weChat = new Wechat($user_type);
// 获取用户openid
$wx_info_data = $weChat->codeToSession($wx_code);
$session_key = $wx_info_data['session_key'] ?? "";
$open_id = $wx_info_data['openid'] ?? "";
} catch (\Exception $e) {
// 此处不进行处理
Log::getInstance()->info($e->getMessage());
}
Db::beginTransaction();
try {
// 获取用户信息
$params = array();
$params['mobile'] = $phone;
$user = UserModel::getOne($params);
if (empty($user)) {
// 处理药师特殊情况,后台添加,前台不允许注册
if ($user_type == 3) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, "账号不存在,请联系客服");
}
// 获取用户默认头像oss地址
$UserService = new UserService();
$avatar = $UserService->getUserDefaultOssAvatar($user_type);
// 新增用户表
$data = array();
$data['user_name'] = 'gdxz' . substr($phone, -4) . mt_rand(10000, 99999);;
$data['mobile'] = $phone;
$data['wx_mobile'] = $phone;
$data['user_type'] = $user_type;
$data['register_method'] = 2;
$data['avatar'] = $avatar;
$data['login_ip'] = (new Http())->getIp() ?? "";// 登陆ip
$data['last_login_at'] = date('Y-m-d H:i:s', time());// 最后登陆时间
$user = UserModel::addUser($data);
if (empty($user)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 新增对应用户数据表
$data = array();
$data['user_id'] = $user->user_id;
$data['user_name'] = $user['user_name'];
$data['status'] = 1;
$data['open_id'] = $open_id ?? '';
$data['wx_session_key'] = $session_key ?? "";
$data['avatar'] = $avatar;
if ($user['user_type'] == 1) {
// 患者
$user_patient = UserPatientModel::addUserPatient($data);
if (empty($user_patient)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
$client_user_id = $user_patient['patient_id'];
} elseif ($user['user_type'] == 2) {
// 新增医生表
$user_doctor = UserDoctorModel::addUserDoctor($data);
if (empty($user_doctor)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
$client_user_id = $user_doctor['doctor_id'];
} elseif ($user['user_type'] == 3) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
} else {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 新增用户配置表
$params = array();
$params['user_id'] = $user['user_id'];
$user_system = UserSystem::getOne($params);
if (empty($user_system)) {
$data = array();
$data['user_id'] = $user['user_id'];
$data['is_accept_im_message_push'] = 1; // 默认新增一下配置表
$user_system = UserSystem::addUserSystem($data);
if (empty($user_system)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}
// 修改用户表创建者id
$params = array();
$params['user_id'] = $user['user_id'];
$data = array();
$data['created_by'] = $user['user_id'];
UserModel::editUser($params,$data);
// 创建im账号
$account = new Account();
// 创建单个账号
$account->createAccount($user->user_id, $user->user_name, addAliyunOssWebsite($avatar));
if ($user['user_type'] == 1) {
// 发放用户优惠卷
$CouponService = new CouponService();
$res = $CouponService->DistributeCoupon(1, (string)$user->user_id, $user_patient['patient_id']);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}
} else {
// 已注册用户
if ($user_type != $user['user_type']) {
Db::rollBack();
$result = UserTypeToString($user['user_type']);
return fail(HttpEnumCode::HTTP_ERROR, "手机号为" . $result . "账号");
}
$params = array();
$params['user_id'] = $user->user_id;
if ($user['user_type'] == 1) {
$result = UserPatientModel::getOne($params);
if (!empty($result)) {
$client_user_id = $result['patient_id'];
}
} elseif ($user['user_type'] == 2) {
$result = UserDoctorModel::getOne($params);
if (!empty($result)) {
$client_user_id = $result['doctor_id'];
}
} elseif ($user['user_type'] == 3) {
$result = UserPharmacistModel::getOne($params);
if (!empty($result)) {
$client_user_id = $result['pharmacist_id'];
}
} else {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
if (empty($result)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 判断用户状态
if ($result['status'] != 1) {
Db::rollBack();
return fail(HttpEnumCode::USER_STATUS_ERROR);
}
$data = array();
if ($wx_info_data['session_key'] != $result['session_key']) {
// 更新session_key
$data['wx_session_key'] = $wx_info_data['session_key'];
}
if ($wx_info_data['openid'] != $result['open_id']) {
// 更新open_id
$data['open_id'] = $wx_info_data['openid'];
}
$data['updated_at'] = date('Y-m-d H:i:s', time());
$params = array();
if ($user['user_type'] == 1) {
$params['patient_id'] = $result['patient_id'];
$res = UserPatientModel::editUserPatient($params, $data);
} elseif ($user['user_type'] == 2) {
$params['doctor_id'] = $result['doctor_id'];
$res = UserDoctorModel::editUserDoctor($params, $data);
} elseif ($user['user_type'] == 3) {
$params['pharmacist_id'] = $result['pharmacist_id'];
$res = UserPharmacistModel::editUserPharmacist($params, $data);
} else {
Db::rollBack();
return fail(HttpEnumCode::USER_STATUS_ERROR);
}
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
try {
$avatar = addAliyunOssWebsite($user['avatar']);
$account = new Account();
// 查询账号导入状态
$res = $account->checkAccountStatus($user['user_id']);
if (!$res) {
// 创建单个账号
$account->createAccount($user['user_id'], $user['user_name'], $avatar);
}
} catch (\Throwable $e) {
Log::getInstance()->error("IM账号倒入失败");
}
}
// 记录用户登陆记录
$Http = new Http();
$login_ip = $Http->getIp();
$params = array();
$params['user_id'] = $user['user_id'];
$data = array();
$data['login_ip'] = $login_ip ?? "";
$data['last_login_at'] = date('Y-m-d H:i:s', time());
UserModel::editUser($params, $data);
// 组合生成token的数据
$token_user_data = array();
$token_user_data['user_id'] = (string)$user['user_id']; // 用户id
$token_user_data['user_type'] = $user['user_type'];// 用户类型
$token_user_data['open_id'] = $open_id ?? "";// open_id
$token_user_data['client_user_id'] = (string)$client_user_id;// 对应客户端id
// 发放token
$Jwt = new Jwt();
$token = $Jwt->encode($token_user_data);
// 登录成功,删除验证码
if ($app_env != 'dev') {
$redis->del("login_code" . $phone);
}
// 组合返回数据
$data = array();
$data['token'] = $token;
$data['user_id'] = (string)$user['user_id'];
$data['client_user_id'] = (string)$client_user_id;
Db::commit();
return success($data);
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage());
}
}
/**
* 微信授权接口
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ClientExceptionInterface
* @throws DecodingExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function wxAuthorize(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$wx_code = $this->request->input('wx_code');
if (empty($user_info)) {
return fail(HttpEnumCode::GET_WX_ERROR);
}
// 获取用户数据
$params = array();
$params['user_id'] = $user_info['user_id'];
$user = UserModel::getOne($params);
if (empty($user)) {
return fail();
}
try {
$weChat = new Wechat($user['user_type']);
// 获取用户openid
$wx_info_data = $weChat->codeToSession($wx_code);
if (empty($wx_info_data['session_key']) || empty($wx_info_data['openid'])) {
return fail(HttpEnumCode::GET_WX_ERROR);
}
// 获取对应端用户信息
$params = array();
$params['user_id'] = $user['user_id'];
if ($user['user_type'] == 1) {
$result = UserPatientModel::getOne($params);
} elseif ($user['user_type'] == 2) {
$result = UserDoctorModel::getOne($params);
} elseif ($user['user_type'] == 3) {
$result = UserPharmacistModel::getOne($params);
}
if (empty($result)) {
return fail(HttpEnumCode::SERVER_ERROR);
}
// 判断用户状态
if ($result['status'] != 1) {
return fail(HttpEnumCode::USER_STATUS_ERROR);
}
// 更新session_key
$data = array();
if ($wx_info_data['session_key'] != $result['session_key']) {
$data['wx_session_key'] = $wx_info_data['session_key'];
}
if ($wx_info_data['openid'] != $result['open_id']) {
$data['open_id'] = $wx_info_data['openid'];
}
if (!empty($data)) {
$data['updated_at'] = date('Y-m-d H:i:s', time());
$params = array();
if ($user['user_type'] == 1) {
$params['patient_id'] = $result['patient_id'];
$res = UserPatientModel::editUserPatient($params, $data);
} elseif ($user['user_type'] == 2) {
$params['doctor_id'] = $result['doctor_id'];
$res = UserDoctorModel::editUserDoctor($params, $data);
} elseif ($user['user_type'] == 3) {
$params['pharmacist_id'] = $result['pharmacist_id'];
$res = UserPharmacistModel::editUserPharmacist($params, $data);
} else {
$res = false;
}
if (!$res) {
return fail(HttpEnumCode::SERVER_ERROR);
}
}
} catch (\Throwable $e) {
// 此处不进行处理
return fail(HttpEnumCode::GET_WX_ERROR, $e->getMessage());
}
return success();
}
}