RegisterService.php 9.0 KB

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