LoginForm.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\alliance\models;
  8. use app\constants\OptionSetting;
  9. use app\models\Option;
  10. use app\models\Share;
  11. use app\models\User;
  12. use app\models\WechatConfig;
  13. use app\modules\client\models\ApiModel;
  14. use app\utils\Notice\NoticeSend;
  15. use yii\base\BaseObject;
  16. use yii\helpers\Json;
  17. use app\modules\client\models\v1\BindForm;
  18. use app\models\SaasUser;
  19. class LoginForm extends ApiModel
  20. {
  21. // 前端类型
  22. public $_platform;
  23. // 商城id
  24. public $store_id;
  25. // 微信小程序
  26. public $code;
  27. public $user_info;
  28. public $encrypted_data;
  29. public $iv;
  30. public $signature;
  31. // 手机注册
  32. public $phone;
  33. public $verify_code;
  34. // 分销商user_id
  35. public $share_user_id;
  36. /**
  37. * @var User $user
  38. */
  39. public $user;
  40. // 微信小程序
  41. const PLATFORM_WX = 'wx';
  42. // 微信公众号
  43. const PLATFORM_MP = 'mp';
  44. // app端微信
  45. const PLATFORM_APP = 'app';
  46. // 手机号注册登录
  47. const PLATFORM_PHONE = 'phone';
  48. // 短信登录验证码
  49. const CACHE_KEY_SMS_LOGIN = '_mobile_sms_login_';
  50. // 绑定手机号验证码
  51. const CACHE_KEY_BIND_PHONE = '_mobile_bind_';
  52. // 验证码类型
  53. // 手机登录
  54. const TYPE_VERIFY_CODE_LOGIN = 'login';
  55. // 手机绑定
  56. const TYPE_VERIFY_CODE_BIND = 'bind';
  57. public $parent_id;
  58. public $appCid;
  59. public function rules()
  60. {
  61. return [
  62. ['_platform', 'in', 'range' => [self::PLATFORM_WX, self::PLATFORM_MP, self::PLATFORM_APP, self::PLATFORM_PHONE]],
  63. ['_platform', 'required'],
  64. [['code', 'user_info', 'encrypted_data', 'iv', 'signature'], 'required', 'on' => self::PLATFORM_WX],
  65. [['user_info'], 'required', 'on' => self::PLATFORM_APP],
  66. [['phone', 'verify_code'], 'required', 'on' => self::PLATFORM_PHONE],
  67. [['phone'], 'match', 'pattern' => '/^1[3456789]\d{9}$/', 'message' => '手机号错误'],
  68. [['verify_code', 'parent_id', 'share_user_id'], 'integer'],
  69. [['code', 'user_info', 'encrypted_data', 'iv', 'signature', 'phone'], 'string'],
  70. [['code', 'user_info', 'encrypted_data', 'iv', 'signature', 'phone'], 'trim'],
  71. ];
  72. }
  73. public function attributeLabels()
  74. {
  75. return [
  76. 'login_type' => 'login_type',
  77. '_platform' => '_platform',
  78. 'store_id' => 'store_id',
  79. 'code' => 'code',
  80. 'user_info' => 'user_info',
  81. 'encrypted_data' => 'encrypted_data',
  82. 'iv' => 'iv',
  83. 'signature' => 'signature',
  84. 'share_user_id' => 'share_user_id',
  85. ];
  86. }
  87. public function scenarios()
  88. {
  89. $scenarios = parent::scenarios();
  90. return $scenarios;
  91. }
  92. /**
  93. * 登录统一入口
  94. * @return array
  95. * @throws \yii\base\Exception
  96. */
  97. public function login()
  98. {
  99. if ($this->_platform == self::PLATFORM_WX) {
  100. // 微信小程序登录
  101. return $this->loginWX();
  102. } else if ($this->_platform == self::PLATFORM_APP) {
  103. // app端微信登录
  104. return $this->loginAppWechat();
  105. } else if ($this->_platform == self::PLATFORM_PHONE) {
  106. // 手机号登录,没有找到手机号自动注册
  107. return $this->phoneLogin();
  108. } else {
  109. return [
  110. 'code' => 1,
  111. 'msg' => '登录失败,请检查参数是否正确'
  112. ];
  113. }
  114. }
  115. /**
  116. * 微信登录方法
  117. * @return array
  118. */
  119. private function loginWX()
  120. {
  121. if ($this->validate()) {
  122. try {
  123. //获取session
  124. $session = self::getWechat()->auth->session($this->code);
  125. if (!$session || empty($session['openid'])) {
  126. throw new \Exception('获取openid失败.');
  127. }
  128. // 验证
  129. $decryptedData = self::getWechat()->encryptor->decryptData($session['session_key'], $this->iv, $this->encrypted_data);
  130. $user_info = json_decode($this->user_info, true);
  131. $user_info['nickName'] = preg_replace('/[\xf0-\xf7].{3}/', '', $user_info['nickName']);
  132. $data = [
  133. 'openId' => $session['openid'],
  134. 'nickName' => isset($user_info['nickName']) ? $user_info['nickName'] : $this->getNickName(),
  135. 'gender' => $user_info['gender'],
  136. 'city' => $user_info['city'],
  137. 'province' => $user_info['province'],
  138. 'country' => $user_info['country'],
  139. 'avatarUrl' => $user_info['avatarUrl'] ?: \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/statics/images/avatar.png',
  140. 'unionId' => isset($session['unionid']) ? $session['unionid'] : '',
  141. ];
  142. $user = User::find()->where(['store_id' => $this->store_id, 'platform' => 0])->andWhere(['binding' => $this->phone])->orderBy('id desc')->one();
  143. if (!$user) {
  144. $user = new User();
  145. $user->type = User::USER_TYPE_NORMAL;
  146. $user->binding = isset($decryptedData['phoneNumber']) ? $decryptedData['phoneNumber'] : '';
  147. $user->username = $data['openId'];
  148. $user->password = \Yii::$app->security->generatePasswordHash(\Yii::$app->security->generateRandomString(), 5);
  149. $user->auth_key = \Yii::$app->security->generateRandomString();
  150. $user->access_token = \Yii::$app->security->generateRandomString();
  151. $user->is_delete = User::USER_NOT_DELETE;
  152. $user->wechat_open_id = $data['openId'];
  153. $user->wechat_union_id = $data['unionId'];
  154. $user->store_id = $this->store_id;
  155. $user->platform = User::USER_FROM_WECHAT; // 微信
  156. }
  157. $user->binding = $this->phone;
  158. $user->nickname = $data['nickName'];
  159. $user->avatar_url = $data['avatarUrl'];
  160. if (empty($user->wechat_open_id) || (!empty($data['openId']) && $user->wechat_open_id !== $data['openId'])) {
  161. $user->wechat_open_id = $data['openId'];
  162. }
  163. if (empty($user->wechat_union_id) || (!empty($data['unionId']) && $user->wechat_union_id !== $data['unionId'])) {
  164. $user->wechat_union_id = $data['unionId'];
  165. }
  166. if (!$user->save()) {
  167. return [
  168. 'code' => 1,
  169. 'msg' => '登陆失败',
  170. 'data' => $user->getErrorSummary(false)[0]
  171. ];
  172. }
  173. // 创建平台会员saas_user
  174. $saas_user = SaasUser::find()->where(['mobile' => $user->binding, 'is_delete' => SaasUser::DELETE_STATUS_FALSE])->one();
  175. if (!$saas_user) {
  176. $saas_user = new SaasUser();
  177. $saas_user->mobile = $user->binding;
  178. $saas_user->store_id = $this->store_id;
  179. $saas_user->save();
  180. }
  181. // 是否开启强制绑定手机号
  182. $is_open_bind = Option::get(OptionSetting::STORE_LOGIN_FORCIBLY_BIND_MOBILE, $this->store_id, 'store')['value'];
  183. $share = $share_user = null;
  184. if ($user->parent_id > 0) {
  185. $share = Share::findOne(['user_id' => $user->parent_id]);
  186. $share_user = User::findOne(['id' => $share->user_id]);
  187. }
  188. if ($this->share_user_id > 0) {
  189. // 绑定上下级
  190. $bindForm = new BindForm();
  191. $bindForm->store_id = $this->store_id;
  192. $bindForm->user_id = $user->id;
  193. $bindForm->parent_id = $this->share_user_id;
  194. $bindForm->condition = 0;
  195. $bindForm->save();
  196. }
  197. $data = [
  198. 'access_token' => $user->access_token,
  199. 'nickname' => $user->nickname,
  200. 'avatar_url' => $user->avatar_url,
  201. 'is_distributor' => $user->is_distributor ? $user->is_distributor : 0,
  202. 'errCode' => 0,
  203. 'parent' => $share ? ($share->name ? $share->name : $share_user->nickname) : '总店',
  204. 'id' => $user->id,
  205. 'is_clerk' => $user->is_clerk === null ? 0 : $user->is_clerk,
  206. 'integral' => $user->integral === null ? 0 : $user->integral,
  207. 'money' => $user->money === null ? 0 : $user->money,
  208. 'binding' => $user->binding,
  209. 'level' => $user->level,
  210. 'blacklist' => $user->blacklist,
  211. 'is_open_bind' => $is_open_bind ? $is_open_bind : 0
  212. ];
  213. return [
  214. 'code' => 0,
  215. 'data' => $data,
  216. 'msg' => '登陆成功'
  217. ];
  218. } catch (\Exception $e) {
  219. return [
  220. 'code' => 1,
  221. 'msg' => '登录失败',
  222. 'data' => $e->getMessage() . 'line:' . $e->getLine() . 'file:' . $e->getFile()
  223. ];
  224. }
  225. } else {
  226. // 验证失败:$errors 是一个包含错误信息的数组
  227. return [
  228. 'code' => 1,
  229. 'msg' => $this->getErrorSummary(false)[0]
  230. ];
  231. }
  232. }
  233. /**
  234. * app 微信登录
  235. * @return array
  236. * @throws \yii\base\Exception
  237. */
  238. public function loginAppWechat()
  239. {
  240. if (!$this->validate()) {
  241. return [
  242. 'code' => 1,
  243. 'msg' => $this->getErrorSummary(false)[0]
  244. ];
  245. }
  246. $user_info = Json::decode($this->user_info);
  247. $user = null;
  248. if (isset($user_info['unionId']) && $user_info['unionId'] != '') {
  249. $user = User::findOne(['wechat_union_id' => $user_info['unionId'], 'store_id' => $this->store_id]);
  250. }
  251. if (!$user) {
  252. $user = User::findOne(['wechat_open_id' => $user_info['openId'], 'store_id' => $this->store_id]);
  253. }
  254. // 是否开启强制绑定手机号
  255. $is_open_bind = Option::get(OptionSetting::STORE_LOGIN_FORCIBLY_BIND_MOBILE, $this->store_id, 'store')['value'];
  256. if(!$user){
  257. $user = new User();
  258. $user->type = 1;
  259. $user->username = $user_info['openId'];
  260. $user->password = \Yii::$app->security->generatePasswordHash(\Yii::$app->security->generateRandomString(), 5);
  261. $user->auth_key = \Yii::$app->security->generateRandomString();
  262. $user->access_token = \Yii::$app->security->generateRandomString();
  263. $user->created_at = time();
  264. $user->is_delete = 0;
  265. $user->wechat_open_id = $user_info['openId'];
  266. $user->wechat_union_id = isset($user_info['unionId']) ? $user_info['unionId'] : '';
  267. $user->nickname = preg_replace('/[\xf0-\xf7].{3}/', '', $user_info['nickName']);
  268. $user->avatar_url = $user_info['avatarUrl'] ? $user_info['avatarUrl'] : \Yii::$app->request->hostInfo . '/web/v1/statics/images/avatar.png';
  269. $user->store_id = 1;
  270. $user->platform = 3; // APP
  271. $user->level = -1;
  272. if(isset($user_info['appCid']) && !empty($user_info['appCid'])){
  273. $user->appcid = $user_info['appCid'];
  274. }
  275. if($user->save()){
  276. // \Yii::$app->user->login($user);
  277. $parent = User::findOne($user->parent_id);
  278. $share = Share::findOne(['user_id' => $user->parent_id]);
  279. $data = [
  280. 'to_bind' => 1,
  281. 'nickname' => $user->nickname,
  282. 'binding' => $user->binding ? $user->binding : '',
  283. 'id' => $user->id,
  284. 'avatar_url' => $user->avatar_url,
  285. 'is_distributor' => $user->is_distributor ? $user->is_distributor : 0,
  286. 'integral' => $user->integral ? $user->integral : 0,
  287. 'money' => $user->money ? $user->money : 0,
  288. 'blacklist' => $user->blacklist ? $user->blacklist : 0,
  289. 'access_token' => $user->access_token,
  290. 'is_clerk' => $user->is_clerk === null ? 0 : $user->is_clerk,
  291. 'parent' => $share ? ($share->name ? $share->name : $parent->nickname) : "总店",
  292. 'level' => $user->level,
  293. 'is_open_bind' => $is_open_bind ? $is_open_bind : 0
  294. ];
  295. } else {
  296. return [
  297. 'code' => 1,
  298. 'msg' => '登录失败',
  299. 'data' => $user->errors[0]
  300. ];
  301. }
  302. } else {
  303. if(isset($user_info['appCid']) && !empty($user_info['appCid']) && $user->appcid != $user_info['appCid']){
  304. $user->appcid = $user_info['appCid'];
  305. }
  306. if (empty($user->wechat_union_id)) {
  307. $user->wechat_union_id = isset($user_info['unionId']) ? $user_info['unionId'] : '';
  308. }
  309. $user->nickname = preg_replace('/[\xf0-\xf7].{3}/', '', $user_info['nickName']);
  310. $user->avatar_url = $user_info['avatarUrl'];
  311. $user->save();
  312. // \Yii::$app->user->login($user);
  313. $parent = User::findOne($user->parent_id);
  314. $share = Share::findOne(['user_id' => $user->parent_id]);
  315. $data = [
  316. 'to_bind' => 0,
  317. 'nickname' => $user->nickname,
  318. 'binding' => $user->binding === null ? '' : $user->binding,
  319. 'id' => $user->id,
  320. 'avatar_url' => $user->avatar_url,
  321. 'is_distributor' => $user->is_distributor,
  322. 'integral' => $user->integral,
  323. 'money' => $user->money,
  324. 'blacklist' => $user->blacklist,
  325. 'access_token' => $user->access_token,
  326. 'is_clerk' => $user->is_clerk === null ? 0 : $user->is_clerk,
  327. 'parent' => $share ? ($share->name ? $share->name : $parent->nickname) : "总店",
  328. 'level' => $user->level,
  329. 'is_open_bind' => $is_open_bind ? $is_open_bind : 0
  330. ];
  331. }
  332. return [
  333. 'code' => 0,
  334. 'msg' => '登录成功',
  335. 'data' => $data
  336. ];
  337. }
  338. /**
  339. * 手机号登录
  340. * @return array
  341. * @throws \yii\base\Exception
  342. */
  343. public function loginAppPhone()
  344. {
  345. if (!$this->validate()) {
  346. return [
  347. 'code' => 1,
  348. 'msg' => $this->getErrorSummary(false)[0]
  349. ];
  350. }
  351. // 验证码验证
  352. $result = $this->verifySmsCode(self::CACHE_KEY_SMS_LOGIN);
  353. if ($result['code'] == 1) {
  354. return $result;
  355. }
  356. $parent_name = '总店';
  357. /**
  358. * @var User $user
  359. */
  360. $user = User::find()->where(['store_id' => $this->store_id, 'type' => 1, 'is_delete' => 0, 'blacklist' => 0,
  361. 'binding' => $this->phone])->one();
  362. if (!$user) {
  363. $password = '0';
  364. $user = new User();
  365. $user->type = 1;
  366. $user->username = \Yii::$app->security->generateRandomString();
  367. $user->password = $password;
  368. $user->auth_key = \Yii::$app->security->generateRandomString();
  369. $user->access_token = \Yii::$app->security->generateRandomString();
  370. $user->created_at = time();
  371. $user->is_delete = 0;
  372. $user->binding = $this->phone;
  373. $user->nickname = $this->getDefaultNickname($this->phone);
  374. $user->avatar_url = $this->getDefaultAvatar();
  375. $user->store_id = $this->store_id;
  376. $user->platform = User::USER_FROM_PHONE;
  377. if ($this->appCid) {
  378. $user->appcid = $this->appCid;
  379. }
  380. if ($this->parent_id > 0) {
  381. $parent_id = $this->parent_id;
  382. $setting = Option::get('share_basic_setting', get_store_id());
  383. $setting = $setting ? Json::decode($setting['value']) : [];
  384. if (!$setting || $setting['level']['value'] == 0) {
  385. $parent_id = 0;
  386. }
  387. if ($parent_id > 0) {
  388. $exists = Share::find()->andWhere(['user_id' => $this->parent_id, 'store_id' => $this->store_id,
  389. 'is_delete' => 0, 'status' => 1]);
  390. if ($exists->exists()) {
  391. $parent_name = $exists->one()->name;
  392. $user->parent_id = $parent_id;
  393. } else {
  394. $parent_name = User::findOne(['id' => $this->parent_id])->nickname;
  395. }
  396. }
  397. }
  398. if ($user->save()) {
  399. $data = [
  400. 'nickname' => $user->nickname,
  401. 'binding' => $user->binding,
  402. 'id' => $user->id,
  403. 'avatar_url' => $user->avatar_url,
  404. 'is_distributor' => $user->is_distributor ? $user->is_distributor : 0,
  405. 'integral' => $user->integral ? $user->integral : 0,
  406. 'money' => $user->money ? $user->money : 0,
  407. 'blacklist' => $user->blacklist ? $user->blacklist : 0,
  408. 'access_token' => $user->access_token,
  409. 'is_clerk' => $user->is_clerk === null ? 0 : $user->is_clerk,
  410. 'parent' => $parent_name,
  411. 'level' => -1
  412. ];
  413. return [
  414. 'code' => 0,
  415. 'msg' => '注册成功',
  416. 'data' => $data,
  417. ];
  418. } else {
  419. foreach ($user->errors as $error) {
  420. return [
  421. 'code' => 1,
  422. 'msg' => $error
  423. ];
  424. }
  425. }
  426. }
  427. if ($user->parent_id > 0) {
  428. $share = Share::findOne(['user_id' => $user->parent_id]);
  429. $parent_user = User::findOne($user->parent_id);
  430. $parent_name = $share ? ($share->name ? $share->name : $parent_user->nickname) : "总店";
  431. }
  432. $data = [
  433. 'nickname' => $user->nickname,
  434. 'binding' => $user->binding,
  435. 'id' => $user->id,
  436. 'avatar_url' => $user->avatar_url,
  437. 'is_distributor' => $user->is_distributor,
  438. 'integral' => $user->integral,
  439. 'money' => $user->money,
  440. 'blacklist' => $user->blacklist,
  441. 'access_token' => $user->access_token,
  442. 'is_clerk' => $user->is_clerk === null ? 0 : $user->is_clerk,
  443. 'parent' => $parent_name,
  444. 'level' => $user->level
  445. ];
  446. return [
  447. 'code' => 0,
  448. 'msg' => '登录成功',
  449. 'data' => $data,
  450. ];
  451. }
  452. public function phoneLogin() {
  453. if (!$this->validate()) {
  454. return [
  455. 'code' => 1,
  456. 'msg' => $this->getErrorSummary(false)[0]
  457. ];
  458. }
  459. // 验证码验证
  460. $result = $this->verifySmsCode(self::CACHE_KEY_SMS_LOGIN);
  461. if ($result['code'] == 1) {
  462. return $result;
  463. }
  464. // 创建平台会员saas_user
  465. $saas_user = SaasUser::find()->where(['mobile' => $this->phone, 'is_delete' => SaasUser::DELETE_STATUS_FALSE])->one();
  466. if (!$saas_user) {
  467. $saas_user = new SaasUser();
  468. $saas_user->access_token = \Yii::$app->security->generateRandomString();
  469. $saas_user->name = substr_replace($this->phone, '******', 3, 6);
  470. $saas_user->mobile = $this->phone;
  471. $saas_user->platform_open_id = '';
  472. $saas_user->avatar = \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/v1/statics/images/avatar.png';
  473. $saas_user->store_id = $this->store_id;
  474. $saas_user->save();
  475. } else {
  476. if (empty($saas_user->name)) {
  477. $saas_user->name = substr_replace($this->phone, '****', 3, 4);
  478. }
  479. if (empty($saas_user->avatar)) {
  480. $saas_user->avatar = \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/v1/statics/images/avatar.png';
  481. }
  482. if (empty($saas_user->access_token)) {
  483. $saas_user->access_token = \Yii::$app->security->generateRandomString();
  484. }
  485. // $saas_user->platform_open_id = $this->phone;
  486. $saas_user->save();
  487. }
  488. // 平台登录 todo: 后续补充其他数据
  489. if ($this->store_id == 0) {
  490. return [
  491. 'code' => 0,
  492. 'msg' => '登录成功',
  493. 'data' => [
  494. 'access_token' => $saas_user->access_token,
  495. 'nickname' => $saas_user->name,
  496. 'avatar_url' => $saas_user->avatar,
  497. 'id' => $saas_user->id,
  498. 'money' => $saas_user->share_profit,
  499. 'integral' => $saas_user->integral
  500. ]
  501. ];
  502. }
  503. $user = User::findOne(['binding' => $this->phone, 'store_id' => $this->store_id, 'is_delete' => 0]);
  504. $share = $share_user = null;
  505. if ($user) {
  506. if ($user->blacklist == '1') {
  507. return [
  508. 'code' => 1,
  509. 'msg' => '您的账号已被限制登录!',
  510. ];
  511. }
  512. $data = [
  513. 'access_token' => $saas_user->access_token,
  514. 'nickname' => $saas_user->name,
  515. 'avatar_url' => $saas_user->avatar,
  516. 'is_distributor' => $user->is_distributor ? $user->is_distributor : 0,
  517. 'errCode' => 0,
  518. 'id' => $user->id,
  519. 'is_clerk' => $user->is_clerk === null ? 0 : $user->is_clerk,
  520. 'integral' => $user->integral === null ? 0 : $user->integral,
  521. 'money' => $user->money === null ? 0 : $user->money,
  522. 'binding' => $user->binding,
  523. 'level' => $user->level,
  524. 'blacklist' => $user->blacklist,
  525. 'is_saas_clerk' => (int)$user->is_saas_clerk,
  526. 'wechat_app_open_id' => $user->wechat_app_open_id,
  527. 'wechat_platform_open_id' => $user->wechat_platform_open_id,
  528. 'h5_auth_link' => self::getAuthLink()
  529. ];
  530. } else {
  531. $data = [
  532. 'nickName' => substr_replace($this->phone, '******', 3, 6),
  533. 'avatarUrl' => \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/v1/statics/images/avatar.png',
  534. ];
  535. $user = new User();
  536. $user->type = User::USER_TYPE_NORMAL;
  537. $user->binding = $this->phone;
  538. $user->nickname = $data['nickName'];
  539. $user->avatar_url = $data['avatarUrl'];
  540. $user->username = \Yii::$app->security->generateRandomString();
  541. $user->password = \Yii::$app->security->generatePasswordHash(\Yii::$app->security->generateRandomString(), 5);
  542. $user->auth_key = \Yii::$app->security->generateRandomString();
  543. $user->access_token = \Yii::$app->security->generateRandomString();
  544. $user->is_delete = User::USER_NOT_DELETE;
  545. $user->store_id = $this->store_id;
  546. $user->platform = User::USER_FROM_PHONE; // 手机号
  547. if (!$user->save()) {
  548. return [
  549. 'code' => 1,
  550. 'msg' => '登陆失败',
  551. 'data' => $user->getErrorSummary(false)[0]
  552. ];
  553. }
  554. $data = [
  555. 'access_token' => $saas_user->access_token,
  556. 'nickname' => $saas_user->name,
  557. 'avatar_url' => $saas_user->avatar,
  558. 'is_distributor' => $user->is_distributor ? $user->is_distributor : 0,
  559. 'errCode' => 0,
  560. 'id' => $user->id,
  561. 'is_clerk' => $user->is_clerk === null ? 0 : $user->is_clerk,
  562. 'integral' => $user->integral === null ? 0 : $user->integral,
  563. 'money' => $user->money === null ? 0 : $user->money,
  564. 'binding' => $user->binding,
  565. 'level' => $user->level,
  566. 'blacklist' => $user->blacklist,
  567. 'is_saas_clerk' => 0,
  568. 'wechat_app_open_id' => $user->wechat_app_open_id,
  569. 'wechat_platform_open_id' => $user->wechat_platform_open_id,
  570. 'h5_auth_link' => self::getAuthLink()
  571. ];
  572. }
  573. return [
  574. 'code' => 0,
  575. 'data' => $data,
  576. 'msg' => '登录成功'
  577. ];
  578. }
  579. /**
  580. * 验证验证码
  581. * @param string $key
  582. * @return array
  583. */
  584. public function verifySmsCode($key)
  585. {
  586. $smsCode = cache()->get($this->phone . $key . $this->store_id);
  587. if (!$smsCode) {
  588. return [
  589. 'code' => 1,
  590. 'msg' => '验证码错误',
  591. ];
  592. }
  593. if (strval($this->verify_code) !== strval($smsCode)) {
  594. return [
  595. 'code' => 1,
  596. 'msg' => '验证码错误',
  597. ];
  598. }
  599. cache()->delete($this->phone . $key . $this->store_id);
  600. return [
  601. 'code' => 0,
  602. 'msg' => '验证成功',
  603. ];
  604. }
  605. /**
  606. * 返回默认头像
  607. */
  608. protected function getDefaultAvatar()
  609. {
  610. return \Yii::$app->request->hostInfo . '/web/v1/statics/images/avatar.png';
  611. }
  612. /**
  613. * 返回默认用户名
  614. */
  615. protected function getDefaultNickname($phone)
  616. {
  617. $randStr = \Yii::$app->security->generateRandomString(5);
  618. return $randStr . '_' . substr($phone, -4, 4);
  619. }
  620. /**
  621. * 发送验证码
  622. * @param string $key
  623. * @return array
  624. */
  625. public function sendCode($key)
  626. {
  627. if (!$this->phone || !preg_match("/^1[3456789]\d{9}$/", $this->phone)) {
  628. return [
  629. 'code' => 1,
  630. 'msg' => '参数不正确',
  631. ];
  632. }
  633. $sms_code = mt_rand(100000, 999999);
  634. $sendResult = NoticeSend::VerifyCode($this->phone, $sms_code, true);
  635. if ($sendResult['code'] == 1) {
  636. return $sendResult;
  637. }
  638. // 验证码有效期5分钟
  639. cache()->set($this->phone . $key . $this->store_id, $sms_code, 600);
  640. return [
  641. 'code' => 0,
  642. 'msg' => '发送成功',
  643. ];
  644. }
  645. /**
  646. * 绑定手机号
  647. * @return array
  648. */
  649. public function bindPhone()
  650. {
  651. if (!trim($this->phone) || !$this->verify_code || !preg_match("/^1[3456789]\d{9}$/", $this->phone)) {
  652. return [
  653. 'code' => 1,
  654. 'msg' => '参数不正确',
  655. ];
  656. }
  657. $user = User::find()->where(['store_id' => $this->store_id, 'type' => 1, 'is_delete' => 0, 'blacklist' => 0,
  658. 'binding' => $this->phone])->one();
  659. if ($user) {
  660. return [
  661. 'code' => 1,
  662. 'msg' => '该手机号已经被绑定',
  663. ];
  664. }
  665. // 验证码验证
  666. $result = $this->verifySmsCode(self::CACHE_KEY_BIND_PHONE);
  667. if ($result['code'] == 1) {
  668. return $result;
  669. }
  670. $this->user->binding = trim($this->phone);
  671. if ($this->user->save()) {
  672. return [
  673. 'code' => 0,
  674. 'msg' => '绑定成功',
  675. ];
  676. } else {
  677. foreach ($this->user->errors as $error) {
  678. return [
  679. 'code' => 1,
  680. 'msg' => $error
  681. ];
  682. }
  683. }
  684. }
  685. /**
  686. * 微信浏览器h5授权链接
  687. */
  688. public static function getAuthLink() {
  689. $redirect_url = \Yii::$app->request->hostInfo . '/h5/#/pages/login/login_res';
  690. return getAuthLink(get_store_id(), $redirect_url, 1);
  691. }
  692. }