UserOpen.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. <?php
  2. namespace app\api\model\user;
  3. use app\api\model\plus\agent\Referee as RefereeModel;
  4. use app\api\model\plus\invitationgift\Partake;
  5. use think\facade\Cache;
  6. use app\common\exception\BaseException;
  7. use app\common\model\user\User as UserModel;
  8. use app\common\model\user\Sms as SmsModel;
  9. use app\common\model\user\Grade as GradeModel;
  10. use think\facade\Db;
  11. /**
  12. * 公众号用户模型类
  13. */
  14. class UserOpen extends UserModel
  15. {
  16. private $token;
  17. /**
  18. * 隐藏字段
  19. */
  20. protected $hidden = [
  21. 'open_id',
  22. 'is_delete',
  23. 'app_id',
  24. 'create_time',
  25. 'update_time'
  26. ];
  27. /**
  28. * 用户登录
  29. */
  30. public function login($userInfo, $referee_id)
  31. {
  32. // 自动注册用户
  33. $user_id = $this->register($userInfo, $referee_id);
  34. // 生成token (session3rd)
  35. $this->token = $this->token($userInfo['openid']);
  36. // 记录缓存, 7天
  37. Cache::set($this->token, $user_id, 86400 * 7);
  38. return $user_id;
  39. }
  40. /**
  41. * 获取token
  42. */
  43. public function getToken()
  44. {
  45. return $this->token;
  46. }
  47. /**
  48. * 生成用户认证的token
  49. */
  50. private function token($openid)
  51. {
  52. return md5($openid . 'token_salt');
  53. }
  54. /**
  55. * 自动注册用户
  56. */
  57. private function register($userInfo, $referee_id = 0)
  58. {
  59. $data = [];
  60. //通过unionid查询用户是否存在
  61. $user = null;
  62. if (isset($userInfo['unionid']) && !empty($userInfo['unionid'])) {
  63. $data['union_id'] = $userInfo['unionid'];
  64. $user = self::detailByUnionid($userInfo['unionid']);
  65. }
  66. // 查询用户是否已存在
  67. if (!$user) {
  68. $user = self::detail(['appopen_id' => $userInfo['openid']]);
  69. }
  70. if ($user) {
  71. $model = $user;
  72. // 只修改union_id
  73. if (isset($data['union_id'])) {
  74. $data = [
  75. 'union_id' => $data['union_id'],
  76. ];
  77. }else{
  78. return $user['user_id'];
  79. }
  80. } else {
  81. $model = $this;
  82. $data['referee_id'] = $referee_id;
  83. $data['reg_source'] = 'app';
  84. //默认等级
  85. $data['grade_id'] = GradeModel::getDefaultGradeId();
  86. }
  87. $data['appopen_id'] = $userInfo['openid'];
  88. // 用户昵称
  89. if (!$user) {
  90. $data['nickName'] = preg_replace('/[\xf0-\xf7].{3}/', '', $userInfo['nickname']);
  91. }
  92. $data['avatarUrl'] = $userInfo['headimgurl'];
  93. $data['gender'] = $userInfo['sex'];
  94. $data['province'] = $userInfo['province'];
  95. $data['country'] = $userInfo['country'];
  96. $data['city'] = $userInfo['city'];
  97. $data['reg_source'] = 'app';
  98. try {
  99. $this->startTrans();
  100. // 保存/更新用户记录
  101. if (!$model->save(array_merge($data, [
  102. 'app_id' => self::$app_id
  103. ]))
  104. ) {
  105. throw new BaseException(['msg' => '用户注册失败']);
  106. }
  107. if (!$user && $referee_id > 0) {
  108. // 记录推荐人关系,
  109. RefereeModel::createRelation($model['user_id'], $referee_id);
  110. //更新用户邀请数量
  111. (new UserModel())->where('user_id', '=', $referee_id)->inc('total_invite')->update();
  112. }
  113. $this->commit();
  114. } catch (\Exception $e) {
  115. $this->rollback();
  116. throw new BaseException(['msg' => $e->getMessage()]);
  117. }
  118. return $model['user_id'];
  119. }
  120. /**
  121. * 手机号密码用户登录
  122. */
  123. public function phoneLogin($data)
  124. {
  125. $where = [
  126. ['user_no','=',$data['mobile']],
  127. ['is_delete','=',0],
  128. ];
  129. $user = $this->where($where)->order('user_id desc')->find();
  130. if (empty($user)) {
  131. $this->error = '登录账号错误';
  132. return false;
  133. }
  134. if ($user['password'] != md5($data['password'])) {
  135. $this->error = '登陆密码错误';
  136. return false;
  137. }
  138. if (!empty($data['openid'])) {
  139. $weixin = [
  140. // 'nickName' => authcode($data['nickName'], 'DECODE'),
  141. // 'avatarUrl' => authcode($data['avatarUrl'], 'DECODE'),
  142. 'mpopen_id' => authcode($data['openid'], 'DECODE'),
  143. ];
  144. // $mpopen_id = authcode($data['openid'], 'DECODE'),
  145. if ($weixin['mpopen_id'] != $user['mpopen_id']) {
  146. if ($this->where('user_id',$user['user_id'])->update(['mpopen_id'=>$weixin['mpopen_id']])) {
  147. $ceshi = [
  148. 'test' => json_encode($weixin,JSON_UNESCAPED_UNICODE),
  149. 'name' => '正确',
  150. 'time' => time(),
  151. ];
  152. Db::name('user_ceshi')->insertGetId($ceshi);
  153. // 生成token (session3rd)
  154. $this->token = $this->token($user['user_no']);
  155. // 记录缓存, 30天
  156. Cache::tag('cache')->set($this->token, $user['user_id'], 86400 * 30);
  157. return $user['user_id'];
  158. }else{
  159. $ceshi = [
  160. 'test' => json_encode($weixin,JSON_UNESCAPED_UNICODE),
  161. 'name' => '微信错误日志',
  162. 'time' => time(),
  163. ];
  164. Db::name('user_ceshi')->insertGetId($ceshi);
  165. $this->error = '会员绑定微信信息失败';
  166. return false;
  167. }
  168. }else{
  169. // 生成token (session3rd)
  170. $this->token = $this->token($user['user_no']);
  171. // 记录缓存, 30天
  172. Cache::tag('cache')->set($this->token, $user['user_id'], 86400 * 30);
  173. return $user['user_id'];
  174. }
  175. }else{
  176. // 生成token (session3rd)
  177. $this->token = $this->token($user['user_no']);
  178. // 记录缓存, 30天
  179. Cache::tag('cache')->set($this->token, $user['user_id'], 86400 * 30);
  180. return $user['user_id'];
  181. }
  182. }
  183. /**
  184. * 手机号验证码登录
  185. */
  186. public function smslogin($data)
  187. {
  188. $where = [
  189. [ 'user_no','=',$data['mobile']],
  190. ['is_delete','=',0],
  191. ];
  192. $user = $this->where($where)->order('user_id desc')->find();
  193. if (empty($user)) {
  194. $this->error = '登录账号错误';
  195. return false;
  196. }
  197. if (empty($user['mobile'])) {
  198. $this->error = '您的账号未绑定手机号';
  199. return false;
  200. }
  201. $vall = [
  202. 'mobile' => $user['mobile'],
  203. 'code' => $data['code'],
  204. ];
  205. if (!$this->check($vall)) {
  206. return false;
  207. }
  208. if (!empty($data['openid'])) {
  209. $weixin = [
  210. // 'nickName' => authcode($data['nickName'], 'DECODE'),
  211. // 'avatarUrl' => authcode($data['avatarUrl'], 'DECODE'),
  212. 'mpopen_id' => authcode($data['openid'], 'DECODE'),
  213. ];
  214. if ($weixin['mpopen_id'] != $user['mpopen_id']) {
  215. if ($this->where('user_id',$user['user_id'])->update(['mpopen_id'=> $weixin['mpopen_id']])) {
  216. $ceshi = [
  217. 'test' => json_encode($weixin,JSON_UNESCAPED_UNICODE),
  218. 'name' => '正确',
  219. 'time' => time(),
  220. ];
  221. Db::name('user_ceshi')->insertGetId($ceshi);
  222. // 生成token (session3rd)
  223. $this->token = $this->token($user['user_no']);
  224. // 记录缓存, 30天
  225. Cache::tag('cache')->set($this->token, $user['user_id'], 86400 * 30);
  226. return $user['user_id'];
  227. }else{
  228. $ceshi = [
  229. 'test' => json_encode($weixin,JSON_UNESCAPED_UNICODE),
  230. 'name' => '微信错误日志',
  231. 'time' => time(),
  232. ];
  233. Db::name('user_ceshi')->insertGetId($ceshi);
  234. $this->error = '会员绑定微信信息失败';
  235. return false;
  236. }
  237. }else{
  238. // 生成token (session3rd)
  239. $this->token = $this->token($user['user_no']);
  240. // 记录缓存, 30天
  241. Cache::tag('cache')->set($this->token, $user['user_id'], 86400 * 30);
  242. return $user['user_id'];
  243. }
  244. }else{
  245. // 生成token (session3rd)
  246. $this->token = $this->token($user['user_no']);
  247. // 记录缓存, 30天
  248. Cache::tag('cache')->set($this->token, $user['user_id'], 86400 * 30);
  249. return $user['user_id'];
  250. }
  251. }
  252. /*
  253. *重置密码
  254. */
  255. public function resetpassword($data)
  256. {
  257. $where = [[ 'user_no','=',$data['mobile']]];
  258. $user = $this->where($where)->order('user_id desc')->find();
  259. if (empty($user)) {
  260. $this->error = '登录账号错误';
  261. return false;
  262. }
  263. if ($user['is_delete'] == 1) {
  264. $this->error = '手机号被禁止或删除,请联系客服';
  265. return false;
  266. }
  267. if (empty($user['mobile'])) {
  268. $this->error = '您的账号未绑定手机号';
  269. return false;
  270. }
  271. $vall = [
  272. 'mobile' => $user['mobile'],
  273. 'code' => $data['code'],
  274. ];
  275. if (!$this->check($vall)) {
  276. return false;
  277. }
  278. if (md5($data['password']) == $user['password']) {
  279. $this->error = '登陆密码与原密码相同';
  280. return false;
  281. }
  282. return $this->where('user_id', $user['user_id'])->update([
  283. 'password' => md5($data['password'])
  284. ]);
  285. }
  286. /*
  287. *手机号注册
  288. */
  289. public function phoneRegister($data)
  290. {
  291. if (!$this->check($data)) {
  292. return false;
  293. }
  294. $user = $this->where('user_no',$data['user_no'])->find();
  295. if (empty($user)) {
  296. $vall = [
  297. 'mobile' => $data['mobile'],
  298. 'user_no' => $data['user_no']??'',
  299. 'reg_source' => isset($data['reg_source'])?$data['reg_source']:'app',
  300. 'grade_id' => GradeModel::getDefaultGradeId(),
  301. 'app_id' => self::$app_id,
  302. 'password' => md5($data['password'])
  303. ];
  304. if (empty($data['nickName'])) {
  305. $vall['nickName'] = $data['user_no']??'';
  306. }
  307. if (!empty($data['openid'])) {
  308. // $vall['avatarUrl'] = authcode($data['avatarUrl'], 'DECODE');
  309. // $vall['nickName'] = authcode($data['nickName'], 'DECODE');
  310. $vall['mpopen_id'] = authcode($data['openid'], 'DECODE');
  311. }
  312. $this->save($vall);
  313. if ($data['referee_id'] > 0) {
  314. // 记录推荐人关系
  315. RefereeModel::createRelation($this['user_id'], $data['referee_id']);
  316. //更新用户邀请数量
  317. (new UserModel())->setIncInvite($data['referee_id']);
  318. //邀请好友送好礼
  319. $data['invitation_id'] > 0 && (new Partake())->addPartake($data['invitation_id'], $data['referee_id'], $this['user_id']);
  320. }
  321. return true;
  322. } else {
  323. $this->error = '会员号已存在';
  324. return false;
  325. }
  326. }
  327. /**
  328. * 验证
  329. */
  330. private function check($data)
  331. {
  332. //判断验证码是否过期、是否正确
  333. $sms_model = new SmsModel();
  334. $sms_record_list = $sms_model
  335. ->where('mobile', '=', $data['mobile'])
  336. ->order(['create_time' => 'desc'])
  337. ->limit(1)->select();
  338. if (count($sms_record_list) == 0) {
  339. $this->error = '未查到短信发送记录';
  340. return false;
  341. }
  342. $sms_model = $sms_record_list[0];
  343. if ((time() - strtotime($sms_model['create_time'])) / 60 > 30) {
  344. $this->error = '短信验证码超时';
  345. return false;
  346. }
  347. if ($sms_model['code'] != $data['code']) {
  348. $this->error = '验证码不正确';
  349. return false;
  350. }
  351. return true;
  352. }
  353. /**
  354. * 手机号验证码登录
  355. */
  356. public function smsloginWx($data)
  357. {
  358. $user = $this->where('user_no', $data['mobile'])->find();
  359. if (empty($user)) {
  360. $vall = [
  361. 'mobile' => $data['mobile'],
  362. 'user_no' => $data['mobile'],
  363. 'reg_source' => 'wx',
  364. 'grade_id' => GradeModel::getDefaultGradeId(),
  365. 'app_id' => self::$app_id,
  366. 'password' => md5('123456'),
  367. 'nickName' => $data['mobile'],
  368. 'openid' => $data['openid'], // authcode($data['openid'], 'DECODE'),
  369. ];
  370. if (!$this->save($vall)) {
  371. $this->error = '登录失败';
  372. return false;
  373. }
  374. $user = $this->where('user_no', $data['user_no'])->find();
  375. $data['mobile'] = $user['mobile'];
  376. }
  377. if (!$this->check($data)) {
  378. return false;
  379. }
  380. $info = [
  381. 'open_id' => $data['openid'],
  382. 'reg_source' => 'wx',
  383. ];
  384. $this->where('user_id', $user['user_id'])->update($info);
  385. // 生成token (session3rd)
  386. $this->token = $this->token($user['user_no']);
  387. // 记录缓存, 30天
  388. Cache::tag('cache')->set($this->token, $user['user_id'], 86400 * 30);
  389. return $user['user_id'];
  390. }
  391. }