RegisterService.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Niucloud-admin 企业快速开发的saas管理平台
  4. // +----------------------------------------------------------------------
  5. // | 官方网址:https://www.niucloud.com
  6. // +----------------------------------------------------------------------
  7. // | niucloud团队 版权所有 开源版本可自由商用
  8. // +----------------------------------------------------------------------
  9. // | Author: Niucloud Team
  10. // +----------------------------------------------------------------------
  11. namespace app\service\api\login;
  12. use app\dict\member\MemberLoginTypeDict;
  13. use app\dict\member\MemberRegisterTypeDict;
  14. use app\job\member\SetMemberNoJob;
  15. use app\model\member\Member;
  16. use app\service\api\captcha\CaptchaService;
  17. use app\service\api\member\MemberConfigService;
  18. use app\service\api\member\MemberService;
  19. use app\service\core\member\CoreMemberService;
  20. use app\service\core\shop\CoreShopMemberService;
  21. use core\base\BaseApiService;
  22. use core\exception\AuthException;
  23. use think\db\exception\DataNotFoundException;
  24. use think\db\exception\DbException;
  25. use think\db\exception\ModelNotFoundException;
  26. /**
  27. * 登录服务层
  28. * Class BaseService
  29. * @package app\service
  30. */
  31. class RegisterService extends BaseApiService
  32. {
  33. public function __construct()
  34. {
  35. parent::__construct();
  36. $this->model = new Member();
  37. }
  38. /**
  39. * 会员公共注册
  40. * @param string $mobile
  41. * @param $data
  42. * @param string $type
  43. * @param bool $is_verify_mobile
  44. * @return array
  45. * @throws DataNotFoundException
  46. * @throws DbException
  47. * @throws ModelNotFoundException
  48. */
  49. public function register(string $mobile, $data, string $type, bool $is_verify_mobile = true)
  50. {
  51. //校验注册方式
  52. if (empty(MemberRegisterTypeDict::getType()[ $type ]))
  53. throw new AuthException('REG_CHANNEL_NOT_EXIST');
  54. $data = $this->bindByMobile($mobile, $data, $type, $is_verify_mobile);
  55. $member_service = new MemberService();
  56. if (!is_array($data)) {
  57. $member_id = $data;
  58. } else {
  59. if (empty($data[ 'nickname' ])) {
  60. if (!empty($data[ 'username' ])) {
  61. $data[ 'nickname' ] = $data[ 'username' ];
  62. } elseif (!empty($mobile)) {
  63. $data[ 'nickname' ] = substr_replace($mobile, '****', 3, 4);
  64. } else {
  65. $data[ 'nickname' ] = $this->createName();
  66. }
  67. }
  68. $data[ 'register_channel' ] = $this->channel;
  69. $data[ 'register_type' ] = $type;
  70. $data[ 'site_id' ] = $this->request->defaultSiteId();
  71. $pid = $this->request->get('pid', $this->request->post('pid', 0));
  72. if ($pid > 0) {
  73. $p_member_info = $member_service->findMemberInfo([ 'member_id' => $pid ]);
  74. if (!$p_member_info->isEmpty()) $data[ 'pid' ] = $pid;//设置上级推荐人
  75. }
  76. $member_id = ( new MemberService() )->add($data);
  77. $data[ 'member_id' ] = $member_id;
  78. event('MemberRegister', $data);
  79. $site_id = $this->request->get('site_id', $this->request->post('site_id', 0));
  80. if ($site_id > 0 && $member_id > 0) {
  81. (new CoreShopMemberService())->findShopMemberCreateIfcNotExist($site_id, $member_id);//更新店铺会员表
  82. }
  83. SetMemberNoJob::dispatch([ 'member_id' => $member_id ]);
  84. }
  85. $member_info = $member_service->findMemberInfo([ 'member_id' => $member_id ]);
  86. if ($member_info->isEmpty()) throw new AuthException('MEMBER_NOT_EXIST');//账号不存在
  87. return ( new LoginService() )->login($member_info, $type);
  88. }
  89. /**
  90. * 随机创建一个昵称
  91. * @return string
  92. */
  93. public function createName()
  94. {
  95. $microtime = substr(microtime(true), strpos(microtime(true), '.') + 1);
  96. $chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  97. $username = '';
  98. for ($i = 0; $i < 6; $i++) {
  99. $username .= $chars[ random_int(0, (strlen($chars) - 1)) ];
  100. }
  101. return $microtime . strtoupper(base_convert(time() - 1420070400, 10, 36)) . $username;
  102. }
  103. /**
  104. * 账号注册
  105. * @param string $username
  106. * @param string $password
  107. * @param $mobile
  108. * @return array
  109. */
  110. public function account(string $username, string $password, $mobile)
  111. {
  112. //todo 校验验证码 可以加try catch 后续
  113. ( new CaptchaService() )->check();
  114. //登录注册配置
  115. $config = ( new MemberConfigService() )->getLoginConfig();
  116. $is_username = $config[ 'is_username' ];
  117. //未开启账号密码登录注册
  118. if ($is_username != 1) throw new AuthException('MEMBER_USERNAME_LOGIN_NOT_OPEN');
  119. $member_service = new MemberService();
  120. $member_info = $member_service->findMemberInfo([ 'username' => $username ]);
  121. if (!$member_info->isEmpty()) throw new AuthException('MEMBER_IS_EXIST');//账号已存在
  122. $password_hash = create_password($password);
  123. $data = array (
  124. 'username' => $username,
  125. 'password' => $password_hash,
  126. );
  127. return $this->register($mobile, $data, MemberRegisterTypeDict::USERNAME);
  128. }
  129. /**
  130. * 手机号注册
  131. * @param $mobile
  132. * @return array
  133. */
  134. public function mobile($mobile)
  135. {
  136. //登录注册配置
  137. $config = ( new MemberConfigService() )->getLoginConfig();
  138. $is_mobile = $config[ 'is_mobile' ];
  139. $is_bind_mobile = $config[ 'is_bind_mobile' ];
  140. //未开启手机号登录注册
  141. if ($is_mobile != 1 && $is_bind_mobile != 1) throw new AuthException('MOBILE_LOGIN_UNOPENED');
  142. $member_service = new MemberService();
  143. $member_info = $member_service->findMemberInfo([ 'mobile' => $mobile ]);
  144. if (!$member_info->isEmpty()) throw new AuthException('MEMBER_IS_EXIST');//账号已存在
  145. $data = array (
  146. 'mobile' => $mobile,
  147. );
  148. return $this->register($mobile, $data, MemberRegisterTypeDict::MOBILE);
  149. }
  150. /**
  151. * 校验是否启用第三方登录注册
  152. * @return true
  153. */
  154. public function checkAuth()
  155. {
  156. $config = ( new MemberConfigService() )->getLoginConfig();
  157. $is_auth_register = $config[ 'is_auth_register' ];
  158. if ($is_auth_register != 1) throw new AuthException('AUTH_LOGIN_NOT_OPEN');//手机号已存在
  159. return true;
  160. }
  161. /**
  162. * 通过手机号尝试绑定已存在会员,没有就绑定数据(todo 仅限注册使用)
  163. * @param string $mobile
  164. * @param array $data
  165. * @param string $type
  166. * @param bool $is_verify
  167. * @return array|mixed
  168. */
  169. public function bindByMobile($mobile, array $data, string $type, bool $is_verify = true)
  170. {
  171. $config = ( new MemberConfigService() )->getLoginConfig();
  172. $is_bind_mobile = $config[ 'is_bind_mobile' ];
  173. $with_field = match($type){
  174. MemberLoginTypeDict::USERNAME => 'username',
  175. MemberLoginTypeDict::MOBILE => 'mobile',
  176. MemberLoginTypeDict::WECHAT => 'wx_openid',
  177. MemberLoginTypeDict::WEAPP => 'weapp_openid',
  178. };
  179. if ($type == MemberLoginTypeDict::MOBILE || $type == MemberLoginTypeDict::WEAPP || $is_bind_mobile == 1) {
  180. //增加判断,否则公众号第三方注册会提示手机号必须填写
  181. if ($type == MemberLoginTypeDict::MOBILE || ( $type == MemberLoginTypeDict::USERNAME && $is_bind_mobile == 1 )) {
  182. if (empty($mobile)) throw new AuthException('MOBILE_NEEDED');//必须填写
  183. //todo 校验手机号验证码
  184. if ($is_verify) {
  185. (new LoginService())->checkMobileCode($mobile);
  186. }
  187. }
  188. if (!empty($mobile)) {
  189. $member_service = new MemberService();
  190. $member = $member_service->findMemberInfo(['mobile' => $mobile]);
  191. if (!$member->isEmpty()) {
  192. if ($type == MemberLoginTypeDict::MOBILE) {
  193. throw new AuthException('MOBILE_IS_EXIST');//手机号注册时发现手机号已存在账号
  194. } else {
  195. if ($member->$with_field != '') throw new AuthException('MOBILE_IS_EXIST');//手机号已存在
  196. foreach ($data as $k => $v) {
  197. $member->$k = $v;
  198. }
  199. $member->save();
  200. return $member->member_id;
  201. }
  202. }
  203. $data['mobile'] = $mobile;
  204. }
  205. }
  206. return $data;
  207. }
  208. }