Customer.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  1. <?php
  2. /*
  3. * FecShop file.
  4. *
  5. * @link http://www.fecshop.com/
  6. * @copyright Copyright (c) 2016 FecShop Software LLC
  7. * @license http://www.fecshop.com/license/
  8. */
  9. namespace fecshop\services;
  10. use Yii;
  11. use yii\web\IdentityInterface;
  12. /**
  13. * Customer service.
  14. * @property \fecshop\services\Customer\Address $address
  15. * @property \fecshop\services\customer\Newsletter $newsletter
  16. * @property \fecshop\services\customer\Affiliate $affiliate
  17. * @property \fecshop\services\customer\Coupon $coupon
  18. * @property \fecshop\services\customer\DropShip $dropship
  19. * @property \fecshop\services\customer\Favorite $favorite
  20. * @property \fecshop\services\customer\Message $message
  21. * @property \fecshop\services\customer\Order $order
  22. * @property \fecshop\services\customer\Point $point
  23. * @property \fecshop\services\customer\Review $review
  24. * @property \fecshop\services\customer\Wholesale $wholesale
  25. * @property \fecshop\services\customer\Facebook $facebook
  26. * @property \fecshop\services\customer\Google $google
  27. *
  28. * @method getPrimaryKey() see [[\fecshop\services\Customer::actionGetPrimaryKey()]]actionGetByPrimaryKey
  29. * @method \fecshop\models\mysqldb\Customer|null getByPrimarykey($val) see [[\fecshop\services\Customer::actionGetByPrimaryKey()]]
  30. * @method \fecshop\models\mysqldb\Customer|null getUserIdentityByEmail($email) see [[\fecshop\services\Customer::actionGetUserIdentityByEmail()]]
  31. * @method loginByAccessToken($type = null) see [[\fecshop\services\Customer::actionLoginByAccessToken()]]
  32. * @author Terry Zhao <2358269014@qq.com>
  33. * @since 1.0
  34. */
  35. class Customer extends Service
  36. {
  37. const USER_LOGIN_SUCCESS_REDIRECT_URL_KEY = 'usr_login_success_redirect_url';
  38. /**
  39. * @var array
  40. *
  41. * example:
  42. * ```php
  43. * [
  44. * 'customer_register' => [
  45. * 'min_name_length' => 1,
  46. * ]
  47. * ]
  48. * ```
  49. */
  50. public $customer_register;
  51. protected $_customerModelName = '\fecshop\models\mysqldb\Customer';
  52. /**
  53. * @var \fecshop\models\mysqldb\Customer
  54. */
  55. protected $_customerModel;
  56. protected $_customerLoginModelName = '\fecshop\models\mysqldb\customer\CustomerLogin';
  57. /**
  58. * @var \fecshop\models\mysqldb\customer\CustomerLogin
  59. */
  60. protected $_customerLoginModel;
  61. protected $_customerRegisterModelName = '\fecshop\models\mysqldb\customer\CustomerRegister';
  62. /**
  63. * @var \fecshop\models\mysqldb\customer\CustomerRegister
  64. */
  65. protected $_customerRegisterModel;
  66. public function init()
  67. {
  68. // 对于 api端口,设置Yii::$app->user->enableSession = false;
  69. // 下面的代码注释掉,对于使用到user组件的,在相应的模块部分设置 Yii::$app->user->enableSession = false;
  70. // if(Yii::$service->store->isApiStore()){
  71. // Yii::$app->user->enableSession = false;
  72. //}
  73. parent::init();
  74. list($this->_customerModelName, $this->_customerModel) = Yii::mapGet($this->_customerModelName);
  75. list($this->_customerLoginModelName, $this->_customerLoginModel) = Yii::mapGet($this->_customerLoginModelName);
  76. list($this->_customerRegisterModelName, $this->_customerRegisterModel) = Yii::mapGet($this->_customerRegisterModelName);
  77. }
  78. /**
  79. * 注册用户名字的最小长度.
  80. * @return int|null
  81. */
  82. protected function actionGetRegisterNameMinLength()
  83. {
  84. if (isset($this->customer_register['min_name_length'])) {
  85. return $this->customer_register['min_name_length'];
  86. }
  87. return null;
  88. }
  89. /**
  90. * 注册用户名字的最大长度.
  91. * @return int|null
  92. */
  93. protected function actionGetRegisterNameMaxLength()
  94. {
  95. if (isset($this->customer_register['max_name_length'])) {
  96. return $this->customer_register['max_name_length'];
  97. }
  98. return null;
  99. }
  100. /**
  101. * 注册用户密码的最小长度.
  102. * @return int|null
  103. */
  104. protected function actionGetRegisterPassMinLength()
  105. {
  106. if (isset($this->customer_register['min_pass_length'])) {
  107. return $this->customer_register['min_pass_length'];
  108. }
  109. return null;
  110. }
  111. /**
  112. * 注册用户密码的最大长度.
  113. * @return int|null
  114. */
  115. protected function actionGetRegisterPassMaxLength()
  116. {
  117. if (isset($this->customer_register['max_pass_length'])) {
  118. return $this->customer_register['max_pass_length'];
  119. }
  120. return null;
  121. }
  122. /**
  123. * @param array $data
  124. *
  125. * example:
  126. *
  127. * ```php
  128. * $data = ['email' => 'user@example.com', 'password' => 'your password'];
  129. * $loginStatus = \Yii::$service->customer->login($data);
  130. * ```
  131. *
  132. * @return bool
  133. */
  134. protected function actionLogin($data)
  135. {
  136. $model = $this->_customerLoginModel;
  137. $model->password = $data['password'];
  138. $model->email = $data['email'];
  139. $loginStatus = $model->login();
  140. $errors = $model->errors;
  141. if (empty($errors)) {
  142. // 合并购物车数据
  143. Yii::$service->cart->mergeCartAfterUserLogin();
  144. // 发送登录信息到trace系统
  145. Yii::$service->page->trace->sendTraceLoginInfoByApi($data['email']);
  146. } else {
  147. Yii::$service->helper->errors->addByModelErrors($errors);
  148. }
  149. return $loginStatus;
  150. }
  151. /**
  152. * Register customer account.
  153. * @param array $param
  154. * 数据格式如下:
  155. * ```php
  156. * [
  157. * 'email',
  158. * 'firstname',
  159. * 'lastname',
  160. * 'password'
  161. * ]
  162. * ```
  163. * @return bool whether the customer is registered ok
  164. */
  165. protected function actionRegister($param)
  166. {
  167. $model = $this->_customerRegisterModel;
  168. $model->attributes = $param;
  169. if ($model->validate()) {
  170. $model->created_at = time();
  171. $model->updated_at = time();
  172. if (Yii::$service->email->customer->registerAccountIsNeedEnableByEmail) {
  173. $model->generateRegisterEnableToken();
  174. $model->status = $model::STATUS_REGISTER_DISABLE;
  175. }
  176. $saveStatus = $model->save();
  177. if (!$saveStatus) {
  178. $errors = $model->errors;
  179. Yii::$service->helper->errors->addByModelErrors($errors);
  180. return false;
  181. }
  182. // 如果用户勾选了订阅邮件,那么添加到订阅
  183. if ($param['is_subscribed'] == 1) {
  184. Yii::$service->customer->newsletter->subscribe($param['email'], true);
  185. }
  186. // 发送注册信息到trace系统
  187. Yii::$service->page->trace->sendTraceRegisterInfoByApi($model->email);
  188. return true;
  189. } else {
  190. $errors = $model->errors;
  191. Yii::$service->helper->errors->addByModelErrors($errors);
  192. return false;
  193. }
  194. }
  195. /**
  196. * Check whether the given email is registered
  197. * @param string $email
  198. * @return bool whether the given email is registered
  199. */
  200. protected function actionIsRegistered($email)
  201. {
  202. $customer = $this->_customerModel->findOne(['email' => $email]);
  203. if ($customer['email']) {
  204. return true;
  205. } else {
  206. return false;
  207. }
  208. }
  209. /**
  210. * Save the customer info.
  211. * @param array $param
  212. * 数据格式如下:
  213. * ['email' => 'xxx', 'password' => 'xxxx','firstname' => 'xxx','lastname' => 'xxx']
  214. * @return bool
  215. */
  216. protected function actionSave($param)
  217. {
  218. $primaryKey = $this->getPrimaryKey();
  219. $primaryVal = isset($param[$primaryKey]) ? $param[$primaryKey] : '';
  220. if ($primaryVal) {
  221. $model = $this->_customerRegisterModel;
  222. $model->attributes = $param;
  223. if (!$model->validate()) {
  224. $errors = $model->errors;
  225. Yii::$service->helper->errors->addByModelErrors($errors);
  226. return false;
  227. }
  228. $model = $this->getByPrimaryKey($primaryVal);
  229. if ($model[$primaryKey]) {
  230. unset($param[$primaryKey]);
  231. $param['updated_at'] = time();
  232. $password = isset($param['password']) ? $param['password'] : '';
  233. if ($password) {
  234. $model->setPassword($password);
  235. unset($param['password']);
  236. }
  237. $saveStatus = Yii::$service->helper->ar->save($model, $param);
  238. if ($saveStatus) {
  239. return true;
  240. } else {
  241. $errors = $model->errors;
  242. Yii::$service->helper->errors->addByModelErrors($errors);
  243. return false;
  244. }
  245. }
  246. } else {
  247. if ($this->register($param)) {
  248. return true;
  249. }
  250. }
  251. return false;
  252. }
  253. /**
  254. * @param int $customerId
  255. * @deprecated 该方法已废弃
  256. */
  257. protected function actionViewInfo($customerId)
  258. {
  259. }
  260. /**
  261. * Change customer's password
  262. * @param string $password
  263. * @param int|string|IdentityInterface $identity this can be customer id, customer email, or customer
  264. * @return bool
  265. * @throws \InvalidArgumentException if $identity is invalid
  266. */
  267. protected function actionChangePassword($password, $identity)
  268. {
  269. if (is_int($identity)) {
  270. $customer_id = $identity;
  271. $customerModel = $this->_customerModel->findIdentity($customer_id);
  272. } elseif (is_string($identity)) {
  273. $email = $identity;
  274. $customerModel = $this->_customerModel->findByEmail($email);
  275. } elseif (is_object($identity) && $identity instanceof IdentityInterface) {
  276. $customerModel = $identity;
  277. } else {
  278. throw new \InvalidArgumentException('$identity can only be customer id, customer email, or customer');
  279. }
  280. if ($customerModel['email']) {
  281. $customerModel->updated_at = time();
  282. $customerModel->setPassword($password);
  283. $customerModel->save();
  284. return true;
  285. } else {
  286. return false;
  287. }
  288. }
  289. /**
  290. * 得到category model的全名.
  291. */
  292. protected function actionGetModelName()
  293. {
  294. $model = new $this->_customerModelName();
  295. return get_class($model);
  296. }
  297. /**
  298. * @param int $val
  299. * @return \fecshop\models\mysqldb\Customer
  300. */
  301. protected function actionGetByPrimaryKey($val)
  302. {
  303. $one = $this->_customerModel->findOne($val);
  304. $primaryKey = $this->getPrimaryKey();
  305. if ($one[$primaryKey]) {
  306. return $one;
  307. } else {
  308. return new $this->_customerModelName();
  309. }
  310. }
  311. /**
  312. * @param $password|string
  313. * @param $customerId|int or String or Object
  314. * change customer password.
  315. * 更改密码,然后,清空token
  316. */
  317. protected function actionChangePasswordAndClearToken($password, $identity)
  318. {
  319. if (is_int($identity)) {
  320. $customer_id = $identity;
  321. $customerModel = $this->_customerModel->findIdentity($customer_id);
  322. } elseif (is_string($identity)) {
  323. $email = $identity;
  324. $customerModel = $this->_customerModel->findByEmail($email);
  325. } elseif (is_object($identity)) {
  326. $customerModel = $identity;
  327. } else {
  328. Yii::$service->helper->errors->add('identity is not right');
  329. return null;
  330. }
  331. $customerModel->setPassword($password);
  332. $customerModel->removePasswordResetToken();
  333. $customerModel->updated_at = time();
  334. $customerModel->save();
  335. return true;
  336. }
  337. /**
  338. * @param $password|string
  339. * @param $customerId|int or String or Object
  340. * change customer password.
  341. * 更改密码,然后,清空token
  342. */
  343. protected function actionRegisterEnableByTokenAndClearToken($token)
  344. {
  345. $identity = $this->findByRegisterEnableToken($token);
  346. if (!$identity['id']) {
  347. Yii::$service->helper->errors->add('token is invalid');
  348. return false;
  349. }
  350. $identity->status = $identity::STATUS_ACTIVE;
  351. $identity->updated_at = time();
  352. return $identity->save();
  353. }
  354. /**
  355. * @deprecated 已废弃
  356. */
  357. protected function actionChangeNameAndPassword($data)
  358. {
  359. }
  360. /**
  361. * @deprecated 已废弃
  362. */
  363. protected function actionGetCurrentAccount()
  364. {
  365. }
  366. /**
  367. * Get customer by email address
  368. * @param string $email
  369. * @return \fecshop\models\mysqldb\Customer|null return customer or null if not found
  370. */
  371. protected function actionGetUserIdentityByEmail($email)
  372. {
  373. $one = $this->_customerModel->findByEmail($email);
  374. if ($one['email']) {
  375. return $one;
  376. } else {
  377. return null;
  378. }
  379. }
  380. // 得到可用的账户
  381. protected function actionGetAvailableUserIdentityByEmail($email)
  382. {
  383. $one = $this->_customerModel->findAvailableByEmail($email);
  384. if ($one['email']) {
  385. return $one;
  386. } else {
  387. return null;
  388. }
  389. }
  390. /**
  391. * 生成resetToken,用来找回密码
  392. * @param string|IdentityInterface $identify identity can be customer email, or customer object
  393. * @return string|null 生成的resetToken,如果生成失败返回false
  394. */
  395. protected function actionGeneratePasswordResetToken($identify)
  396. {
  397. if (is_string($identify)) {
  398. $email = $identify;
  399. $one = $this->getUserIdentityByEmail($email);
  400. } else {
  401. $one = $identify;
  402. }
  403. if ($one) {
  404. $one->generatePasswordResetToken();
  405. $one->updated_at = time();
  406. $one->save();
  407. return $one->password_reset_token;
  408. }
  409. return false;
  410. }
  411. /**
  412. * 生成resetToken,用来找回密码
  413. * @param string|IdentityInterface $identify identity can be customer email, or customer object
  414. * @return string|null 生成的resetToken,如果生成失败返回false
  415. */
  416. protected function actionGenerateRegisterEnableToken($identify)
  417. {
  418. if (is_string($identify)) {
  419. $email = $identify;
  420. $one = $this->actionGetAvailableUserIdentityByEmail($email);
  421. } else {
  422. $one = $identify;
  423. }
  424. if ($one) {
  425. $one->generateRegisterEnableToken();
  426. $one->updated_at = time();
  427. $one->save();
  428. return $one->register_enable_token;
  429. }
  430. return false;
  431. }
  432. /**
  433. * @param string $token the password reset token
  434. * 通过PasswordResetToken 得到user.
  435. * @return \fecshop\models\mysqldb\Customer|null returns customer or null if not found
  436. */
  437. protected function actionFindByPasswordResetToken($token)
  438. {
  439. return $this->_customerModel->findByPasswordResetToken($token);
  440. }
  441. protected function actionFindByRegisterEnableToken($token)
  442. {
  443. return $this->_customerModel->findByRegisterEnableToken($token);
  444. }
  445. /**
  446. * @param $url|string
  447. * **注意**:该方法不能在接口类型里面使用
  448. * 在一些功能中,需要用户进行登录操作,等用户操作成功后,应该跳转到相应的页面中,这里通过session存储需要跳转到的url。
  449. * 某些页面 , 譬如评论页面,需要用户登录后才能进行登录操作,那么可以通过这个方法把url set 进去,登录成功
  450. * 后,页面不会跳转到账户中心,而是需要操作的页面中。
  451. */
  452. protected function actionSetLoginSuccessRedirectUrl($url)
  453. {
  454. return Yii::$service->session->set($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY, $url);
  455. }
  456. /**
  457. * @param $url|string
  458. * **注意**:该方法不能在接口类型里面使用
  459. * **注意**:该方法不能在接口类型里面使用
  460. * 在一些功能中,需要用户进行登录操作,等用户操作成功后,应该跳转到相应的页面中,这里通过session得到需要跳转到的url。
  461. */
  462. protected function actionGetLoginSuccessRedirectUrl()
  463. {
  464. $url = Yii::$service->session->get($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY);
  465. return $url ? $url : '';
  466. }
  467. /**
  468. * @param $urlKey | String
  469. * **注意**:该方法不能在接口类型里面使用
  470. * 登录用户成功后,进行url跳转。
  471. */
  472. protected function actionLoginSuccessRedirect($urlKey = '')
  473. {
  474. $url = $this->getLoginSuccessRedirectUrl();
  475. if ($url) {
  476. // 这个优先级最高
  477. // 在跳转之前,去掉这个session存储的值。跳转后,这个值必须失效。
  478. Yii::$service->session->remove($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY);
  479. //echo Yii::$service->session->get($this::USER_LOGIN_SUCCESS_REDIRECT_URL_KEY);
  480. //exit;
  481. return Yii::$service->url->redirect($url);
  482. } elseif ($urlKey) {
  483. return Yii::$service->url->redirectByUrlKey($urlKey);
  484. } else {
  485. return Yii::$service->url->redirectHome();
  486. }
  487. }
  488. /**
  489. * 得到status为删除状态的值
  490. */
  491. protected function actionGetStatusDeleted()
  492. {
  493. $model = $this->_customerModel;
  494. return $model::STATUS_DELETED;
  495. }
  496. /**
  497. * 得到status为激活状态的值
  498. */
  499. protected function actionGetStatusActive()
  500. {
  501. $model = $this->_customerModel;
  502. return $model::STATUS_ACTIVE;
  503. }
  504. /**
  505. * Get primary key field name.
  506. */
  507. protected function actionGetPrimaryKey()
  508. {
  509. return 'id';
  510. }
  511. /**
  512. * Get customer collection by filter array
  513. * @param array $filter
  514. * filter example:
  515. * [
  516. * 'numPerPage' => 20,
  517. * 'pageNum' => 1,
  518. * 'orderBy' => ['_id' => SORT_DESC, 'sku' => SORT_ASC ],
  519. * 'where' => [
  520. * ['>','price','1'],
  521. * ['<','price','10'],
  522. * ['sku' => 'uk10001'],
  523. * ],
  524. * 'asArray' => true,
  525. * ]
  526. * @return array
  527. */
  528. protected function actionColl($filter = [])
  529. {
  530. $query = $this->_customerModel->find();
  531. $query = Yii::$service->helper->ar->getCollByFilter($query, $filter);
  532. return [
  533. 'coll' => $query->all(),
  534. 'count'=> $query->limit(null)->offset(null)->count(),
  535. ];
  536. }
  537. /**
  538. * Remove customer by primary key value
  539. * @param int $id the primary key value
  540. * @return bool
  541. * @throws
  542. */
  543. public function remove($id)
  544. {
  545. if (!$id) {
  546. Yii::$service->helper->errors->add('remove id is empty');
  547. return false;
  548. }
  549. $model = $this->_customerModel->findOne($id);
  550. if (isset($model[$this->getPrimaryKey()]) && !empty($model[$this->getPrimaryKey()])) {
  551. $model->delete();
  552. } else {
  553. Yii::$service->helper->errors->add("customer Remove Errors:ID:$id is not exist.");
  554. return false;
  555. }
  556. return true;
  557. }
  558. /**
  559. * @param $user_ids | Array , 子项为Int类型
  560. * @return Array ,数据格式为:
  561. * ['id' => 'email']
  562. * 得到customer id 和customer email的对应数组。
  563. */
  564. protected function actionGetEmailByIds($user_ids)
  565. {
  566. $arr = [];
  567. if (is_array($user_ids) && !empty($user_ids)) {
  568. $data = $this->_customerModel->find()->where([
  569. 'in', 'id', $user_ids,
  570. ])->all();
  571. if (is_array($data) && !empty($data)) {
  572. foreach ($data as $one) {
  573. $arr[$one['id']] = $one['email'];
  574. }
  575. }
  576. }
  577. return $arr;
  578. }
  579. //2. 创建第三方用户的账户,密码自动生成
  580. /**
  581. * @param $user | Array ,example:
  582. * ['first_name' => $first_name,'last_name' => $last_name,'email' => $email,]
  583. * @param $type | String 代表第三方登录的名称,譬如google,facebook
  584. * @return bool
  585. * 如果用户emai存在,则直接登录,成功后返回true
  586. * 如果用户不存在,则注册用户,然后直接登录,成功后返回true
  587. */
  588. protected function actionRegisterThirdPartyAccountAndLogin($user, $type)
  589. {
  590. // 查看邮箱是否存在
  591. $email = $user['email'];
  592. $customer_one = Yii::$service->customer->getUserIdentityByEmail($email);
  593. if ($customer_one) {
  594. $loginStatus = \Yii::$app->user->login($customer_one);
  595. if ($loginStatus) {
  596. $customer_one->generateAccessToken();
  597. $customer_one->access_token_created_at = time();
  598. $customer_one->save();
  599. return $this->setHeaderAccessToken($customer_one->access_token);
  600. }
  601. // 不存在,注册。
  602. } else {
  603. if (!(isset($user['password']) && $user['password'])) {
  604. $user['password'] = $this->getRandomPassword();
  605. }
  606. $registerData = [
  607. 'email' => $email,
  608. 'firstname' => $user['first_name'],
  609. 'lastname' => $user['last_name'],
  610. 'password' => $user['password'],
  611. 'type' => $type,
  612. ];
  613. $registerStatus = Yii::$service->customer->register($registerData);
  614. if ($registerStatus) {
  615. return Yii::$service->customer->loginAndGetAccessToken($registerData['email'], $registerData['password']);
  616. }
  617. }
  618. return false;
  619. }
  620. /**
  621. * 生成账户密码
  622. */
  623. protected function getRandomPassword()
  624. {
  625. srand((float) microtime() * 1000000); //create a random number feed.
  626. $ychar = '0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z';
  627. $list = explode(',', $ychar);
  628. for ($i = 0; $i < 6; $i++) {
  629. $randnum = rand(0, 35); // 10+26;
  630. $authnum .= $list[$randnum];
  631. }
  632. //return $authnum;
  633. return $authnum;
  634. }
  635. /**
  636. * @param $identity | Object, customer model
  637. * #param $duration
  638. * 通过identity 进行登陆账户
  639. * 通过
  640. */
  641. public function loginByIdentityAndGetAccessToken($identity, $wx_session_key='', $duration = 0)
  642. {
  643. $header = Yii::$app->request->getHeaders();
  644. if (isset($header['access-token']) && $header['access-token']) {
  645. $accessToken = $header['access-token'];
  646. }
  647. // 如果request header中有access-token,则查看这个 access-token 是否有效
  648. if ($accessToken) {
  649. $access_token_identity = Yii::$app->user->loginByAccessToken($accessToken);
  650. if ($access_token_identity !== null) {
  651. $access_token_created_at = $access_token_identity->access_token_created_at;
  652. $timeout = Yii::$service->session->timeout;
  653. if ($access_token_created_at + $timeout > time()) {
  654. return $accessToken;
  655. }
  656. }
  657. }
  658. // 执行登陆
  659. if (!$duration) {
  660. if (Yii::$service->session->timeout) {
  661. $duration = Yii::$service->session->timeout;
  662. }
  663. }
  664. //var_dump($identity);exit;
  665. if (\Yii::$app->user->login($identity, $duration)) {
  666. $identity->generateAccessToken();
  667. $identity->access_token_created_at = time();
  668. $identity->wx_session_key = $wx_session_key;
  669. $identity->save();
  670. // 执行购物车合并等操作。
  671. Yii::$service->cart->mergeCartAfterUserLogin();
  672. $this->setHeaderAccessToken($identity->access_token);
  673. return $identity->access_token;
  674. }
  675. }
  676. /** AppServer 部分使用的函数
  677. * @param $email | String
  678. * @param $password | String
  679. * 无状态登录,通过email 和password进行登录
  680. * 登录成功后,合并购物车,返回accessToken
  681. * ** 该函数是未登录用户,通过参数进行登录需要执行的函数。
  682. */
  683. protected function actionLoginAndGetAccessToken($email, $password)
  684. {
  685. $header = Yii::$app->request->getHeaders();
  686. if (isset($header['access-token']) && $header['access-token']) {
  687. $accessToken = $header['access-token'];
  688. }
  689. // 如果request header中有access-token,则查看这个 access-token 是否有效
  690. if ($accessToken) {
  691. $identity = Yii::$app->user->loginByAccessToken($accessToken);
  692. if ($identity !== null) {
  693. $access_token_created_at = $identity->access_token_created_at;
  694. $timeout = Yii::$service->session->timeout;
  695. if ($access_token_created_at + $timeout > time()) {
  696. return $accessToken;
  697. }
  698. }
  699. }
  700. // 如果上面access-token不存在
  701. $data = [
  702. 'email' => $email,
  703. 'password' => $password,
  704. ];
  705. if (Yii::$service->customer->login($data)) {
  706. $identity = Yii::$app->user->identity;
  707. $identity->generateAccessToken();
  708. $identity->access_token_created_at = time();
  709. $identity->save();
  710. // 执行购物车合并等操作。
  711. Yii::$service->cart->mergeCartAfterUserLogin();
  712. $this->setHeaderAccessToken($identity->access_token);
  713. return $identity->access_token;
  714. }
  715. }
  716. /**
  717. * Logs in a user by the given access token.
  718. * Token is passed through headers. So you can get it from the key 'access-token'.
  719. * @param $type
  720. * @return IdentityInterface|null the identity associated with the given access token. Null is returned if
  721. * the access token is invalid.
  722. * @see [[\yii\web\User::loginByAccessToken()]]
  723. */
  724. protected function actionLoginByAccessToken($type = null)
  725. {
  726. $header = Yii::$app->request->getHeaders();
  727. if (isset($header['access-token']) && $header['access-token']) {
  728. $accessToken = $header['access-token'];
  729. } else {
  730. return null;
  731. }
  732. /** @var \fecshop\models\mysqldb\Customer|null $identity */
  733. $identity = Yii::$app->user->loginByAccessToken($accessToken, $type);
  734. if ($identity !== null) {
  735. $access_token_created_at = $identity->access_token_created_at;
  736. $timeout = Yii::$service->session->timeout;
  737. // 如果时间没有过期,则返回 identity
  738. if ($access_token_created_at + $timeout > time()) {
  739. // 如果时间没有过期,但是快要过期了,在过$updateTimeLimit段时间就要过期,那么更新access_token_created_at。
  740. $updateTimeLimit = Yii::$service->session->updateTimeLimit;
  741. if ($access_token_created_at + $timeout <= (time() + $updateTimeLimit)) {
  742. $identity->access_token_created_at = time();
  743. $identity->save();
  744. }
  745. return $identity;
  746. } else {
  747. $this->logoutByAccessToken();
  748. return null;
  749. }
  750. }
  751. return null;
  752. }
  753. /**
  754. * @param $openid | string
  755. * 通过微信的openid 得到 user
  756. */
  757. protected function actionGetByWxOpenid($openid)
  758. {
  759. $one = $this->_customerModel->findOne(['wx_openid' => $openid]);
  760. $primaryKey = $this->getPrimaryKey();
  761. if ($one[$primaryKey]) {
  762. return $one;
  763. }
  764. return null;
  765. }
  766. /**
  767. * 通过accessToek的方式,进行登出从操作。
  768. */
  769. public function logoutByAccessToken()
  770. {
  771. $userComponent = Yii::$app->user;
  772. $identity = $userComponent->identity;
  773. if ($identity !== null) {
  774. if (!Yii::$app->user->isGuest) {
  775. $identity->access_token = null;
  776. $identity->access_token_created_at = null;
  777. $identity->save();
  778. }
  779. $userComponent->switchIdentity(null);
  780. // 刷新uuid
  781. Yii::$service->session->reflushUUID();
  782. }
  783. return $userComponent->getIsGuest();
  784. }
  785. protected function actionSetHeaderAccessToken($accessToken)
  786. {
  787. if ($accessToken) {
  788. Yii::$app->response->getHeaders()->set('access-token', $accessToken);
  789. return true;
  790. }
  791. }
  792. /**
  793. * @param $days | Int 天数
  794. * 得到最近X天的注册用户
  795. * 下面的数据是为了后台的customer 注册数统计
  796. */
  797. public function getPreMonthCustomer($days)
  798. {
  799. // 得到一个月前的时间戳
  800. $preMonthTime = strtotime("-$days days");
  801. $filter = [
  802. 'select' => ['created_at', 'email' ],
  803. 'numPerPage' => 10000000,
  804. 'pageNum' => 1,
  805. 'where' => [
  806. ['>=', 'created_at', $preMonthTime]
  807. ],
  808. 'asArray' => true,
  809. ];
  810. $data = $this->coll($filter);
  811. $coll = $data['coll'];
  812. $dateArr = Yii::$service->helper->format->getPreDayDateArr($days);
  813. $customerArr = $dateArr;
  814. if (is_array($coll) && !empty($coll)) {
  815. foreach ($coll as $order) {
  816. $created_at = $order['created_at'];
  817. $created_at_str = date("Y-m-d", $created_at);
  818. if (isset($customerArr[$created_at_str])) {
  819. $customerArr[$created_at_str] += 1;
  820. }
  821. }
  822. }
  823. return [
  824. '用户注册数' => $customerArr,
  825. ];
  826. }
  827. }