User.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. <?php
  2. namespace app\common\model;
  3. use app\admin\model\UserRelation;
  4. use fast\Random;
  5. use liuniu\BaseModel;
  6. use think\Db;
  7. use think\Model;
  8. use think\Request;
  9. /**
  10. * 会员模型
  11. */
  12. class User extends BaseModel
  13. {
  14. // 开启自动写入时间戳字段
  15. protected $autoWriteTimestamp = 'int';
  16. // 定义时间戳字段名
  17. protected $createTime = 'createtime';
  18. protected $updateTime = 'updatetime';
  19. // 追加属性
  20. protected $append = [
  21. 'url',
  22. ];
  23. /**
  24. * 获取个人URL
  25. * @param string $value
  26. * @param array $data
  27. * @return string
  28. */
  29. public function getUrlAttr($value, $data)
  30. {
  31. return "/u/" . $data['id'];
  32. }
  33. /**
  34. * 获取头像
  35. * @param string $value
  36. * @param array $data
  37. * @return string
  38. */
  39. public function getAvatarAttr($value, $data)
  40. {
  41. if (!$value) {
  42. //如果不需要启用首字母头像,请使用
  43. //$value = '/assets/img/avatar.png';
  44. $value = letter_avatar($data['nickname']);
  45. }
  46. return $value;
  47. }
  48. /**
  49. * 获取会员的组别
  50. */
  51. public function getGroupAttr($value, $data)
  52. {
  53. return UserGroup::get($data['group_id']);
  54. }
  55. /**
  56. * 获取验证字段数组值
  57. * @param string $value
  58. * @param array $data
  59. * @return object
  60. */
  61. public function getVerificationAttr($value, $data)
  62. {
  63. $value = array_filter((array)json_decode($value, true));
  64. $value = array_merge(['email' => 0, 'mobile' => 0], $value);
  65. return (object)$value;
  66. }
  67. /**
  68. * 设置验证字段
  69. * @param mixed $value
  70. * @return string
  71. */
  72. public function setVerificationAttr($value)
  73. {
  74. $value = is_object($value) || is_array($value) ? json_encode($value) : $value;
  75. return $value;
  76. }
  77. /**
  78. * 变更会员余额
  79. * @param int $money 余额
  80. * @param int $user_id 会员ID
  81. * @param string $memo 备注
  82. */
  83. public static function money($money, $user_id, $memo)
  84. {
  85. Db::startTrans();
  86. try {
  87. $user = self::lock(true)->find($user_id);
  88. if ($user && $money != 0) {
  89. $before = $user->money;
  90. //$after = $user->money + $money;
  91. $after = function_exists('bcadd') ? bcadd($user->money, $money, 2) : $user->money + $money;
  92. //更新会员信息
  93. $user->save(['money' => $after]);
  94. //写入日志
  95. MoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before' => $before, 'after' => $after, 'memo' => $memo]);
  96. }
  97. Db::commit();
  98. } catch (\Exception $e) {
  99. Db::rollback();
  100. }
  101. }
  102. /**
  103. * 变更会员积分
  104. * @param int $score 积分
  105. * @param int $user_id 会员ID
  106. * @param string $memo 备注
  107. */
  108. public static function score($score, $user_id, $memo)
  109. {
  110. Db::startTrans();
  111. try {
  112. $user = self::lock(true)->find($user_id);
  113. if ($user && $score != 0) {
  114. $before = $user->score;
  115. $after = $user->score + $score;
  116. $level = self::nextlevel($after);
  117. //更新会员信息
  118. $user->save(['score' => $after, 'level' => $level]);
  119. //写入日志
  120. ScoreLog::create(['user_id' => $user_id, 'score' => $score, 'before' => $before, 'after' => $after, 'memo' => $memo]);
  121. }
  122. Db::commit();
  123. } catch (\Exception $e) {
  124. Db::rollback();
  125. }
  126. }
  127. /**
  128. * 根据积分获取等级
  129. * @param int $score 积分
  130. * @return int
  131. */
  132. public static function nextlevel($score = 0)
  133. {
  134. $lv = array(1 => 0, 2 => 30, 3 => 100, 4 => 500, 5 => 1000, 6 => 2000, 7 => 3000, 8 => 5000, 9 => 8000, 10 => 10000);
  135. $level = 1;
  136. foreach ($lv as $key => $value) {
  137. if ($score >= $value) {
  138. $level = $key;
  139. }
  140. }
  141. return $level;
  142. }
  143. /**
  144. * 关联用户关系
  145. * @return \think\model\relation\HasOne
  146. */
  147. public function userRelation()
  148. {
  149. return $this->hasOne("UserRelation","user_id","id");
  150. }
  151. /**
  152. * 更新用户信息
  153. * @param $wechatUser 用户信息
  154. * @param $uid 用户uid
  155. * @return bool|void
  156. * @throws \think\db\exception\DataNotFoundException
  157. * @throws \think\db\exception\ModelNotFoundException
  158. * @throws \think\exception\DbException
  159. */
  160. public static function updateWechatUser($wechatUser, $uid)
  161. {
  162. $userInfo = self::where('id', $uid)->find();
  163. if (!$userInfo) return;
  164. if ($userInfo->spread_uid) {
  165. return self::where('id',$uid)->update([
  166. 'nickname' => $wechatUser['nickname'] ?: '',
  167. 'avatar' => $wechatUser['headimgurl'] ?: '',
  168. 'login_type' => isset($wechatUser['login_type']) ? $wechatUser['login_type'] : $userInfo->login_type,
  169. ]);
  170. } else {
  171. $data = [
  172. 'nickname' => $wechatUser['nickname'] ?: '',
  173. 'avatar' => $wechatUser['headimgurl'] ?: '',
  174. 'login_type' => isset($wechatUser['login_type']) ? $wechatUser['login_type'] : $userInfo->login_type,
  175. ];
  176. return self::where('id',$uid)->update($data);
  177. }
  178. }
  179. /**
  180. * 设置推广关系
  181. * @param $spread
  182. * @param $uid
  183. * @return bool
  184. * @throws \think\db\exception\DataNotFoundException
  185. * @throws \think\db\exception\ModelNotFoundException
  186. * @throws \think\exception\DbException
  187. */
  188. public static function setSpread($spread, $uid)
  189. {
  190. //当前用户信息
  191. $userInfo = self::where('id', $uid)->find();
  192. if (!$userInfo) return true;
  193. //当前用户有上级直接返回
  194. if ($userInfo->spread_uid) return true;
  195. //没有推广编号直接返回
  196. if (!$spread) return true;
  197. if ($spread >= $uid) return true;
  198. if ($uid == self::where('id', $spread)->value('spread_uid')) return true;
  199. $data['spread_uid'] = $spread;
  200. $data['spread_time'] = time();
  201. return self::where('id',$uid)->update($data);
  202. }
  203. /**
  204. * 小程序用户添加
  205. * @param $routineUser
  206. * @param int $spread_uid
  207. * @return object
  208. */
  209. public static function setRoutineUser($routineUser, $spread_uid = 0)
  210. {
  211. self::beginTrans();
  212. $res1 = true;
  213. if ($spread_uid) $res1 = self::where('id', $spread_uid)->inc('spread_count', 1)->update();
  214. // $storeBrokerageStatu = sys_config('store_brokerage_statu') ? : 1;//获取后台分销类型
  215. $salt = Random::alnum();
  216. $res2 = self::create([
  217. 'username' => 'rt' .Random::alpha(3).time(),
  218. 'password' => md5(md5(12345678).$salt),
  219. 'salt' => $salt,
  220. 'nickname' => $routineUser['nickname'] ?: '',
  221. 'avatar' => $routineUser['headimgurl'] ?: '',
  222. 'spread_uid' => $spread_uid,
  223. 'spread_time' => $spread_uid ? time() : 0,
  224. 'jointime' =>time(),
  225. 'joinip' => Request::instance()->ip(),
  226. 'logintime' => time(),
  227. 'loginip' => Request::instance()->ip(),
  228. 'login_type' => $routineUser['login_type'],
  229. 'cid' => $routineUser['cid'],
  230. 'status' =>'normal',
  231. ]);
  232. $routineUser['user_id'] = $res2['id'];
  233. $routineUser['login_type'] = $routineUser['login_type'];
  234. UserRelation::create($routineUser);
  235. $res = $res1 && $res2;
  236. self::checkTrans($res);
  237. return $res2;
  238. }
  239. /**
  240. * 小程序创建用户后返回uid
  241. * @param $routineInfo
  242. * @return mixed
  243. */
  244. public static function routineOauth($routine)
  245. {
  246. $routineInfo['nickname'] = filter_emoji($routine['nickName']);//姓名
  247. $routineInfo['sex'] = $routine['gender'];//性别
  248. $routineInfo['language'] = $routine['language'];//语言
  249. $routineInfo['city'] = $routine['city'];//城市
  250. $routineInfo['province'] = $routine['province'];//省份
  251. $routineInfo['country'] = $routine['country'];//国家
  252. $routineInfo['headimgurl'] = $routine['avatarUrl'];//头像
  253. $routineInfo['routine_openid'] = $routine['openId'];//openid
  254. $routineInfo['session_key'] = $routine['session_key'];//会话密匙
  255. $routineInfo['unionid'] = $routine['unionId'];//用户在开放平台的唯一标识符
  256. $routineInfo['login_type'] = 2;//用户类型
  257. $routineInfo['cid'] = $routine['cid'];
  258. $spid = 0;//绑定关系uid
  259. $isCOde = false;
  260. //获取是否有扫码进小程序
  261. if ($routine['code']) {
  262. $spid = $routine['spid'];
  263. } else if ($routine['spid'])
  264. $spid = $routine['spid'];
  265. // 判断unionid 存在根据unionid判断
  266. if ($routineInfo['unionid'] != '' && ($uid = UserRelation::where(['unionid' => $routineInfo['unionid']])->where('login_type', '<>', '0')->value('user_id'))) {
  267. UserRelation::where('user_id',$uid)->update($routineInfo);
  268. $routineInfo['code'] = $spid;
  269. $routineInfo['isPromoter'] = $isCOde;
  270. if ($routine['login_type']) $routineInfo['login_type'] = 3;
  271. self::updateWechatUser($routineInfo,0);
  272. } else if ($uid = UserRelation::where(['routine_openid' => $routineInfo['routine_openid']])->where('login_type', '<>', 0)->value('user_id')) { //根据小程序openid判断
  273. UserRelation::where('user_id',$uid)->update($routineInfo);
  274. $routineInfo['code'] = $spid;
  275. $routineInfo['isPromoter'] = $isCOde;
  276. if ($routine['login_type']) $routineInfo['login_type'] = $routine['login_type'];
  277. self::updateWechatUser($routineInfo, 0);
  278. } else {
  279. $res = self::setRoutineUser($routineInfo, $spid);
  280. $uid = $res['id'];
  281. }
  282. return $uid;
  283. }
  284. /**
  285. * 微信用户增加
  286. * @param $WechatUser
  287. * @param int $spread_uid
  288. */
  289. public static function setWechatUser($WechatUser, $spread_uid = 0)
  290. {
  291. self::beginTrans();
  292. $res1 = true;
  293. if ($spread_uid) $res1 = self::where('id', $spread_uid)->inc('spread_count', 1)->update();
  294. $salt = Random::alnum();
  295. $res2 = self::create([
  296. 'username' => 'wx' . Random::alpha(3).time(),
  297. 'password' => md5(md5(12345678).$salt),
  298. 'salt' => $salt,
  299. 'nickname' => $WechatUser['nickname'] ?: '',
  300. 'avatar' => $WechatUser['headimgurl'] ?: '',
  301. 'spread_uid' => $spread_uid,
  302. 'spread_time' => $spread_uid ? time() : 0,
  303. 'jointime' => time(),
  304. 'joinip' => Request::instance()->ip(),
  305. 'logintime' => time(),
  306. 'loginip' => Request::instance()->ip(),
  307. 'login_type' => $WechatUser['login_type'],
  308. 'status' => 'normal',
  309. 'cid' => $WechatUser['cid'],
  310. ]);
  311. $WechatUser['user_id'] = $res2['id'];
  312. $WechatUser['login_type'] = $WechatUser['login_type'];
  313. UserRelation::create($WechatUser);
  314. $res = $res1 && $res2;
  315. self::checkTrans($res);
  316. return $res2;
  317. }
  318. public static function getByUsername($cid,$value)
  319. {
  320. return self::where('username',$value)->where('cid',$cid)->find();
  321. }
  322. public static function getByEmail($cid,$value)
  323. {
  324. return self::where('email',$value)->where('cid',$cid)->find();
  325. }
  326. public static function getByMobile($cid,$value)
  327. {
  328. return self::where('mobile',$value)->where('cid',$cid)->find();
  329. }
  330. public static function getByNickname($cid,$value)
  331. {
  332. return self::where('nickname',$value)->where('cid',$cid)->find();
  333. }
  334. public static function setendtime($user_id,$level_id)
  335. {
  336. $level = UserGroup::find($level_id);
  337. $user = self::find($user_id);
  338. if($user['vip_forever']==0 && $user['vip_endtime']>time())
  339. {
  340. $data['vip_endtime'] = strtotime("+{$level['validity_month']} month",$user['vip_endtime']);
  341. }
  342. else
  343. {
  344. $data['vip_endtime'] = strtotime("+{$level['validity_month']} month");
  345. }
  346. $data['group_id'] = $level_id;
  347. $data['level'] = $level_id;
  348. $data['user_type'] = $level['user_type'];
  349. self::where('id',$user_id)->update($data);
  350. return true;
  351. }
  352. }